diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml new file mode 100644 index 0000000000000..e5bd27659ceb2 --- /dev/null +++ b/.github/codeql/codeql-config.yml @@ -0,0 +1,10 @@ +name: openttd +queries: +- uses: security-and-quality +query-filters: +- exclude: + id: + # Only feasible way is to move away from fopen; fopen_s is optional C11 and not implemented on most platforms. + - cpp/world-writable-file-creation + # Basically OpenTTD's coding style for adding things like ..._INVALID to enumerations + - cpp/irregular-enum-init diff --git a/.github/script-missing-mode-enforcement.py b/.github/script-missing-mode-enforcement.py new file mode 100644 index 0000000000000..5903b5f0a0bf3 --- /dev/null +++ b/.github/script-missing-mode-enforcement.py @@ -0,0 +1,71 @@ +""" +Script to scan the OpenTTD's script API for functions that miss checks for the +function being called from the right mode (deity or company mode). + +When a function calls either ScriptObject::Command or ScriptObject::GetCompany +then the function is considered dangerous. When one of the mode enforcement +macros from script_error.hpp, i.e. EnforceDeityMode, EnforceCompanyModeValid or +EnforceDeityOrCompanyModeValid, are called in the function, then we consider +that the function has mode enforcement. + +Any dangerous function for which no enforcement is found are emitted as errors. +""" + +import glob +import re +import sys + + +def check_mode_enforcement(path): + errors = [] + with open(path, "r") as reader: + mode_enforcement_found = False + dangerous_function = False + for line in reader: + # Line does not start with a tab and have ::. That looks like the begin of a function, so reset the state. + if re.match(r"^[^\t].*\w::\w", line): + mode_enforcement_found = False + dangerous_function = False + currentFunction = line + continue + + if re.match( + r"\t(EnforceDeityMode|EnforceCompanyModeValid|EnforceDeityOrCompanyModeValid|EnforceDeityOrCompanyModeValid_Void)\(", + line, + ): + # Mode enforcement macro found + mode_enforcement_found = True + continue + + if re.match(r".*(ScriptObject::Command|ScriptObject::GetCompany).*", line): + # Dangerous function found + dangerous_function = True + continue + + # Line with only a closing bracket. That looks like the end of a function, so check for the dangerous function without mode enforcement + if re.match(r"^}$", line) and dangerous_function and not mode_enforcement_found: + function_name = currentFunction.rstrip("\n").replace("/* static */ ", "") + errors.append(f"{path}: {function_name}") + + return errors + + +def main(): + errors = [] + for path in sorted(glob.glob("src/script/api/*.cpp")): + # Skip a number of files that yield only false positives + if path.endswith(("script_object.cpp", "script_companymode.cpp", "script_controller.cpp", "script_game.cpp")): + continue + + errors.extend(check_mode_enforcement(path)) + + if errors: + print("Mode enforcement was expected in the following files/functions:") + print("\n".join(errors)) + sys.exit(1) + + print("OK") + + +if __name__ == "__main__": + main() diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 57d42d6921ad2..0000000000000 --- a/.github/stale.yml +++ /dev/null @@ -1,34 +0,0 @@ -daysUntilClose: 7 -staleLabel: stale -closeComment: false -exemptMilestones: true -exemptAssignees: true - -issues: - daysUntilStale: 60 - exemptLabels: - - pinned - - security - - "good first issue" - - regression - markComment: > - This issue has been automatically marked as stale because it has not had any activity in the last two months. - - If you believe the issue is still relevant, please test on the latest nightly and report back. - - It will be closed if no further activity occurs within 7 days. - - Thank you for your contributions. - -pulls: - daysUntilStale: 30 - exemptLabels: - - pinned - markComment: > - This pull request has been automatically marked as stale because it has not had any activity in the last month. - - Please feel free to give a status update now, ping for review, or re-open when it's ready. - - It will be closed if no further activity occurs within 7 days. - - Thank you for your contributions. diff --git a/.github/unused-strings.py b/.github/unused-strings.py index 210212c397bd7..527a938dc501c 100644 --- a/.github/unused-strings.py +++ b/.github/unused-strings.py @@ -210,11 +210,10 @@ def main(): errors.append(f"ERROR: {string} is (possibly) no longer needed.") if errors: - for error in errors: - print(error) + print("\n".join(errors)) sys.exit(1) - else: - print("OK") + + print("OK") if __name__ == "__main__": diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index e9c4490ed3f39..172682c20a1c8 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -12,6 +12,10 @@ on: env: CTEST_OUTPUT_ON_FAILURE: 1 +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + jobs: emscripten: name: Emscripten @@ -19,7 +23,7 @@ jobs: runs-on: ubuntu-20.04 container: # If you change this version, change the number in the cache step too. - image: emscripten/emsdk:2.0.31 + image: emscripten/emsdk:3.1.28 steps: - name: Checkout @@ -29,7 +33,7 @@ jobs: uses: actions/cache@v3 with: path: /emsdk/upstream/emscripten/cache - key: 2.0.31-${{ runner.os }} + key: 3.1.28-${{ runner.os }} - name: Patch Emscripten to support LZMA run: | @@ -105,6 +109,7 @@ jobs: echo "::group::Install dependencies" sudo apt-get install -y --no-install-recommends \ liballegro4-dev \ + libcurl4-openssl-dev \ libfontconfig-dev \ libicu-dev \ liblzma-dev \ @@ -165,16 +170,25 @@ jobs: runs-on: macos-latest env: - MACOSX_DEPLOYMENT_TARGET: 10.14 + MACOSX_DEPLOYMENT_TARGET: 10.13 steps: - name: Checkout uses: actions/checkout@v3 + - name: Install dependencies + env: + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_INSTALL_CLEANUP: 1 + run: | + brew install \ + pkg-config \ + # EOF + - name: Prepare cache key id: key run: | - echo "::set-output name=image::$ImageOS-$ImageVersion" + echo "image=$ImageOS-$ImageVersion" >> $GITHUB_OUTPUT - name: Enable vcpkg cache uses: actions/cache@v3 @@ -187,6 +201,7 @@ jobs: - name: Prepare vcpkg run: | vcpkg install --triplet=${{ matrix.arch }}-osx \ + curl \ liblzma \ libpng \ lzo \ @@ -256,7 +271,7 @@ jobs: # Work around caching failure with GNU tar New-Item -Type Junction -Path vcpkg -Target c:\vcpkg - Write-Output "::set-output name=image::$env:ImageOS-$env:ImageVersion" + Write-Output "image=$env:ImageOS-$env:ImageVersion" >> $env:GITHUB_OUTPUT - name: Enable vcpkg cache uses: actions/cache@v3 @@ -411,4 +426,4 @@ jobs: steps: - name: Check annotations - uses: OpenTTD/actions/annotation-check@v2 + uses: OpenTTD/actions/annotation-check@v3 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000000..936c4c92d7999 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,83 @@ +name: CodeQL + +on: + push: + branches: + - master + pull_request: + # The branches below must be a subset of the branches above + branches: + - master + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install dependencies + run: | + echo "::group::Update apt" + sudo apt-get update + echo "::endgroup::" + + echo "::group::Install dependencies" + sudo apt-get install -y --no-install-recommends \ + liballegro4-dev \ + libcurl4-openssl-dev \ + libfontconfig-dev \ + libicu-dev \ + liblzma-dev \ + liblzo2-dev \ + libsdl2-dev \ + zlib1g-dev \ + # EOF + echo "::endgroup::" + env: + DEBIAN_FRONTEND: noninteractive + + - name: Set number of make jobs + run: | + echo "MAKEFLAGS=-j$(nproc)" >> $GITHUB_ENV + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: cpp + config-file: ./.github/codeql/codeql-config.yml + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: /language:cpp + upload: False + output: sarif-results + + - name: Filter out table & generated code + uses: advanced-security/filter-sarif@v1 + with: + patterns: | + +**/*.* + -**/table/*.* + -**/generated/**/*.* + input: sarif-results/cpp.sarif + output: sarif-results/cpp.sarif + + - name: Upload results + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: sarif-results/cpp.sarif diff --git a/.github/workflows/commit-checker.yml b/.github/workflows/commit-checker.yml index 91fc54b104f9b..1407757fc5570 100644 --- a/.github/workflows/commit-checker.yml +++ b/.github/workflows/commit-checker.yml @@ -3,6 +3,10 @@ name: Commit checker on: pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + jobs: commit-checker: name: Commit checker diff --git a/.github/workflows/preview_build.yml b/.github/workflows/preview_build.yml index d2935cefbc71b..b1d7b917ef127 100644 --- a/.github/workflows/preview_build.yml +++ b/.github/workflows/preview_build.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-20.04 container: # If you change this version, change the number in the cache step too. - image: emscripten/emsdk:2.0.31 + image: emscripten/emsdk:3.1.28 steps: - name: Update deployment status to in progress @@ -37,6 +37,7 @@ jobs: - name: Name branch run: | + git config --global --add safe.directory ${GITHUB_WORKSPACE} name=$(echo "${{ github.event.client_payload.folder }}") git checkout -b ${name} @@ -44,7 +45,7 @@ jobs: uses: actions/cache@v3 with: path: /emsdk/upstream/emscripten/cache - key: 2.0.31-${{ runner.os }} + key: 3.1.28-${{ runner.os }} - name: Patch Emscripten to support LZMA run: | diff --git a/.github/workflows/release-docs.yml b/.github/workflows/release-docs.yml new file mode 100644 index 0000000000000..759f33035c94f --- /dev/null +++ b/.github/workflows/release-docs.yml @@ -0,0 +1,85 @@ +name: Release (Docs) + +on: + workflow_call: + inputs: + version: + required: true + type: string + +jobs: + docs: + name: Docs + + runs-on: ubuntu-20.04 + + steps: + - name: Download source + uses: actions/download-artifact@v3 + with: + name: internal-source + + - name: Unpack source + run: | + tar -xf source.tar.gz --strip-components=1 + + - name: Install dependencies + run: | + echo "::group::Update apt" + sudo apt-get update + echo "::endgroup::" + + echo "::group::Install dependencies" + sudo apt-get install -y --no-install-recommends \ + doxygen \ + # EOF + echo "::endgroup::" + env: + DEBIAN_FRONTEND: noninteractive + + - name: Build + run: | + mkdir -p ${GITHUB_WORKSPACE}/build + cd ${GITHUB_WORKSPACE}/build + + echo "::group::CMake" + cmake ${GITHUB_WORKSPACE} \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DOPTION_DOCS_ONLY=ON \ + # EOF + echo "::endgroup::" + + echo "::group::Build" + cmake --build . --target docs + echo "::endgroup::" + + - name: Create bundles + run: | + BASENAME=openttd-${{ inputs.version }} + + cd ${GITHUB_WORKSPACE}/build + + mv docs/source ${BASENAME}-docs + mv docs/ai-api ${BASENAME}-docs-ai + mv docs/gs-api ${BASENAME}-docs-gs + + mkdir -p bundles + + echo "::group::Create docs bundle" + tar --xz -cf bundles/${BASENAME}-docs.tar.xz ${BASENAME}-docs + echo "::endgroup::" + + echo "::group::Create AI API docs bundle" + tar --xz -cf bundles/${BASENAME}-docs-ai.tar.xz ${BASENAME}-docs-ai + echo "::endgroup::" + + echo "::group::Create GameScript API docs bundle" + tar --xz -cf bundles/${BASENAME}-docs-gs.tar.xz ${BASENAME}-docs-gs + echo "::endgroup::" + + - name: Store bundles + uses: actions/upload-artifact@v3 + with: + name: openttd-docs + path: build/bundles/*.tar.xz + retention-days: 5 diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml new file mode 100644 index 0000000000000..048e1b0710965 --- /dev/null +++ b/.github/workflows/release-linux.yml @@ -0,0 +1,141 @@ +name: Release (Linux) + +on: + workflow_call: + +jobs: + linux: + name: Linux (Generic) + + runs-on: ubuntu-20.04 + container: + # manylinux2014 is based on CentOS 7, but already has a lot of things + # installed and preconfigured. It makes it easier to build OpenTTD. + image: quay.io/pypa/manylinux2014_x86_64 + + steps: + - name: Download source + uses: actions/download-artifact@v3 + with: + name: internal-source + + - name: Unpack source + run: | + tar -xf source.tar.gz --strip-components=1 + + - name: Enable vcpkg cache + uses: actions/cache@v3 + with: + path: /vcpkg/installed + key: ubuntu-20.04-vcpkg-release-0 # Increase the number whenever dependencies are modified + restore-keys: | + ubuntu-20.04-vcpkg-release + + - name: Install dependencies + run: | + echo "::group::Install system dependencies" + # ICU is used as vcpkg fails to install ICU. Other dependencies + # are needed either for vcpkg or for the packages installed with + # vcpkg. + yum install -y \ + libicu-devel \ + perl-IPC-Cmd \ + wget \ + zip \ + # EOF + echo "::endgroup::" + + # We use vcpkg for our dependencies, to get more up-to-date version. + echo "::group::Install vcpkg and dependencies" + + # We do a little dance to make sure we copy the cached install folder + # into our new clone. + git clone --depth=1 https://github.com/microsoft/vcpkg /vcpkg-clone + if [ -e /vcpkg/installed ]; then + mv /vcpkg/installed /vcpkg-clone/ + rm -rf /vcpkg + fi + mv /vcpkg-clone /vcpkg + + ( + cd /vcpkg + ./bootstrap-vcpkg.sh -disableMetrics + + # Make Python3 available for other packages. + ./vcpkg install python3 + ln -sf $(pwd)/installed/x64-linux/tools/python3/python3.[0-9][0-9] /usr/bin/python3 + + ./vcpkg install \ + curl[http2] \ + fontconfig \ + freetype \ + liblzma \ + libpng \ + lzo \ + sdl2 \ + zlib \ + # EOF + ) + echo "::endgroup::" + + # The yum variant of fluidsynth depends on all possible audio drivers, + # like jack, ALSA, pulseaudio, etc. This is not really useful for us, + # as we route the output of fluidsynth back via our sound driver, and + # as such do not use these audio driver outputs at all. + # The vcpkg variant of fluidsynth depends on ALSA. Similar issue here. + # So instead, we compile fluidsynth ourselves, with as few + # dependencies as possible. This currently means it picks up SDL2, but + # this is fine, as we need SDL2 anyway. + echo "::group::Install fluidsynth" + wget https://github.com/FluidSynth/fluidsynth/archive/v2.1.6.tar.gz + tar xf v2.1.6.tar.gz + ( + cd fluidsynth-2.1.6 + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr + cmake --build . -j $(nproc) + cmake --install . + ) + echo "::endgroup::" + + - name: Install GCC problem matcher + uses: ammaraskar/gcc-problem-matcher@master + + - name: Build + run: | + mkdir -p build + cd build + + echo "::group::CMake" + cmake ${GITHUB_WORKSPACE} \ + -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DOPTION_PACKAGE_DEPENDENCIES=ON \ + # EOF + echo "::endgroup::" + + echo "::group::Build" + echo "Running on $(nproc) cores" + cmake --build . -j $(nproc) + echo "::endgroup::" + + - name: Create bundles + run: | + cd ${GITHUB_WORKSPACE}/build + echo "::group::Run CPack" + cpack + echo "::endgroup::" + + echo "::group::Cleanup" + # Remove the sha256 files CPack generates; we will do this ourself at + # the end of this workflow. + rm -f bundles/*.sha256 + echo "::endgroup::" + + - name: Store bundles + uses: actions/upload-artifact@v3 + with: + name: openttd-linux-generic + path: build/bundles + retention-days: 5 diff --git a/.github/workflows/release-macos.yml b/.github/workflows/release-macos.yml new file mode 100644 index 0000000000000..b7a32015666ed --- /dev/null +++ b/.github/workflows/release-macos.yml @@ -0,0 +1,200 @@ +name: Release (MacOS) + +on: + workflow_call: + +jobs: + macos: + name: MacOS + + runs-on: macos-11 + env: + MACOSX_DEPLOYMENT_TARGET: 10.13 + + steps: + - name: Download source + uses: actions/download-artifact@v3 + with: + name: internal-source + + - name: Unpack source + run: | + tar -xf source.tar.gz --strip-components=1 + + - name: Install dependencies + env: + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_INSTALL_CLEANUP: 1 + run: | + brew install \ + pandoc \ + pkg-config \ + # EOF + + - name: Prepare cache key + id: key + run: | + echo "image=$ImageOS-$ImageVersion" >> $GITHUB_OUTPUT + + - name: Enable vcpkg cache + uses: actions/cache@v3 + with: + path: /usr/local/share/vcpkg/installed + key: ${{ steps.key.outputs.image }}-vcpkg-release-0 # Increase the number whenever dependencies are modified + restore-keys: | + ${{ steps.key.outputs.image }}-vcpkg-release + ${{ steps.key.outputs.image }}-vcpkg-x64 + + - name: Prepare vcpkg + run: | + vcpkg install \ + curl:x64-osx \ + curl:arm64-osx \ + liblzma:x64-osx \ + liblzma:arm64-osx \ + libpng:x64-osx \ + libpng:arm64-osx \ + lzo:x64-osx \ + lzo:arm64-osx \ + zlib:x64-osx \ + zlib:arm64-osx \ + # EOF + + - name: Install GCC problem matcher + uses: ammaraskar/gcc-problem-matcher@master + + - name: Build tools + run: | + mkdir build-host + cd build-host + + echo "::group::CMake" + cmake ${GITHUB_WORKSPACE} \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DOPTION_TOOLS_ONLY=ON \ + # EOF + echo "::endgroup::" + + echo "::group::Build tools" + echo "Running on $(sysctl -n hw.logicalcpu) cores" + cmake --build . -j $(sysctl -n hw.logicalcpu) --target tools + echo "::endgroup::" + + - name: Import code signing certificates + uses: Apple-Actions/import-codesign-certs@v1 + with: + # The certificates in a PKCS12 file encoded as a base64 string + p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }} + # The password used to import the PKCS12 file. + p12-password: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }} + # If this is run on a fork, there may not be a certificate set up - continue in this case + continue-on-error: true + + - name: Build arm64 + run: | + mkdir build-arm64 + cd build-arm64 + + echo "::group::CMake" + cmake ${GITHUB_WORKSPACE} \ + -DCMAKE_OSX_ARCHITECTURES=arm64 \ + -DVCPKG_TARGET_TRIPLET=arm64-osx \ + -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + # EOF + echo "::endgroup::" + + echo "::group::Build" + echo "Running on $(sysctl -n hw.logicalcpu) cores" + cmake --build . -j $(sysctl -n hw.logicalcpu) + echo "::endgroup::" + + - name: Build x64 + run: | + mkdir build-x64 + cd build-x64 + + echo "::group::CMake" + cmake ${GITHUB_WORKSPACE} \ + -DCMAKE_OSX_ARCHITECTURES=x86_64 \ + -DVCPKG_TARGET_TRIPLET=x64-osx \ + -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake \ + -DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DCPACK_BUNDLE_APPLE_CERT_APP=${{ secrets.APPLE_DEVELOPER_CERTIFICATE_ID }} \ + "-DCPACK_BUNDLE_APPLE_CODESIGN_PARAMETER=--deep -f --options runtime" \ + -DAPPLE_UNIVERSAL_PACKAGE=1 \ + # EOF + echo "::endgroup::" + + echo "::group::Build" + echo "Running on $(sysctl -n hw.logicalcpu) cores" + cmake --build . -j $(sysctl -n hw.logicalcpu) + echo "::endgroup::" + + - name: Create bundles + run: | + cd build-x64 + + echo "::group::Create universal binary" + # Combine the `openttd` binaries from each build into a single file + lipo -create -output openttd-universal ../build-*/openttd + mv openttd-universal openttd + echo "::endgroup::" + + echo "::group::Run CPack" + cpack + echo "::endgroup::" + + echo "::group::Cleanup" + # Remove the sha256 files CPack generates; we will do this ourself at + # the end of this workflow. + rm -f bundles/*.sha256 + echo "::endgroup::" + + - name: Install gon + env: + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_INSTALL_CLEANUP: 1 + run: | + brew tap mitchellh/gon + brew install mitchellh/gon/gon + + - name: Notarize + env: + AC_USERNAME: ${{ secrets.APPLE_DEVELOPER_APP_USERNAME }} + AC_PASSWORD: ${{ secrets.APPLE_DEVELOPER_APP_PASSWORD }} + run: | + cd build-x64 + ../os/macosx/notarize.sh + + - name: Build zip + run: | + cd build-x64 + + pushd _CPack_Packages/*/Bundle/openttd-*/ + + # Remove the Applications symlink from the staging folder + rm -f Applications + + # Remove the original dmg built by CPack to avoid a conflict when resolving + # the zip_filename variable below + rm -f ../*.dmg + + zip_filename=(../openttd-*) + + # Package up the existing, notarised .app into a zip file + zip -r -9 ${zip_filename}.zip OpenTTD.app + + popd + + # Now move it into place to be uploaded + mv _CPack_Packages/*/Bundle/openttd-*.zip bundles/ + + - name: Store bundles + uses: actions/upload-artifact@v3 + with: + name: openttd-macos-universal + path: build-x64/bundles + retention-days: 5 diff --git a/.github/workflows/release-source.yml b/.github/workflows/release-source.yml new file mode 100644 index 0000000000000..2213efed25bdf --- /dev/null +++ b/.github/workflows/release-source.yml @@ -0,0 +1,186 @@ +name: Release (Source) + +on: + workflow_call: + outputs: + version: + value: ${{ jobs.source.outputs.version }} + is_tag: + value: ${{ jobs.source.outputs.is_tag }} + trigger_type: + value: ${{ jobs.source.outputs.trigger_type }} + folder: + value: ${{ jobs.source.outputs.folder }} + +jobs: + source: + name: Source + + runs-on: ubuntu-20.04 + + outputs: + version: ${{ steps.metadata.outputs.version }} + is_tag: ${{ steps.metadata.outputs.is_tag }} + trigger_type: ${{ steps.metadata.outputs.trigger_type }} + folder: ${{ steps.metadata.outputs.folder }} + + steps: + - name: Checkout (Release) + if: github.event_name == 'release' + uses: actions/checkout@v3 + with: + # We generate a changelog; for this we need the full git log. + fetch-depth: 0 + + - name: Checkout (Manual) + if: github.event_name == 'workflow_dispatch' + uses: actions/checkout@v3 + with: + ref: ${{ github.event.inputs.ref }} + # We generate a changelog; for this we need the full git log. + fetch-depth: 0 + + - name: Checkout (Trigger) + if: github.event_name == 'repository_dispatch' + uses: actions/checkout@v3 + with: + ref: ${{ github.event.client_payload.ref }} + # We generate a changelog; for this we need the full git log. + fetch-depth: 0 + + - name: Check valid branch name + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + REF="${{ github.event.inputs.ref }}" + elif [ "${{ github.event_name }}" = "repository_dispatch" ]; then + REF="${{ github.event.client_payload.ref }}" + else + REF="${{ github.ref }}" + fi + + # Check if we are a tag. + if [ -n "$(git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null || false)" ]; then + exit 0 + fi + + # Check if the checkout caused the branch to be named. + if [ "$(git rev-parse --abbrev-ref HEAD)" != "HEAD" ]; then + exit 0 + fi + + # Check if this was a pull request. + if [ -n "$(echo ${REF} | grep '^refs/pull/[0-9]*')" ]; then + PULL=$(echo ${REF} | cut -d/ -f3) + git checkout -b pr${PULL} + fi + + # Are we still in a detached state? Error out. + if [ "$(git rev-parse --abbrev-ref HEAD)" == "HEAD" ]; then + echo "The 'ref' given resulted in a checkout of a detached HEAD." + echo "We cannot detect the version for these checkout accurate." + echo "" + echo "If you want to build a Pull Request, make sure you use 'refs/pull/NNN/head'." + echo "" + echo "Cancelling build, as without a version we cannot store the artifacts." + exit 1 + fi + + - name: Generate metadata + id: metadata + run: | + echo "::group::Prepare metadata files" + cmake -DGENERATE_OTTDREV=1 -P cmake/scripts/FindVersion.cmake + ./.github/changelog.sh > .changelog + TZ='UTC' date +"%Y-%m-%d %H:%M UTC" > .release_date + cat .ottdrev | cut -f 1 -d$'\t' > .version + + if [ $(cat .ottdrev | cut -f 5 -d$'\t') = '1' ]; then + # Assume that all tags are always releases. Why else make a tag? + IS_TAG="true" + + FOLDER="${{ env.FOLDER_RELEASES }}" + TRIGGER_TYPE="new-tag" + else + IS_TAG="false" + + BRANCH=$(git symbolic-ref -q HEAD | sed 's@.*/@@') + if [ -z "${BRANCH}" ]; then + echo "Internal error: branch name is empty." + echo "An earlier step should have prevented this from happening." + echo "Cancelling build, as without a branch name we cannot store the artifacts" + exit 1 + fi + + if [ "${BRANCH}" = "${{ env.NIGHTLIES_BRANCH }}" ]; then + # The "master" branch is special, and we call a nightly. + FOLDER="${{ env.FOLDER_NIGHTLIES }}/$(date +%Y)" + TRIGGER_TYPE="new-master" + else + # All other branches, which can be builds of Pull Requests, are + # put in their own folder. + FOLDER="${{ env.FOLDER_BRANCHES }}/${BRANCH}" + TRIGGER_TYPE="new-branch" + fi + fi + + mkdir -p build/bundles + cp .changelog build/bundles/changelog.txt + cp .release_date build/bundles/released.txt + cp README.md build/bundles/README.md + echo "::endgroup::" + + echo "Release Date: $(cat .release_date)" + echo "Revision: $(cat .ottdrev)" + echo "Version: $(cat .version)" + echo "Is tag: ${IS_TAG}" + echo "Folder on CDN: ${FOLDER}" + echo "Workflow trigger: ${TRIGGER_TYPE}" + + echo "version=$(cat .version)" >> $GITHUB_OUTPUT + echo "is_tag=${IS_TAG}" >> $GITHUB_OUTPUT + echo "folder=${FOLDER}" >> $GITHUB_OUTPUT + echo "trigger_type=${TRIGGER_TYPE}" >> $GITHUB_OUTPUT + env: + NIGHTLIES_BRANCH: master + FOLDER_RELEASES: openttd-releases + FOLDER_NIGHTLIES: openttd-nightlies + FOLDER_BRANCHES: openttd-branches + + - name: Remove VCS information + run: | + rm -rf .git + + - name: Create bundles + run: | + FOLDER_NAME=openttd-${{ steps.metadata.outputs.version }} + + # Rename the folder to openttd-NNN + mkdir ${FOLDER_NAME} + find . -maxdepth 1 -not -name . -not -name build -not -name ${FOLDER_NAME} -exec mv {} ${FOLDER_NAME}/ \; + + echo "::group::Create tarball (xz) bundle" + tar --xz -cvf build/bundles/${FOLDER_NAME}-source.tar.xz ${FOLDER_NAME} + echo "::endgroup::" + + # This tarball is only to be used within this workflow. + echo "::group::Create tarball (gz) bundle" + tar --gzip -cvf source.tar.gz ${FOLDER_NAME} + echo "::endgroup::" + + echo "::group::Create zip bundle" + zip -9 -r build/bundles/${FOLDER_NAME}-source.zip ${FOLDER_NAME} + echo "::endgroup::" + + - name: Store bundles + uses: actions/upload-artifact@v3 + with: + name: openttd-source + path: build/bundles/* + retention-days: 5 + + - name: Store source (for other jobs) + uses: actions/upload-artifact@v3 + with: + name: internal-source + path: source.tar.gz + retention-days: 1 diff --git a/.github/workflows/release-windows-store.yml b/.github/workflows/release-windows-store.yml new file mode 100644 index 0000000000000..97b4398b36719 --- /dev/null +++ b/.github/workflows/release-windows-store.yml @@ -0,0 +1,192 @@ +name: Release (Windows Store) + +on: + workflow_call: + inputs: + version: + required: true + type: string + +jobs: + windows-store: + name: Windows Store + + runs-on: windows-latest + + steps: + - name: Download source + uses: actions/download-artifact@v3 + with: + name: internal-source + + - name: Unpack source + shell: bash + run: | + tar -xf source.tar.gz --strip-components=1 + + - name: Download x86 build + uses: actions/download-artifact@v3 + with: + name: openttd-windows-x86 + + - name: Download x64 build + uses: actions/download-artifact@v3 + with: + name: openttd-windows-x64 + + - name: Download arm64 build + uses: actions/download-artifact@v3 + with: + name: openttd-windows-arm64 + + - name: Unpack builds + shell: bash + run: | + mkdir builds + cd builds + + function extract { + mkdir $1 + + # Extract the zip version of the release + unzip ../openttd-*-windows-$2.zip -d $1 + + # Remove the extraneous directory + mv $1/openttd-*-windows-$2/* $1/ + rmdir $1/openttd-*-windows-$2 + + # Move the openttd.exe to the '{arch}-binaries' folder + mkdir $1-binaries + mv $1/openttd.exe $1-binaries/ + } + + extract x86 win32 + extract x64 win64 + extract arm64 arm64 + + # Use the "x86" folder as the source of the common binaries (lang files, etc) and remove the others + mv x86 common-binaries + rm -rf x64 arm64 + + - name: Install OpenGFX + shell: bash + run: | + mkdir -p builds/common-binaries/baseset + cd builds/common-binaries/baseset + + echo "::group::Download OpenGFX" + curl -L https://cdn.openttd.org/opengfx-releases/7.1/opengfx-7.1-all.zip -o opengfx-all.zip + echo "::endgroup::" + + echo "::group::Unpack OpenGFX" + unzip opengfx-all.zip + tar xf opengfx-*.tar + echo "::endgroup::" + + rm -f opengfx-all.zip opengfx-*.tar + + - name: Install OpenMSX + shell: bash + run: | + mkdir -p builds/common-binaries/baseset + cd builds/common-binaries/baseset + + echo "::group::Download OpenMSX" + curl -L https://cdn.openttd.org/openmsx-releases/0.4.2/openmsx-0.4.2-all.zip -o openmsx-all.zip + echo "::endgroup::" + + echo "::group::Unpack OpenGFX" + unzip openmsx-all.zip + tar xf openmsx-*.tar + echo "::endgroup::" + + rm -f openmsx-all.zip openmsx-*.tar + + - name: Install OpenSFX + shell: bash + run: | + mkdir -p builds/common-binaries/baseset/opensfx + cd builds/common-binaries/baseset/opensfx + + echo "::group::Download OpenSFX" + curl -L https://cdn.openttd.org/opensfx-releases/1.0.3/opensfx-1.0.3-all.zip -o opensfx-all.zip + echo "::endgroup::" + + echo "::group::Unpack OpenSFX" + unzip opensfx-all.zip + tar xf opensfx-*.tar + echo "::endgroup::" + + rm -f opensfx-all.zip opensfx-*.tar + + - name: Generate signing certificate + shell: cmd + run: | + cd builds + + REM We need to provide a signed .appx to the Windows Store, so generate a certificate with password 'password' + call ..\os\windows\winstore\generate-key.bat "CN=78024DA8-4BE4-4C77-B12E-547BBF7359D2" password cert.pfx + + - name: Generate assets + shell: cmd + run: | + cd os\windows\winstore + call generate-assets.bat + + - name: Prepare manifests + shell: cmd + run: | + cd builds + mkdir manifests + + REM Set the version environment variable + call ..\os\windows\winstore\set-version.bat x86-binaries\openttd.exe + + call ..\os\windows\winstore\prepare-manifests.bat manifests "CN=78024DA8-4BE4-4C77-B12E-547BBF7359D2" "57420OpenTTDDevelopers.OpenTTDofficial" + + - name: Prepare binaries + shell: bash + run: | + cd builds + + # Copy the Windows Store assets + mkdir common-binaries/Assets + cp -R ../os/windows/winstore/assets-common/* common-binaries/Assets/ + + mkdir Assets + cp -R ../os/windows/winstore/assets/* Assets/ + + cp manifests/*.xml . + + - name: Build + shell: cmd + run: | + REM Add the Windows SDK tools to the PATH + + echo|set /p="SET VS_INSTALLDIR=" > _vspath.bat + vswhere -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath >> _vspath.bat + call _vspath.bat + call "%VS_INSTALLDIR%\Common7\Tools\VsDevCmd.bat" + + REM Set the version environment variable + call os\windows\winstore\set-version.bat builds\x86-binaries\openttd.exe + + cd builds + mkdir output + + REM Build and sign the package + makeappx build /v /f PackagingLayout.xml /op output\ /bv %OTTD_VERSION% /pv %OTTD_VERSION% /ca + SignTool sign /fd sha256 /a /f cert.pfx /p password "output\OpenTTD.appxbundle" + + REM Move resulting files to bundles folder + mkdir bundles + mkdir bundles\internal + move cert.pfx bundles\internal\openttd-${{ inputs.version }}-windows-store.pfx + move output\OpenTTD.appxbundle bundles\internal\openttd-${{ inputs.version }}-windows-store.appxbundle + + - name: Store bundles + uses: actions/upload-artifact@v3 + with: + name: openttd-windows-store + path: builds/bundles + retention-days: 5 diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml new file mode 100644 index 0000000000000..af67ffb18f857 --- /dev/null +++ b/.github/workflows/release-windows.yml @@ -0,0 +1,201 @@ +name: Release (Windows) + +on: + workflow_call: + inputs: + is_tag: + required: true + type: string + +jobs: + windows: + name: Windows + + strategy: + fail-fast: false + matrix: + include: + - arch: x86 + host: x86 + - arch: x64 + host: x64 + - arch: arm64 + host: x64_arm64 + + runs-on: windows-latest + + steps: + - name: Download source + uses: actions/download-artifact@v3 + with: + name: internal-source + + - name: Unpack source + shell: bash + run: | + tar -xf source.tar.gz --strip-components=1 + + - name: Install dependencies + shell: bash + run: | + choco install pandoc + + - name: Prepare cache key + id: key + shell: powershell + run: | + # Work around caching failure with GNU tar + New-Item -Type Junction -Path vcpkg -Target c:\vcpkg + + Write-Output "image=$env:ImageOS-$env:ImageVersion" >> $env:GITHUB_OUTPUT + + - name: Enable vcpkg cache + uses: actions/cache@v3 + with: + path: vcpkg/installed + key: ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }}-0 # Increase the number whenever dependencies are modified + restore-keys: | + ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }} + + - name: Prepare vcpkg + shell: bash + run: | + vcpkg install --triplet=${{ matrix.arch }}-windows-static \ + liblzma \ + libpng \ + lzo \ + zlib \ + # EOF + + - name: Install MSVC problem matcher + uses: ammaraskar/msvc-problem-matcher@master + + - name: Configure developer command prompt for tools + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + + - name: Build tools + shell: bash + run: | + mkdir build-host + cd build-host + + echo "::group::CMake" + cmake ${GITHUB_WORKSPACE} \ + -GNinja \ + -DOPTION_TOOLS_ONLY=ON \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + # EOF + echo "::endgroup::" + + echo "::group::Build" + cmake --build . --target tools + echo "::endgroup::" + + - name: Configure developer command prompt for ${{ matrix.arch }} + uses: ilammy/msvc-dev-cmd@v1 + 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: inputs.is_tag == 'true' + shell: bash + run: | + mkdir build + cd build + + echo "::group::CMake" + cmake ${GITHUB_WORKSPACE} \ + -GNinja \ + -DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \ + -DCMAKE_TOOLCHAIN_FILE="c:\vcpkg\scripts\buildsystems\vcpkg.cmake" \ + -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: inputs.is_tag != 'true' + shell: bash + run: | + mkdir build + cd build + + echo "::group::CMake" + cmake ${GITHUB_WORKSPACE} \ + -GNinja \ + -DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \ + -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 + run: | + cd ${GITHUB_WORKSPACE}/build + echo "::group::Run CPack" + cpack + echo "::endgroup::" + + echo "::group::Prepare PDB to be bundled" + PDB=$(ls bundles/*.zip | cut -d/ -f2 | sed 's/.zip$/.pdb/') + cp openttd.pdb bundles/${PDB} + xz -9 bundles/${PDB} + echo "::endgroup::" + + echo "::group::Cleanup" + # Remove the sha256 files CPack generates; we will do this ourself at + # the end of this workflow. + rm -f bundles/*.sha256 + echo "::endgroup::" + + - name: Sign installer + if: inputs.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@v3 + with: + name: openttd-windows-${{ matrix.arch }} + path: build/bundles + retention-days: 5 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 31829c0fba431..f6ae267bad247 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,251 +18,18 @@ jobs: source: name: Source - runs-on: ubuntu-20.04 - - outputs: - version: ${{ steps.metadata.outputs.version }} - is_tag: ${{ steps.metadata.outputs.is_tag }} - trigger_type: ${{ steps.metadata.outputs.trigger_type }} - folder: ${{ steps.metadata.outputs.folder }} - - steps: - - name: Checkout (Release) - if: github.event_name == 'release' - uses: actions/checkout@v3 - with: - # We generate a changelog; for this we need the full git log. - fetch-depth: 0 - - - name: Checkout (Manual) - if: github.event_name == 'workflow_dispatch' - uses: actions/checkout@v3 - with: - ref: ${{ github.event.inputs.ref }} - # We generate a changelog; for this we need the full git log. - fetch-depth: 0 - - - name: Checkout (Trigger) - if: github.event_name == 'repository_dispatch' - uses: actions/checkout@v3 - with: - ref: ${{ github.event.client_payload.ref }} - # We generate a changelog; for this we need the full git log. - fetch-depth: 0 - - - name: Check valid branch name - run: | - if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - REF="${{ github.event.inputs.ref }}" - elif [ "${{ github.event_name }}" = "repository_dispatch" ]; then - REF="${{ github.event.client_payload.ref }}" - else - REF="${{ github.ref }}" - fi - - # Check if we are a tag. - if [ -n "$(git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null || false)" ]; then - exit 0 - fi - - # Check if the checkout caused the branch to be named. - if [ "$(git rev-parse --abbrev-ref HEAD)" != "HEAD" ]; then - exit 0 - fi - - # Check if this was a pull request. - if [ -n "$(echo ${REF} | grep '^refs/pull/[0-9]*')" ]; then - PULL=$(echo ${REF} | cut -d/ -f3) - git checkout -b pr${PULL} - fi - - # Are we still in a detached state? Error out. - if [ "$(git rev-parse --abbrev-ref HEAD)" == "HEAD" ]; then - echo "The 'ref' given resulted in a checkout of a detached HEAD." - echo "We cannot detect the version for these checkout accurate." - echo "" - echo "If you want to build a Pull Request, make sure you use 'refs/pull/NNN/head'." - echo "" - echo "Cancelling build, as without a version we cannot store the artifacts." - exit 1 - fi - - - name: Generate metadata - id: metadata - run: | - echo "::group::Prepare metadata files" - cmake -DGENERATE_OTTDREV=1 -P cmake/scripts/FindVersion.cmake - ./.github/changelog.sh > .changelog - TZ='UTC' date +"%Y-%m-%d %H:%M UTC" > .release_date - cat .ottdrev | cut -f 1 -d$'\t' > .version - - if [ $(cat .ottdrev | cut -f 5 -d$'\t') = '1' ]; then - # Assume that all tags are always releases. Why else make a tag? - IS_TAG="true" - - FOLDER="${{ env.FOLDER_RELEASES }}" - TRIGGER_TYPE="new-tag" - else - IS_TAG="false" - - BRANCH=$(git symbolic-ref -q HEAD | sed 's@.*/@@') - if [ -z "${BRANCH}" ]; then - echo "Internal error: branch name is empty." - echo "An earlier step should have prevented this from happening." - echo "Cancelling build, as without a branch name we cannot store the artifacts" - exit 1 - fi - - if [ "${BRANCH}" = "${{ env.NIGHTLIES_BRANCH }}" ]; then - # The "master" branch is special, and we call a nightly. - FOLDER="${{ env.FOLDER_NIGHTLIES }}/$(date +%Y)" - TRIGGER_TYPE="new-master" - else - # All other branches, which can be builds of Pull Requests, are - # put in their own folder. - FOLDER="${{ env.FOLDER_BRANCHES }}/${BRANCH}" - TRIGGER_TYPE="new-branch" - fi - fi - - mkdir -p build/bundles - cp .changelog build/bundles/changelog.txt - cp .release_date build/bundles/released.txt - cp README.md build/bundles/README.md - echo "::endgroup::" - - echo "Release Date: $(cat .release_date)" - echo "Revision: $(cat .ottdrev)" - echo "Version: $(cat .version)" - echo "Is tag: ${IS_TAG}" - echo "Folder on CDN: ${FOLDER}" - echo "Workflow trigger: ${TRIGGER_TYPE}" - - echo "::set-output name=version::$(cat .version)" - echo "::set-output name=is_tag::${IS_TAG}" - echo "::set-output name=folder::${FOLDER}" - echo "::set-output name=trigger_type::${TRIGGER_TYPE}" - env: - NIGHTLIES_BRANCH: master - FOLDER_RELEASES: openttd-releases - FOLDER_NIGHTLIES: openttd-nightlies - FOLDER_BRANCHES: openttd-branches - - - name: Remove VCS information - run: | - rm -rf .git - - - name: Create bundles - run: | - FOLDER_NAME=openttd-${{ steps.metadata.outputs.version }} - - # Rename the folder to openttd-NNN - mkdir ${FOLDER_NAME} - find . -maxdepth 1 -not -name . -not -name build -not -name ${FOLDER_NAME} -exec mv {} ${FOLDER_NAME}/ \; - - echo "::group::Create tarball (xz) bundle" - tar --xz -cvf build/bundles/${FOLDER_NAME}-source.tar.xz ${FOLDER_NAME} - echo "::endgroup::" - - # This tarball is only to be used within this workflow. - echo "::group::Create tarball (gz) bundle" - tar --gzip -cvf source.tar.gz ${FOLDER_NAME} - echo "::endgroup::" - - echo "::group::Create zip bundle" - zip -9 -r build/bundles/${FOLDER_NAME}-source.zip ${FOLDER_NAME} - echo "::endgroup::" - - - name: Store bundles - uses: actions/upload-artifact@v3 - with: - name: openttd-source - path: build/bundles/* - retention-days: 5 - - - name: Store source (for other jobs) - uses: actions/upload-artifact@v3 - with: - name: internal-source - path: source.tar.gz - retention-days: 1 + uses: ./.github/workflows/release-source.yml + secrets: inherit docs: name: Docs needs: source - runs-on: ubuntu-20.04 - - steps: - - name: Download source - uses: actions/download-artifact@v3 - with: - name: internal-source - - - name: Unpack source - run: | - tar -xf source.tar.gz --strip-components=1 - - - name: Install dependencies - run: | - echo "::group::Update apt" - sudo apt-get update - echo "::endgroup::" - - echo "::group::Install dependencies" - sudo apt-get install -y --no-install-recommends \ - doxygen \ - # EOF - echo "::endgroup::" - env: - DEBIAN_FRONTEND: noninteractive - - - name: Build - run: | - mkdir -p ${GITHUB_WORKSPACE}/build - cd ${GITHUB_WORKSPACE}/build - - echo "::group::CMake" - cmake ${GITHUB_WORKSPACE} \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DOPTION_DOCS_ONLY=ON \ - # EOF - echo "::endgroup::" - - echo "::group::Build" - cmake --build . --target docs - echo "::endgroup::" - - - name: Create bundles - run: | - BASENAME=openttd-${{ needs.source.outputs.version }} - - cd ${GITHUB_WORKSPACE}/build - - mv docs/source ${BASENAME}-docs - mv docs/ai-api ${BASENAME}-docs-ai - mv docs/gs-api ${BASENAME}-docs-gs - - mkdir -p bundles - - echo "::group::Create docs bundle" - tar --xz -cf bundles/${BASENAME}-docs.tar.xz ${BASENAME}-docs - echo "::endgroup::" - - echo "::group::Create AI API docs bundle" - tar --xz -cf bundles/${BASENAME}-docs-ai.tar.xz ${BASENAME}-docs-ai - echo "::endgroup::" + uses: ./.github/workflows/release-docs.yml + secrets: inherit - echo "::group::Create GameScript API docs bundle" - tar --xz -cf bundles/${BASENAME}-docs-gs.tar.xz ${BASENAME}-docs-gs - echo "::endgroup::" - - - name: Store bundles - uses: actions/upload-artifact@v3 - with: - name: openttd-docs - path: build/bundles/*.tar.xz - retention-days: 5 + with: + version: ${{ needs.source.outputs.version }} emscripten: name: Emscripten @@ -349,581 +116,91 @@ jobs: name: Linux (Generic) needs: source - runs-on: ubuntu-20.04 - container: - # manylinux2014 is based on CentOS 7, but already has a lot of things - # installed and preconfigured. It makes it easier to build OpenTTD. - image: quay.io/pypa/manylinux2014_x86_64 - - steps: - - name: Download source - uses: actions/download-artifact@v3 - with: - name: internal-source - - - name: Unpack source - run: | - tar -xf source.tar.gz --strip-components=1 - - - name: Install dependencies - run: | - echo "::group::Install dependencies" - yum install -y \ - fontconfig-devel \ - freetype-devel \ - libicu-devel \ - libpng-devel \ - libpng-devel \ - lzo-devel \ - SDL2-devel \ - wget \ - xz-devel \ - zlib-devel \ - # EOF - echo "::endgroup::" - - # The yum variant of fluidsynth depends on all possible audio drivers, - # like jack, ALSA, pulseaudio, etc. This is not really useful for us, - # as we route the output of fluidsynth back via our sound driver, and - # as such do not use these audio driver outputs at all. So instead, - # we compile fluidsynth ourselves, with as little dependencies as - # possible. This currently means it picks up SDL2, but this is fine, - # as we need SDL2 anyway. - echo "::group::Install fluidsynth" - wget https://github.com/FluidSynth/fluidsynth/archive/v2.1.6.tar.gz - tar xf v2.1.6.tar.gz - ( - cd fluidsynth-2.1.6 - mkdir build - cd build - cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr - cmake --build . -j $(nproc) - cmake --install . - ) - echo "::endgroup::" - - - name: Install GCC problem matcher - uses: ammaraskar/gcc-problem-matcher@master - - - name: Build - run: | - mkdir -p build - cd build - - echo "::group::CMake" - cmake ${GITHUB_WORKSPACE} \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DOPTION_PACKAGE_DEPENDENCIES=ON \ - # EOF - echo "::endgroup::" - - echo "::group::Build" - echo "Running on $(nproc) cores" - cmake --build . -j $(nproc) - echo "::endgroup::" - - - name: Create bundles - run: | - cd ${GITHUB_WORKSPACE}/build - echo "::group::Run CPack" - cpack - echo "::endgroup::" - - echo "::group::Cleanup" - # Remove the sha256 files CPack generates; we will do this ourself at - # the end of this workflow. - rm -f bundles/*.sha256 - echo "::endgroup::" - - - name: Store bundles - uses: actions/upload-artifact@v3 - with: - name: openttd-linux-generic - path: build/bundles - retention-days: 5 - - linux-distro: - name: Linux (Distros) - needs: source - - if: needs.source.outputs.is_tag == 'true' - - strategy: - fail-fast: false - matrix: - include: - - container_image: "ubuntu:20.04" - bundle_name: "focal" - compiler: "g++" - - container_image: "debian:bullseye" - bundle_name: "bullseye" - compiler: "g++" - - runs-on: ubuntu-20.04 - container: - image: ${{ matrix.container_image }} - - steps: - - name: Download source - uses: actions/download-artifact@v3 - with: - name: internal-source - - - name: Unpack source - run: | - tar -xf source.tar.gz --strip-components=1 - - - name: Install dependencies - run: | - echo "::group::Update apt" - apt-get update - echo "::endgroup::" - - echo "::group::Install dependencies" - apt-get install -y --no-install-recommends \ - cmake \ - debhelper \ - ${{ matrix.compiler }} \ - git \ - make \ - openssl \ - libfontconfig-dev \ - libfluidsynth-dev \ - libicu-dev \ - liblzma-dev \ - liblzo2-dev \ - libsdl2-dev \ - lsb-release \ - zlib1g-dev \ - # EOF - echo "::endgroup::" - env: - DEBIAN_FRONTEND: noninteractive - - - name: Install GCC problem matcher - uses: ammaraskar/gcc-problem-matcher@master - - - name: Build - run: | - mkdir -p build - cd build - - echo "::group::CMake" - CXX=${{ matrix.compiler }} cmake ${GITHUB_WORKSPACE} \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_INSTALL_PREFIX=/usr \ - # EOF - echo "::endgroup::" - - echo "::group::Build" - echo "Running on $(nproc) cores" - # Ubuntu 18.04 cmake does not support -j so we pass the option to the native tool - cmake --build . -- -j $(nproc) - echo "::endgroup::" - - - name: Create bundles - run: | - cd ${GITHUB_WORKSPACE}/build - echo "::group::Run CPack" - cpack - echo "::endgroup::" - - echo "::group::Cleanup" - # Remove the sha256 files CPack generates; we will do this ourself at - # the end of this workflow. - rm -f bundles/*.sha256 - echo "::endgroup::" - - - name: Store bundles - uses: actions/upload-artifact@v3 - with: - name: openttd-linux-${{ matrix.bundle_name }} - path: build/bundles - retention-days: 5 + uses: ./.github/workflows/release-linux.yml + secrets: inherit macos: name: MacOS needs: source - runs-on: macos-11 - env: - MACOSX_DEPLOYMENT_TARGET: 10.14 - - steps: - - name: Download source - uses: actions/download-artifact@v3 - with: - name: internal-source - - - name: Unpack source - run: | - tar -xf source.tar.gz --strip-components=1 - - - name: Install dependencies - env: - HOMEBREW_NO_AUTO_UPDATE: 1 - HOMEBREW_NO_INSTALL_CLEANUP: 1 - run: | - brew install \ - pandoc \ - pkg-config \ - # EOF - - - name: Prepare cache key - id: key - run: | - echo "::set-output name=image::$ImageOS-$ImageVersion" - - - name: Enable vcpkg cache - uses: actions/cache@v3 - with: - path: /usr/local/share/vcpkg/installed - key: ${{ steps.key.outputs.image }}-vcpkg-release-0 # Increase the number whenever dependencies are modified - restore-keys: | - ${{ steps.key.outputs.image }}-vcpkg-release - ${{ steps.key.outputs.image }}-vcpkg-x64 - - - name: Prepare vcpkg - run: | - vcpkg install \ - liblzma:x64-osx \ - liblzma:arm64-osx \ - libpng:x64-osx \ - libpng:arm64-osx \ - lzo:x64-osx \ - lzo:arm64-osx \ - zlib:x64-osx \ - zlib:arm64-osx \ - # EOF - - - name: Install GCC problem matcher - uses: ammaraskar/gcc-problem-matcher@master - - - name: Build tools - run: | - mkdir build-host - cd build-host - - echo "::group::CMake" - cmake ${GITHUB_WORKSPACE} \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DOPTION_TOOLS_ONLY=ON \ - # EOF - echo "::endgroup::" - - echo "::group::Build tools" - echo "Running on $(sysctl -n hw.logicalcpu) cores" - cmake --build . -j $(sysctl -n hw.logicalcpu) --target tools - echo "::endgroup::" - - - name: Import code signing certificates - uses: Apple-Actions/import-codesign-certs@v1 - with: - # The certificates in a PKCS12 file encoded as a base64 string - p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }} - # The password used to import the PKCS12 file. - p12-password: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }} - # If this is run on a fork, there may not be a certificate set up - continue in this case - continue-on-error: true - - - name: Build arm64 - run: | - mkdir build-arm64 - cd build-arm64 - - echo "::group::CMake" - cmake ${GITHUB_WORKSPACE} \ - -DCMAKE_OSX_ARCHITECTURES=arm64 \ - -DVCPKG_TARGET_TRIPLET=arm64-osx \ - -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake \ - -DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - # EOF - echo "::endgroup::" - - echo "::group::Build" - echo "Running on $(sysctl -n hw.logicalcpu) cores" - cmake --build . -j $(sysctl -n hw.logicalcpu) - echo "::endgroup::" - - - name: Build x64 - run: | - mkdir build-x64 - cd build-x64 - - echo "::group::CMake" - cmake ${GITHUB_WORKSPACE} \ - -DCMAKE_OSX_ARCHITECTURES=x86_64 \ - -DVCPKG_TARGET_TRIPLET=x64-osx \ - -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake \ - -DHOST_BINARY_DIR=${GITHUB_WORKSPACE}/build-host \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCPACK_BUNDLE_APPLE_CERT_APP=${{ secrets.APPLE_DEVELOPER_CERTIFICATE_ID }} \ - "-DCPACK_BUNDLE_APPLE_CODESIGN_PARAMETER=--deep -f --options runtime" \ - -DAPPLE_UNIVERSAL_PACKAGE=1 \ - # EOF - echo "::endgroup::" - - echo "::group::Build" - echo "Running on $(sysctl -n hw.logicalcpu) cores" - cmake --build . -j $(sysctl -n hw.logicalcpu) - echo "::endgroup::" - - - name: Create bundles - run: | - cd build-x64 - - echo "::group::Create universal binary" - # Combine the `openttd` binaries from each build into a single file - lipo -create -output openttd-universal ../build-*/openttd - mv openttd-universal openttd - echo "::endgroup::" - - echo "::group::Run CPack" - cpack - echo "::endgroup::" - - echo "::group::Cleanup" - # Remove the sha256 files CPack generates; we will do this ourself at - # the end of this workflow. - rm -f bundles/*.sha256 - echo "::endgroup::" - - - name: Install gon - env: - HOMEBREW_NO_AUTO_UPDATE: 1 - HOMEBREW_NO_INSTALL_CLEANUP: 1 - run: | - brew tap mitchellh/gon - brew install mitchellh/gon/gon - - - name: Notarize - env: - AC_USERNAME: ${{ secrets.APPLE_DEVELOPER_APP_USERNAME }} - AC_PASSWORD: ${{ secrets.APPLE_DEVELOPER_APP_PASSWORD }} - run: | - cd build-x64 - ../os/macosx/notarize.sh - - - name: Build zip - run: | - cd build-x64 - - pushd _CPack_Packages/*/Bundle/openttd-*/ - - # Remove the Applications symlink from the staging folder - rm -f Applications - - # Remove the original dmg built by CPack to avoid a conflict when resolving - # the zip_filename variable below - rm -f ../*.dmg - - zip_filename=(../openttd-*) - - # Package up the existing, notarised .app into a zip file - zip -r -9 ${zip_filename}.zip OpenTTD.app - - popd - - # Now move it into place to be uploaded - mv _CPack_Packages/*/Bundle/openttd-*.zip bundles/ - - - name: Store bundles - uses: actions/upload-artifact@v3 - with: - name: openttd-macos-universal - path: build-x64/bundles - retention-days: 5 + uses: ./.github/workflows/release-macos.yml + secrets: inherit windows: name: Windows needs: source - strategy: - fail-fast: false - matrix: - include: - - arch: x86 - host: x86 - - arch: x64 - host: x64 - - arch: arm64 - host: x64_arm64 - - runs-on: windows-latest - - steps: - - name: Download source - uses: actions/download-artifact@v3 - with: - name: internal-source - - - name: Unpack source - shell: bash - run: | - tar -xf source.tar.gz --strip-components=1 - - - name: Install dependencies - shell: bash - run: | - choco install pandoc - - - name: Prepare cache key - id: key - shell: powershell - run: | - # Work around caching failure with GNU tar - New-Item -Type Junction -Path vcpkg -Target c:\vcpkg - - Write-Output "::set-output name=image::$env:ImageOS-$env:ImageVersion" - - - name: Enable vcpkg cache - uses: actions/cache@v3 - with: - path: vcpkg/installed - key: ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }}-0 # Increase the number whenever dependencies are modified - restore-keys: | - ${{ steps.key.outputs.image }}-vcpkg-${{ matrix.arch }} - - - name: Prepare vcpkg - shell: bash - run: | - vcpkg install --triplet=${{ matrix.arch }}-windows-static \ - liblzma \ - libpng \ - lzo \ - zlib \ - # EOF - - - name: Install MSVC problem matcher - uses: ammaraskar/msvc-problem-matcher@master - - - name: Configure developer command prompt for tools - uses: ilammy/msvc-dev-cmd@v1 - with: - arch: x64 - - - name: Build tools - shell: bash - run: | - mkdir build-host - cd build-host + uses: ./.github/workflows/release-windows.yml + secrets: inherit - echo "::group::CMake" - cmake ${GITHUB_WORKSPACE} \ - -GNinja \ - -DOPTION_TOOLS_ONLY=ON \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - # EOF - echo "::endgroup::" + with: + is_tag: ${{ needs.source.outputs.is_tag }} - echo "::group::Build" - cmake --build . --target tools - echo "::endgroup::" + windows-store: + name: Windows Store + needs: + - source + - windows - - name: Configure developer command prompt for ${{ matrix.arch }} - uses: ilammy/msvc-dev-cmd@v1 - 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 - run: | - mkdir build - cd build - - echo "::group::CMake" - cmake ${GITHUB_WORKSPACE} \ - -GNinja \ - -DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \ - -DCMAKE_TOOLCHAIN_FILE="c:\vcpkg\scripts\buildsystems\vcpkg.cmake" \ - -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' - shell: bash - run: | - mkdir build - cd build - - echo "::group::CMake" - cmake ${GITHUB_WORKSPACE} \ - -GNinja \ - -DVCPKG_TARGET_TRIPLET=${{ matrix.arch }}-windows-static \ - -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 - run: | - cd ${GITHUB_WORKSPACE}/build - echo "::group::Run CPack" - cpack - echo "::endgroup::" - - echo "::group::Prepare PDB to be bundled" - PDB=$(ls bundles/*.zip | cut -d/ -f2 | sed 's/.zip$/.pdb/') - cp openttd.pdb bundles/${PDB} - xz -9 bundles/${PDB} - echo "::endgroup::" - - echo "::group::Cleanup" - # Remove the sha256 files CPack generates; we will do this ourself at - # the end of this workflow. - 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 }} + if: needs.source.outputs.is_tag == 'true' - - name: Store bundles - uses: actions/upload-artifact@v3 - with: - name: openttd-windows-${{ matrix.arch }} - path: build/bundles - retention-days: 5 + uses: ./.github/workflows/release-windows-store.yml + secrets: inherit + + with: + version: ${{ needs.source.outputs.version }} + + upload-aws: + name: Upload (AWS) + needs: + - source + - docs + - linux + - macos + - windows + - windows-store + + # As windows-store is condition, we need to check ourselves if we need to run. + # The always() makes sure the rest is always evaluated. + if: always() && needs.source.result == 'success' && needs.docs.result == 'success' && needs.linux.result == 'success' && needs.macos.result == 'success' && needs.windows.result == 'success' && (needs.windows-store.result == 'success' || needs.windows-store.result == 'skipped') + + uses: ./.github/workflows/upload-aws.yml + secrets: inherit + + with: + version: ${{ needs.source.outputs.version }} + folder: ${{ needs.source.outputs.folder }} + trigger_type: ${{ needs.source.outputs.trigger_type }} + + upload-steam: + name: Upload (Steam) + needs: + - source + - linux + - macos + - windows + + if: needs.source.outputs.trigger_type == 'new-master' || needs.source.outputs.trigger_type == 'new-tag' + + uses: ./.github/workflows/upload-steam.yml + secrets: inherit + + with: + version: ${{ needs.source.outputs.version }} + trigger_type: ${{ needs.source.outputs.trigger_type }} + + upload-gog: + name: Upload (GOG) + needs: + - source + - linux + - macos + - windows + + if: needs.source.outputs.trigger_type == 'new-tag' + + uses: ./.github/workflows/upload-gog.yml + secrets: inherit + + with: + version: ${{ needs.source.outputs.version }} diff --git a/.github/workflows/script-missing-mode-enforcement.yml b/.github/workflows/script-missing-mode-enforcement.yml new file mode 100644 index 0000000000000..9b9e8e7efa0ac --- /dev/null +++ b/.github/workflows/script-missing-mode-enforcement.yml @@ -0,0 +1,22 @@ +name: Script missing mode enforcement + +on: + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + +jobs: + script-missing-mode-enforcement: + name: Script missing mode enforcement + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Check for finding script functions that require company/deity mode enforcement/checks + run: | + set -ex + python3 .github/script-missing-mode-enforcement.py diff --git a/.github/workflows/unused-strings.yml b/.github/workflows/unused-strings.yml index 6026671307474..08a0cb26e7474 100644 --- a/.github/workflows/unused-strings.yml +++ b/.github/workflows/unused-strings.yml @@ -3,6 +3,10 @@ name: Unused strings on: pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + jobs: unused-strings: name: Unused strings diff --git a/.github/workflows/upload-aws.yml b/.github/workflows/upload-aws.yml new file mode 100644 index 0000000000000..72319ad5ab044 --- /dev/null +++ b/.github/workflows/upload-aws.yml @@ -0,0 +1,76 @@ +name: Upload (AWS) + +on: + workflow_call: + inputs: + version: + required: true + type: string + folder: + required: true + type: string + trigger_type: + required: true + type: string + +jobs: + upload: + name: Upload (AWS) + + runs-on: ubuntu-20.04 + + steps: + - name: Download all bundles + uses: actions/download-artifact@v3 + + - name: Calculate checksums + run: | + echo "::group::Move bundles to a single folder" + mkdir bundles + mv openttd-*/* bundles/ + echo "::endgroup::" + + cd bundles + for i in $(ls openttd-*); do + echo "::group::Calculating checksums for ${i}" + openssl dgst -r -md5 -hex $i > $i.md5sum + openssl dgst -r -sha1 -hex $i > $i.sha1sum + openssl dgst -r -sha256 -hex $i > $i.sha256sum + echo "::endgroup::" + done + + # Some targets generate files that are meant for our-eyes-only. + # They are stored in the "internal" folder, and contains bundles + # for targets like Windows Store. No user has a benefit of knowing + # they exist, hence: internal. + if [ -e internal ]; then + cd internal + for i in $(ls openttd-*); do + echo "::group::Calculating checksums for ${i}" + openssl dgst -r -md5 -hex $i > $i.md5sum + openssl dgst -r -sha1 -hex $i > $i.sha1sum + openssl dgst -r -sha256 -hex $i > $i.sha256sum + echo "::endgroup::" + done + fi + + - name: Upload bundles to AWS + run: | + aws s3 cp --recursive --only-show-errors bundles/ s3://${{ secrets.CDN_S3_BUCKET }}/${{ inputs.folder }}/${{ inputs.version }}/ + + # We do not invalidate the CloudFront distribution here. The trigger + # for "New OpenTTD release" first updated the manifest files and + # creates an index.html. We invalidate after that, so everything + # becomes visible at once. + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }} + + - name: Trigger 'New OpenTTD release' + uses: peter-evans/repository-dispatch@v2 + with: + token: ${{ secrets.DEPLOYMENT_TOKEN }} + repository: OpenTTD/workflows + event-type: ${{ inputs.trigger_type }} + client-payload: '{"version": "${{ inputs.version }}", "folder": "${{ inputs.folder }}"}' diff --git a/.github/workflows/upload-gog.yml b/.github/workflows/upload-gog.yml new file mode 100644 index 0000000000000..b4a591fdccd7d --- /dev/null +++ b/.github/workflows/upload-gog.yml @@ -0,0 +1,124 @@ +name: Upload (GOG) + +on: + workflow_call: + inputs: + version: + required: true + type: string + +jobs: + upload: + name: Upload (GOG) + + runs-on: ubuntu-20.04 + + steps: + - name: Download all bundles + uses: actions/download-artifact@v3 + + - name: Install GOG Galaxy Build Creator + run: | + wget https://cdn.gog.com/open/galaxy/pipeline/build_creator/gnu-linux/GOGGalaxyBuildCreator-1.4.0.AppImage + 7z x GOGGalaxyBuildCreator-1.4.0.AppImage + chmod +x ./app/GOGGalaxyPipelineBuilder + + - name: Install OpenGFX + shell: bash + run: | + mkdir -p gog/opengfx/baseset + cd gog/opengfx/baseset + + echo "::group::Download OpenGFX" + curl -L https://cdn.openttd.org/opengfx-releases/7.1/opengfx-7.1-all.zip -o opengfx-all.zip + echo "::endgroup::" + + echo "::group::Unpack OpenGFX" + unzip opengfx-all.zip + echo "::endgroup::" + + rm -f opengfx-all.zip + + - name: Install OpenMSX + shell: bash + run: | + mkdir -p gog/openmsx/baseset + cd gog/openmsx/baseset + + echo "::group::Download OpenMSX" + curl -L https://cdn.openttd.org/openmsx-releases/0.4.2/openmsx-0.4.2-all.zip -o openmsx-all.zip + echo "::endgroup::" + + echo "::group::Unpack OpenGFX" + unzip openmsx-all.zip + tar xf openmsx-*.tar + echo "::endgroup::" + + rm -f openmsx-all.zip openmsx-*.tar + + - name: Install OpenSFX + shell: bash + run: | + mkdir -p gog/opensfx/baseset + cd gog/opensfx/baseset + + echo "::group::Download OpenSFX" + curl -L https://cdn.openttd.org/opensfx-releases/1.0.3/opensfx-1.0.3-all.zip -o opensfx-all.zip + echo "::endgroup::" + + echo "::group::Unpack OpenSFX" + unzip opensfx-all.zip + tar xf opensfx-*.tar + echo "::endgroup::" + + rm -f opensfx-all.zip opensfx-*.tar + + - name: Upload to GOG + run: | + echo "::group::Extracting source" + mkdir source + ( + cd source + tar -xf ../internal-source/source.tar.gz --strip-components=1 + ) + echo "::endgroup::" + + ( + cd gog + + echo "::group::Prepare Win32" + unzip ../openttd-windows-x86/openttd-*-windows-win32.zip + mv openttd-*-windows-win32 win32 + echo "::endgroup::" + + echo "::group::Prepare Win64" + unzip ../openttd-windows-x64/openttd-*-windows-win64.zip + mv openttd-*-windows-win64 win64 + echo "::endgroup::" + + echo "::group::Prepare macOS" + mkdir macos + ( + cd macos + unzip ../../openttd-macos-universal/openttd-*-macos-universal.zip + ) + echo "::endgroup::" + + echo "::group::Prepare Linux" + tar xvf ../openttd-linux-generic/openttd-*-linux-generic-amd64.tar.xz + mv openttd-*-linux-generic-amd64 linux + echo "::endgroup::" + + echo "::group::Preparing build files" + cp ../source/os/gog/*.json . + for json in $(ls *.json); do + sed -i 's/VERSION/${{ inputs.version }}/g;s/CLIENT_ID/${{ secrets.GOG_CLIENT_ID }}/g;s/CLIENT_SECRET/${{ secrets.GOG_CLIENT_SECRET }}/g' ${json} + done + echo "::endgroup::" + + echo "::group::Upload to GOG" + ../app/GOGGalaxyPipelineBuilder build-game --username "${{ secrets.GOG_USERNAME }}" --password "${{ secrets.GOG_PASSWORD }}" --branch Testing windows.json + ../app/GOGGalaxyPipelineBuilder build-game --username "${{ secrets.GOG_USERNAME }}" --password "${{ secrets.GOG_PASSWORD }}" --branch Testing macos.json + ../app/GOGGalaxyPipelineBuilder build-game --username "${{ secrets.GOG_USERNAME }}" --password "${{ secrets.GOG_PASSWORD }}" --branch Testing linux.json + echo "::endgroup::" + ) diff --git a/.github/workflows/upload-steam.yml b/.github/workflows/upload-steam.yml new file mode 100644 index 0000000000000..cd646dd81ca77 --- /dev/null +++ b/.github/workflows/upload-steam.yml @@ -0,0 +1,82 @@ +name: Upload (Steam) + +on: + workflow_call: + inputs: + version: + required: true + type: string + trigger_type: + required: true + type: string + +jobs: + upload: + name: Upload (Steam) + + runs-on: ubuntu-20.04 + + steps: + - name: Download all bundles + uses: actions/download-artifact@v3 + + - name: Setup steamcmd + uses: CyberAndrii/setup-steamcmd@v1 + + - name: Generate Steam auth code + id: steam-totp + uses: CyberAndrii/steam-totp@v1 + with: + shared_secret: ${{ secrets.STEAM_SHARED_SECRET }} + + - name: Upload to Steam + run: | + echo "::group::Extracting source" + mkdir source + ( + cd source + tar -xf ../internal-source/source.tar.gz --strip-components=1 + ) + echo "::endgroup::" + + mkdir steam + ( + cd steam + + echo "::group::Prepare Win32" + unzip ../openttd-windows-x86/openttd-*-windows-win32.zip + mv openttd-*-windows-win32 steam-win32 + echo "::endgroup::" + + echo "::group::Prepare Win64" + unzip ../openttd-windows-x64/openttd-*-windows-win64.zip + mv openttd-*-windows-win64 steam-win64 + echo "::endgroup::" + + echo "::group::Prepare macOS" + mkdir steam-macos + ( + cd steam-macos + unzip ../../openttd-macos-universal/openttd-*-macos-universal.zip + ) + echo "::endgroup::" + + echo "::group::Prepare Linux" + tar xvf ../openttd-linux-generic/openttd-*-linux-generic-amd64.tar.xz + mv openttd-*-linux-generic-amd64 steam-linux + echo "::endgroup::" + + echo "::group::Preparing build file" + if [ "${{ inputs.trigger_type }}" = "new-tag" ]; then + BRANCH="testing" + else + BRANCH="nightly" + fi + cat ../source/os/steam/release.vdf | sed 's/@@DESCRIPTION@@/openttd-${{ inputs.version }}/;s/@@BRANCH@@/'${BRANCH}'/' > release.vdf + cat release.vdf + echo "::endgroup::" + + echo "::group::Upload to Steam" + steamcmd +login ${{ secrets.STEAM_USERNAME }} ${{ secrets.STEAM_PASSWORD }} ${{ steps.steam-totp.outputs.code }} +run_app_build $(pwd)/release.vdf +quit + echo "::endgroup::" + ) diff --git a/CMakeLists.txt b/CMakeLists.txt index f4e08daf4a4ce..19ebc760d6c2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ if(NOT BINARY_NAME) endif() project(${BINARY_NAME} - VERSION 13.0 + VERSION 14.0 ) if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) @@ -22,7 +22,7 @@ if (EMSCRIPTEN) endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") -set(CMAKE_OSX_DEPLOYMENT_TARGET 10.14) +set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13) # Use GNUInstallDirs to allow customisation # but set our own default data and bin dir @@ -124,6 +124,14 @@ find_package(LibLZMA) find_package(LZO) find_package(PNG) +if(WIN32 OR EMSCRIPTEN) + # Windows uses WinHttp for HTTP requests. + # Emscripten uses Javascript for HTTP requests. +else() + # All other targets use libcurl. + find_package(CURL) +endif() + if(NOT OPTION_DEDICATED) if(NOT WIN32) find_package(Allegro) @@ -259,6 +267,10 @@ link_package(ZLIB TARGET ZLIB::ZLIB ENCOURAGED) link_package(LIBLZMA TARGET LibLZMA::LibLZMA ENCOURAGED) link_package(LZO) +if(NOT WIN32 AND NOT EMSCRIPTEN) + link_package(CURL ENCOURAGED) +endif() + if(NOT OPTION_DEDICATED) link_package(Fluidsynth) link_package(SDL) @@ -280,6 +292,8 @@ if(NOT OPTION_DEDICATED) endif() endif() +include(CheckAtomic) + if(APPLE) link_package(Iconv TARGET Iconv::Iconv) @@ -368,6 +382,7 @@ if(WIN32) imm32 usp10 psapi + winhttp ) endif() diff --git a/CODINGSTYLE.md b/CODINGSTYLE.md new file mode 100644 index 0000000000000..2c204446c8dcd --- /dev/null +++ b/CODINGSTYLE.md @@ -0,0 +1,490 @@ +**Why a set coding style is important**
+This project is an open source project. To get open source working as intended, many people should be able to comprehend the code. This implies that there is a well documented and uniform flow of code. +That does not necessarily mean that a contributor should not write optimised yet cryptic code - one should always care about performance. However, other developers need to understand the code which means complicated parts of code **must** have good documentation. + +**Why we require that EVERYTHING is documented**
+What is simple to some might appear very complicated to others. Documentation helps these others. Anyone should be able to improve the code. But the main reason is, that when patch contributors want their patches added to the common codebase, the code needs to be reviewed by one or more developers. Documentation makes reviewing much easier. + +## Coding style for OpenTTD +### Functions +* Function names use [CamelCase](http://www.wikipedia.org/wiki/Camelcase) without underscores. +* Opening curly bracket **{** for a function starts on the next line. +* Use Foo() instead of Foo(void). +```c++ +void ThisIsAFunction() +{ +} +``` + +### Variables +* Variable names are all lowercase, and use "_" as separator. +* Global variables are preceded by an underscore. ("_") Use descriptive names because leading underscores are often used for system / compiler variables. +* Own members of classes should always be referenced using "this->" +* Pointers and references should have their reference symbol next to the name (compatibility with current code). +* Variables that are declared below one another should have their type, name or reference operator, and assignment operator aligned by spaces. +* There are set names for many variables. Those are (but not limited to): Vehicle *u, *v, *w; Station *st; Town *t; Window *w; Engine *e. +* For multiple instances, use numbers "*t1, *t2" or postfixes "*st_from, *st_to". +* Declare variables upon first usage. +* Declare iterators in their loop. +* There is a space between '*' and 'const' in "const pointers" +```c++ +int number = 10; +Vehicle *u_first_wagon = v->next; +int value = v->value; + +uint32 _global_variable = 3750; + +static const char * const _global_array[] = { + "first string", + "second string", + "another string", + "last string followed by comma", +}; + +protected: + char protected_array[10]; + +for (int i = 0;;); +``` + +* Give the variables expedient names, this increases the readability of the code +```c++ +bool is_maglev_train = true; +if (!is_maglev_train) DoSomething(); +``` + +* Some people like to introduce copies of variables to increase readability, which can waste memory. However, in some cases, especially in code pieces which are often called, it makes sense to cache some calculated variables. +```c++ +/* Unoptimized code: + * foo is not touched inside the loop! + */ +for (uint8 i = 0; i < 100000; i++) { + /* Do something */ + if (value_to_check == (foo * 4) % 5 + 6) DoSomething(); + /* Do something else */ +} + +/* Better: + * The used value of foo is calculated outside the loop. + */ +const uint32 bar = (foo * 4) % 5 + 6; +for (uint8 i = 0; i < 100000; i++) { + /* Do something */ + if (value_to_check == bar) DoSomething(); + /* Do something else */ +} +``` + +### Enumerations / static consts +* Enumerations store integers that belong logically together (railtypes, string IDs, etc.). +* Enumeration names also use CamelCase. +* Unscoped enumerators are all caps with "_" between the words. +* Scoped enumerators are use CamelCase. +* Enums are not used to store single numbers. +* Enums have consecutive numbers OR +* Enums have consecutive powers of two. Powers of two (bits) are written in hex or with the shift operator. +* Enums may have special enumerators: "_BEGIN", "\_END", and "INVALID\_"). See example. +* The invalid always has 0xFF, 0xFFFF, 0xFFFFFFFF as a value. +* Other special values are consecutively less than the invalid. +* Variables that hold enumerators should have the type of the enumeration. +```c++ +enum DiagDirection { + DIAGDIR_BEGIN = 0, + DIAGDIR_NE = 0, + DIAGDIR_SE = 1, + DIAGDIR_SW = 2, + DIAGDIR_NW = 3, + DIAGDIR_END, + INVALID_DIAGDIR = 0xFF, + BROKEN_DIAGDIR = 0xFE, +}; + +enum { + DEPOT_SERVICE = (1 << 0), + DEPOT_MASS_SEND = (1 << 1), + DEPOT_DONT_CANCEL = (1 << 2), + DEPOT_LOCATE_HANGAR = (1 << 3), +}; + +DiagDirection enterdir = DIAGDIR_NE; +``` + +* Numbers that store single or uncorrelated data are static consts. Those may use the naming conventions of enums. +Example: +```c++ +static const int MAXIMUM_STATIONS = 42; +``` + +* Enums are useful in GUI code: When widgets are enumerated, they are easier to access during many operations. Additionally changes caused by modified widget sequences require less code adapting. If a widget is used like this, its enum name should be present in a comment behind the corresponding widget definition. +```c++ +/** Enum referring to the widgets of the build rail depot window */ +enum BuildRailDepotWidgets { + BRDW_CLOSEBOX = 0, + BRDW_CAPTION, + BRDW_BACKGROUND, + BRDW_DEPOT_NE, + BRDW_DEPOT_SE, + BRDW_DEPOT_SW, + BRDW_DEPOT_NW, +}; +/* ... */ +/** Widget definition of the build rail depot window */ +static const Widget _build_depot_widgets[] = { +{ WWT_CLOSEBOX, RESIZE_NONE, 7, 0, 10, 0, 13, STR_00C5, STR_..}, // BRDW_CLOSEBOX +{ WWT_CAPTION, RESIZE_NONE, 7, 11, 139, 0, 13, STR_..., STR_...}, // BRDW_CAPTION +{ WWT_PANEL, RESIZE_NONE, 7, 0, 139, 14, 121, 0x0, STR_NULL}, // BRDW_BACKGROUND +{ WWT_PANEL, RESIZE_NONE, 14, 71, 136, 17, 66, 0x0, STR_..}, // BRDW_DEPOT_NE +{ WWT_PANEL, RESIZE_NONE, 14, 71, 136, 69, 118, 0x0, STR_..}, // BRDW_DEPOT_SE +{ WWT_PANEL, RESIZE_NONE, 14, 3, 68, 69, 118, 0x0, STR_..}, // BRDW_DEPOT_SW +{ WWT_PANEL, RESIZE_NONE, 14, 3, 68, 17, 66, 0x0, STR_..}, // BRDW_DEPOT_NW +{ WIDGETS_END}, +}; +``` + +* Comments on the enum values should start with "///<" to enable doxygen documentation +```c++ +enum SomeEnumeration { + SE_BEGIN = 0, ///< Begin of the enumeration, used for iterations + SE_FOO = 0, ///< Used for xy + SE_BAR, ///< Another value of the enumeration + SE_SUB, ///< Special case for z + SE_END, ///< End of the enumeration, used for iterations +}; +``` + +### Control flow +* Put a space before the parentheses in **if**, **switch**, **for** and **while** statements. +* Use curly braces and put the contained statements on their own lines (e.g., don't put them directly after the **if**). +* Opening curly bracket **{** stays on the first line, closing curly bracket **}** gets a line to itself (except for the **}** preceding an **else**, which should be on the same line as the **else**). +* When only a single statement is contained, the brackets can be omitted. In this case, put the single statement on the same line as the preceding keyword (**if**, **while**, etc.). Note that this is only allowed for if statements without an **else** clause. +* All fall throughs must be documented, using a **FALLTHROUGH** define/macro. +* The NOT_REACHED() macro can be used in default constructs that should never be reached. +* Unconditional loops are written with **`for (;;) {`** + +```c++ +if (a == b) { + Foo(); +} else { + Bar(); +} + +if (very_large_checks && + spread_over_two_lines) { + Foo(); +} + +if (a == b) Foo(); + +switch (a) { + case 0: DoSomethingShort(); break; + + case 1: + DoSomething(); + /* FALL THROUGH */ + + case 2: + DoMore(); + b = a; + break; + + case 3: { + int r = 2; + + DoEvenMore(a); + /* FALL THROUGH */ + } + + case 4: { + int q = 345; + + DoIt(); + break; + } + + default: + NOT_REACHED(); +} + +for (int i = 0; i < 10; i++) { + Foo(); + Bar(); +} +``` + +### Classes +* Classes names also use CamelCase. +* Classes should have "public", "protected", and "private" sections. +* Within these section the order is: types, static const members, static members, members, constructors / destructors, static methods, methods. +* Deviations from above order are allowed when the code dictates it (e.g. a static const is needed for a typedef) +* Methods and members ought to be grouped logically. +* All those sorting rules sometimes conflict which one another. Please use common sense what increases legibility of the code in such a case. +* The method implementation should indicate if it is virtual or similar by using a comment. +* Very short methods can have one-line definition (if defined in the class scope). +```c++ +class ThisIsAClass { +public: + typedef Titem_ *ItemPtr; +private: + static const int MAX_SIZE = 500; + int size; + ItemPtr *items; + +public: + explicit ThisIsAClass(); + ~ThisIsAClass(); + + int GetSize() { return this->size; } + virtual void Method(); +}; + +/*virtual*/ void Class::Method() +{ + this->size *= 2; +} +``` + +### Templates +Templates are a very powerful C++ tool, but they can easily confuse beginners. Thus: +* Templates are to be documented in a very clear and verbose manner. Never assume anything in the documentation. +* the template keyword and the template layout get a separate line. typenames are either "T" or preceded by a "T", integers get a single capital letter or a descriptive name preceded by "T". +```c++ +template +int Func(); +``` + +* If you are writing one or more template class in the dedicated header file, use file.hpp for its name instead of file.h. This will let others know that it is template library (includes also implementation), not just header with declarations. + +### Other important rules +* Put a space before and after binary operators: "a + b", "a == b", "a & b", "a <<= b", etc.. Exceptions are ".", "->" and "[]" (no spaces) and "," (just space after it). +* Put parenthesis where it improves readability: "*(b++)" instead of "*b++", and "if ((a & b) && c == 2)" instead of "if (a & b && c == 2)". +* Do not put external declarations in implementation (i.e. cpp) files. +* Use const where possible. +* Do not typedef enums and structs. +* Don't treat non-flags as flags: use "if (char_pointer != nullptr && *char_pointer != '\0')", not "if (char_pointer && *char_pointer)". +* Use "free(p)" instead of "if (p != nullptr) free(p)". "free(nullptr)" doesn't hurt anyone. +* No trailing whitespace. The Github workflows will not allow tabs or space on the end of lines. +* Only use tabs to indent from the start of the line. +* Line length is unlimited. In practice it may be useful to split a long line. When splitting, add two tabs in front of the second part. +* The '#' of preprocessor instructions goes into the first column of a line. Indenting is done after the '#' (using tabs again). +* Use /* */ for single line comments. +* Use // at the end of a command line to indicate comments. +** However, use /* */ after # preprocessor statements as // causes warnings in some compilers and/or might have unwanted side effects. +* C++ is defined using the ASCII character set. Do not use other character sets, not even in comments. +* OpenTTD includes some Objective-C sources (*.mm, used by OSX), which has a special object method invocation syntax: "[ obj doStuff:foo ]". Please use spaces on the inside of the brackets to differentiate from the C array syntax. + +## Documentation +We use [Doxygen](http://doxygen.org/) to automatically generate documentation from the source code. It scans the source files for *recognizable* comments. +* **Make your comments recognizable.** +Doxygen only comments starting with the following style: +```c++ +/** +///< +``` + +Use /** for multi-line comment blocks. Use ///< for single line comments for variables. Use //!< for single-line comments in the NoAI .hpp files. +For comments blocks inside a function always use /* */ or //. Use // only if the comment is on the same line as an instruction, otherwise use /* */. + +### Files +* Put a @file command in a JavaDoc style comment at the start of the file, followed by a description. +```c++ +/** + * @file + * This is the brief description. + * This is the detailed description here and on the following lines. + */ +``` +> ### Warning +> If a file lacks a **file comment block** then NO entities in that file will be documented by Doxygen! + +### Functions +* The documentation should be as close to the actual code as possible to maximise the chance of staying in sync. + * Comments for functions go in the .cpp file. + * Comments for inlines go in the .h/.hpp file. +* Small inlines can have a short 3 or 4 line JavaDoc style comment. +* Completely document larger functions. +* Document obvious parameters and return values too! + +```c++ +/** + * A brief explanation of what the function does and/or what purpose it serves. + * Then follows a more detailed explanation of the function that can span multiple lines. + * + * @param foo Explanation of the foo parameter + * @param bar Explanation of the bar parameter + * @return The sum of foo and bar (@return can be omitted if the return type is void) + * + * @see SomeOtherFunc() + * @see SOME_ENUM + * + * @bug Some bug description + * @bug Another bug description which continues in the next line + * and ends with the following blank line + * + * @todo Some to-do entry + */ +static int FooBar(int foo, int bar) +{ + return foo + bar; +} +``` + +### Classes +* Document structs similarly to functions: +```c++ +/** + * A short description of the struct. + * More detailed description of the its usage. + * + * @see [link to anything of interest] + */ +struct foo { +} +``` + +### JavaDoc structural commands + +This table shows the commands you should use with OpenTTD. The full list is [here](http://www.stack.nl/~dimitri/doxygen/commands.html). + +| Command | Action | Example | +| ------- | -------- | ------- | +| **@attention** | Starts a paragraph where a message that needs attention may be entered. The paragraph will be indented. | @attention Whales crossing! | +| **@brief** | Starts a paragraph that serves as a brief description. For classes and files the brief description will be used in lists and at the start of the documentation page. For class and file members, the brief description will be placed at the declaration of the member and prepended to the detailed description. A brief description may span several lines (although it is advised to keep it brief!). | @brief This is the brief description. | +| **@bug** | Starts a paragraph where one or more bugs may be reported. The paragraph will be indented. Multiple adjacent @bug commands will be joined into a single paragraph. Each bug description will start on a new line. Alternatively, one @bug command may mention several bugs. | @bug Memory leak in here? | +| **@note** | Starts a paragraph where a note can be entered. The paragraph will be indented. | @note Might be slow | +| **@todo** | Starts a paragraph where a TODO item is described. The description will also add an item to a separate TODO list. The two instances of the description will be cross-referenced. Each item in the TODO list will be preceded by a header that indicates the origin of the item. | @todo Better error checking | +| **@warning** | Starts a paragraph where one or more warning messages may be entered. The paragraph will be indented. | @warning Not thread safe! | +| | **Function related commands** | | +| **@return** | Starts a return value description for a function. | @return a character pointer | +| **@param** | Starts a parameter description for a function parameter with name . Followed by a description of the parameter. The existence of the parameter is checked and a warning is given if the documentation of this (or any other) parameter is missing or not present in the function declaration or definition.

The @param command has an optional attribute specifying the direction of the attribute. Possible values are "in" and "out". | @param n The number of bytes to copy
@param[out] dest The memory area to copy to.
@param[in] src The memory area to copy from. | +| **@see** | Starts a paragraph where one or more cross-references to classes, functions, methods, variables, files or URL may be specified. Two names joined by either :: or # are understood as referring to a class and one of its members. One of several overloaded methods or constructors may be selected by including a parenthesized list of argument types after the method name. [Here](http://www.stack.nl/~dimitri/doxygen/autolink.html) you can find detailed information about this feature. | @see OtherFunc() | +| **@b** | Displays the following word using a bold font. Equivalent to <b>word</b>. To put multiple words in bold use <b>multiple words</b>.| ...@b this and @b that... | +| **@c / @p** | Displays the parameter using a typewriter font. You can use this command to refer to member function parameters in the running text. To have multiple words in typewriter font use <tt>multiple words</tt>. | ... the @p x and @p y coordinates are used to... | +| **@arg / @li** | This command has one argument that continues until the first blank line or until another @arg / @li is encountered. The command can be used to generate a simple, not nested list of arguments. Each argument should start with an @arg / @li command. | @arg @c AlignLeft left alignment.
@arg @c AlignCenter center alignment.
@arg @c AlignRight right alignment | +| **@n** | Forces a new line. Equivalent to and inspired by the printf function. |@n | + +### More on Doxygen and JavaDoc + +Doxygen knows two different kinds of comments: +* *Brief descriptions*: one-liners that describe the function roughly ([example](http://docs.openttd.org/annotated.html)) +* *Detailed descriptions*: as the name suggests, these contain the detailed function/purpose of the entity they describe ([example](http://docs.openttd.org/structBridge.html)) + +You can omit either one or put them into different places but there's only one brief and one detailed description allowed for the same entity. + +Doxygen knows three modes for documenting an entity: +* Before the entity +* After the entity +* In a different file + +The latter is a little harder to maintain since the prototype of the entity it describes then is stored in several places (e.g. the .h file and the file with the descriptions). Also while it makes the code easier to read it also makes it easier to omit the important step of updating the description of an entity if it was changed - and we all know why that shouldn't happen ;)
+Because of those reasons, we will only use the first two documentation schemes. + + +Doxygen supports both Qt and JavaDoc comment styles: +* Qt style example: **int i; //!< The counter for the main loop** +* JavaDoc style example: **int i; /*\*< The counter for the main loop \*/** + +It also supports more comment styles but those two are the ones which are standardized. For OTTD we'll be using the JavaDoc style. One of the reasons is that it has a feature that the Qt style doesn't offer: JavaDoc style comment blocks will automatically start a brief description which ends at the first dot followed by a space or new line. Everything after that will also be part of the detailed description. + +The general structure of a JavaDoc style comment is +```c++ +/** + * This is the brief description. And this sentence contains some further explanations that will appear in the detailed description only. + */ +``` + +and the resulting descriptions of that block would be: +* *Brief description*: This is the brief description. +* *Detailed description*: This is the brief description. And this sentence contains some further explanations that will appear in the detailed description only. + +The distinction between the brief and detailed descriptions is made by the dot followed by a space/newline, so if you want to use that inside the brief description you need to escape the space/newline: +```c++ +/** + * This is a brief description (e.g.\ using only a few words). Details go here. + */ +``` + +If you're doing a one-line comment, use: +```c++ +int i; ///< This is the description. +``` + +Also in the comment block you can include so-called structural commands which tell Doxygen what follows. In general, their area of effect begins after the command word and ends when a blank line or some other command is encountered. Also, multiple occurrences of the same structural command within a comment block or the referring entity will be joined in the documentation output usually. + +## Commit message +To achieve a coherent whole and to make changelog writing easier, here are some guidelines for commit messages. +There is a check-script on the git server (also available for clients, see below) to make sure we all follow those rules. + +The first line of a message must match: +``` +
+( #| (, ( #|))*)?: ([
+
+``` +Keywords are: +* Add, Feature: Adding new stuff. Difference between "Feature" and "Add" is somewhat subjective. "Feature" for user-point-of-view stuff, "Add" for other. +* Change: Changing behaviour from user-point-of-view. +* Remove: Removing something from user-point-of-view. +* Codechange, Cleanup: Changes without intentional change of behaviour from user-point-of-view. Difference between "Codechange" and "Cleanup" is somewhat subjective. +* Fix, Revert: Fixing stuff. +* Doc, Update: Documentation changes, version increments, translator commits. +* Prepare: Preparation for bigger changes. Rarely used. + +If you commit a fix for an [issue](https://github.com/OpenTTD/OpenTTD/issues), add the corresponding issue number in the form of #NNNN. Do it as well if you implement a feature with a matching entry. + +In the case of bugfixes, if you know what revision the bug was introduced (eg regression), please mention that revision as well just after the prefix. Finding the trouble-causing revision is highly encouraged as it makes backporting/branching/releases that much easier. + +To further structure the changelog, you can add sections. Example are: +* "Network" for network specific changes +* "NewGRF" for NewGRF additions +* "YAPP", "NPF", for changes in these features +* "OSX", "Debian", "win32", for OS-specific packaging changes + +Further explanations, general bitching, etc. don't go into the first line. Use a new line for those. + +Complete examples: +* Fix: [YAPF] Infinite loop in pathfinder. +* Fix #5926: [YAPF] Infinite loop in pathfinder. +* Fix 80dffae130: Warning about unsigned unary minus. +* Fix #6673, 99bb3a95b4: Store the map variety setting in the samegame. +* Revert d9065fbfbe, Fix #5922: ClientSizeChanged is only called via WndProcGdi which already has the mutex. +* Fix #1264, Fix #2037, Fix #2038, Fix #2110: Rewrite the autoreplace kernel. + + +## Other tips +### Remove trailing whitespace +To find out if/where you have trailing whitespace, you can use the following (unix/bash) command: +``` +grep -n -R --include "*.[ch]" '[ ]$' * | grep --invert-match ".diff" | grep --invert-match ".patch" +``` +Automatically removing whitespace is also possible with the following shell script (Note that it only checks .c, .cpp, .h, .hpp and .mm files): +``` +#!/bin/sh +IFS=' +' +for i in Makefile `find . -name \*.c -o -name \*.cpp -o -name \*.h -o -name \*.hpp -o -name \*.mm` +do + ( + echo '%s/[ ]\{1,\}$/' + echo w + echo q + ) | ed $i 2> /dev/null > /dev/null +done +``` + +### Install the client-side git commit hooks + +The client-side hooks perform various checks when you commit changes locally. +* Whitespace and indentation checks. +* **Coding style** checks. + +Get the hooks: +``` +git clone https://github.com/OpenTTD/OpenTTD-git-hooks.git openttd_hooks +``` + +Install the hooks, assuming "openttd" is your work tree folder: +``` +cd openttd/.git/hooks +ln -s -t . ../../../openttd_hooks/hooks/* +``` + diff --git a/COMPILING.md b/COMPILING.md index ba910ed6dfdda..5b1d457224fb2 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -10,14 +10,17 @@ OpenTTD makes use of the following external libraries: - (encouraged) libpng: making screenshots and loading heightmaps - (optional) liblzo2: (de)compressing of old (pre 0.3.0) savegames -For Linux, the following additional libraries are used (for non-dedicated only): +For Linux, the following additional libraries are used: +- (encouraged) libcurl: content downloads - libSDL2: hardware access (video, sound, mouse) - libfreetype: loading generic fonts and rendering them - libfontconfig: searching for fonts, resolving font names to actual fonts - libicu: handling of right-to-left scripts (e.g. Arabic and Persian) and natural sorting of strings +If you are building a dedicated-server only, you don't need the last four. + OpenTTD does not require any of the libraries to be present, but without liblzma you cannot open most recent savegames and without zlib you cannot open most older savegames or use the content downloading system. @@ -97,7 +100,7 @@ Via CMake, several options can be influenced to get different types of builds. - `-DCMAKE_BUILD_TYPE=RelWithDebInfo`: build a release build. This is - significant faster than a debug build, but has far less useful information + significantly faster than a debug build, but has far less useful information in case of a crash. - `-DOPTION_DEDICATED=ON`: build OpenTTD without a GUI. Useful if you are running a headless server, as it requires less libraries to operate. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f9ffdf98ce51d..b0ca0ab7a902d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,8 +94,8 @@ Although we really appreciate feedback and ideas, we will close feature requests Many of those ideas etc do have a place on the [forums](https://www.tt-forums.net); and if enough people like it, someone will stand up and make it. -It's usually best discuss in [irc](https://wiki.openttd.org/en/Development/IRC%20channel) before opening a feature request or working on a large feature in a fork. -Discussion in irc can take time, but it can be productive and avoid disappointment :) +It's usually best to discuss on [Discord](https://discord.gg/openttd) before opening a feature request or working on a large feature in a fork. +Discussion can take time, but it can be productive and avoid disappointment. :) ## Pull requests @@ -212,8 +212,8 @@ When it comes to gameplay features there are at least these groups of interests: - *Control freak:* micromanagement like conditional orders, refitting and loading etc. - *Casual:* automatisation like cargodist, path based signalling etc. -To please everyone, the official branch tries to stay close to the original gameplay; after all, that is what everyone brought here. -The preferred method to alter and extent the gameplay is via add-ons like NewGRF and GameScripts. +To please everyone, the official branch tries to stay close to the original gameplay; after all, that is what brought everyone here. +The preferred method to alter and extend the gameplay is via add-ons like NewGRF and GameScripts. For a long time, the official branch was also open to features which could be enabled/disabled, but the corner-cases that came with some configurations have rendered some parts of the code very complicated. Today, new features have to work with all the already existing features, which is not only challenging in corner cases, but also requires spending considerable more work than just "making it work in the game mode that I play". diff --git a/CREDITS.md b/CREDITS.md index 33f883626561b..8826c9dcfe393 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -1,31 +1,32 @@ ### The OpenTTD team (in alphabetical order): -- Grzegorz Duczyński (adf88) - General coding (since 1.7.2) -- Albert Hofkamp (Alberth) - GUI expert (since 0.7) - Matthijs Kooijman (blathijs) - Pathfinder-guru, Debian port (since 0.3) -- Ulf Hermann (fonsinchen) - Cargo Distribution (since 1.3) - Christoph Elsenhans (frosch) - General coding (since 0.6) -- Loïc Guilloux (glx) - Windows Expert (since 0.4.5) +- Loïc Guilloux (glx) - General / Windows Expert (since 0.4.5) - Charles Pigott (LordAro) - General / Correctness police (since 1.9) -- Michael Lutz (michi_cc) - Path based signals (since 0.7) +- Michael Lutz (michi_cc) - General / Path based signals (since 0.7) - Niels Martin Hansen (nielsm) - Music system, general coding (since 1.9) - Owen Rudge (orudge) - Forum host, OS/2 port (since 0.1) - Peter Nelson (peter1138) - Spiritual descendant from newGRF gods (since 0.4.5) -- Ingo von Borstel (planetmaker) - General coding, Support (since 1.1) -- Remko Bijker (Rubidium) - Lead coder and way more (since 0.4.5) -- José Soler (Terkhen) - General coding (since 1.0) +- Remko Bijker (Rubidium) - Coder and way more (since 0.4.5) +- Patric Stout (TrueBrain) - NoProgrammer (since 0.3), sys op +- Tyler Trahan (2TallTyler) - General coding (since 13) ### Inactive Developers: +- Grzegorz Duczyński (adf88) - General coding (1.7 - 1.8) +- Albert Hofkamp (Alberth) - GUI expert (0.7 - 1.9) - Jean-François Claeys (Belugas) - GUI, newindustries and more (0.4.5 - 1.0) - Bjarni Corfitzen (Bjarni) - macOS port, coder and vehicles (0.3 - 0.7) - Victor Fischer (Celestar) - Programming everywhere you need him to (0.3 - 0.6) +- Ulf Hermann (fonsinchen) - Cargo Distribution (1.3 - 1.6) - Jaroslav Mazanec (KUDr) - YAPG (Yet Another Pathfinder God) ;) (0.4.5 - 0.6) - Jonathan Coome (Maedhros) - High priest of the NewGRF Temple (0.5 - 0.6) -- Attila Bán (MiHaMiX) - WebTranslator 1 and 2 (0.3 - 0.5) +- Attila Bán (MiHaMiX) - Developer WebTranslator 1 and 2 (0.3 - 0.5) +- Ingo von Borstel (planetmaker) - General coding, Support (1.1 - 1.9) - Zdeněk Sojka (SmatZ) - Bug finder and fixer (0.6 - 1.3) +- José Soler (Terkhen) - General coding (1.0 - 1.4) - Christoph Mallon (Tron) - Programmer, code correctness police (0.3 - 0.5) -- Patric Stout (TrueBrain) - NoProgrammer (0.3 - 1.2), sys op (active) - Thijs Marinussen (Yexo) - AI Framework, General (0.6 - 1.3) - Leif Linse (Zuu) - AI/Game Script (1.2 - 1.6) @@ -33,11 +34,11 @@ - Tamás Faragó (Darkvater) - Ex-Lead coder (0.3 - 0.5) - Dominik Scherer (dominik81) - Lead programmer, GUI expert (0.3 - 0.3) -- Emil Djupfeld (egladil) - macOS port (0.4 - 0.6) +- Emil Djupfeld (egladil) - macOS port (0.4.5 - 0.6) - Simon Sasburg (HackyKid) - Bug fixer (0.4 - 0.4.5) - Ludvig Strigeus (ludde) - Original author of OpenTTD, main coder (0.1 - 0.3) - Cian Duffy (MYOB) - BeOS port / manual writing (0.1 - 0.3) -- Petr Baudiš (pasky) - Many patches, newgrf support, etc. (0.3 - 0.3) +- Petr Baudiš (pasky) - Many patches, newgrf support (0.3 - 0.3) - Benedikt Brüggemeier (skidd13) - Bug fixer and code reworker (0.6 - 0.7) - Serge Paquet (vurlix) - 2nd contributor after ludde (0.1 - 0.3) @@ -52,7 +53,7 @@ - Alberto Demichelis - Squirrel scripting language - L. Peter Deutsch - MD5 implementation - Michael Blunck - For revolutionizing TTD with awesome graphics -- George - Canal graphics +- George - Canal/Lock graphics - Andrew Parkhouse (andythenorth) - River graphics - David Dallaston (Pikka) - Tram tracks - All Translators - For their support to make OpenTTD a truly international game diff --git a/Doxyfile.in b/Doxyfile.in index 8727594771c5a..51a44526c3aff 100644 --- a/Doxyfile.in +++ b/Doxyfile.in @@ -41,7 +41,6 @@ INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 2 ALIASES = -TCL_SUBST = OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO @@ -155,7 +154,6 @@ VERBATIM_HEADERS = YES # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output @@ -224,7 +222,7 @@ LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO -PAPER_TYPE = a4wide +PAPER_TYPE = a4 EXTRA_PACKAGES = LATEX_HEADER = LATEX_FOOTER = diff --git a/README.md b/README.md index f1109b13a9589..2b2c23c133f6a 100644 --- a/README.md +++ b/README.md @@ -120,35 +120,6 @@ Most types of add-on content can be downloaded within OpenTTD via the 'Check Onl Add-on content can also be installed manually, but that's more complicated; the [OpenTTD wiki](https://wiki.openttd.org/) may offer help with that, or the [OpenTTD directory structure guide](./docs/directory_structure.md). -### 1.5.1) AI opponents - -OpenTTD comes without AI opponents, so if you want to play with AIs you have to download them. - -The easiest way is via the 'Check Online Content' button in the main menu. - -You can select some AIs that you think are compatible with your playing style. - -AI help and discussions may also be found in the [AI section of the forum](https://www.tt-forums.net/viewforum.php?f=65). - -### 1.5.2) Scenarios and height maps - -Scenarios and heightmaps can be added via the 'Check Online Content' button in the main menu. - -### 1.5.3) NewGRFs - -A wide range of add-content is available as NewGRFs, including vehicles, industries, stations, landscape objects, town names and more. - -NewGRFs can be added via the 'Check Online Content' button in the main menu. - -See also the wiki [guide to NewGRFs](https://wiki.openttd.org/en/Manual/NewGRF) and [the forum graphics development section](https://www.tt-forums.net/viewforum.php?f=66). - -### 1.5.4) Game scripts - -Game scripts can provide additional challenges or changes to the standard OpenTTD gameplay, for example setting transport goals, or changing town growth behaviour. - -Game scripts can be added via the 'Check Online Content' button in the main menu. - -See also the wiki [guide to game scripts](https://wiki.openttd.org/en/Manual/Game%20script) and [the forum graphics game script section](https://www.tt-forums.net/viewforum.php?f=65). ### 1.6) OpenTTD directories @@ -166,6 +137,7 @@ If you want to compile OpenTTD from source, instructions can be found in [COMPIL 'Official' channels - [OpenTTD website](https://www.openttd.org) +- [OpenTTD official Discord](https://discord.gg/openttd) - IRC chat using #openttd on irc.oftc.net [more info about our irc channel](https://wiki.openttd.org/en/Development/IRC%20channel) - [OpenTTD on Github](https://github.com/OpenTTD/) for code repositories and for reporting issues - [forum.openttd.org](https://forum.openttd.org/) - the primary community forum site for discussing OpenTTD and related games diff --git a/bin/ai/CMakeLists.txt b/bin/ai/CMakeLists.txt index 9417004fce93d..7fb23cada3a4f 100644 --- a/bin/ai/CMakeLists.txt +++ b/bin/ai/CMakeLists.txt @@ -13,6 +13,8 @@ set(AI_COMPAT_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/compat_1.10.nut ${CMAKE_CURRENT_SOURCE_DIR}/compat_1.11.nut ${CMAKE_CURRENT_SOURCE_DIR}/compat_12.nut + ${CMAKE_CURRENT_SOURCE_DIR}/compat_13.nut + ${CMAKE_CURRENT_SOURCE_DIR}/compat_14.nut ) foreach(AI_COMPAT_SOURCE_FILE IN LISTS AI_COMPAT_SOURCE_FILES) diff --git a/bin/ai/compat_0.7.nut b/bin/ai/compat_0.7.nut index c40308592cf4a..341b543bd3fa8 100644 --- a/bin/ai/compat_0.7.nut +++ b/bin/ai/compat_0.7.nut @@ -379,3 +379,16 @@ AIGroup.CreateGroup <- function(vehicle_type) { return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID); } + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.0.nut b/bin/ai/compat_1.0.nut index b8da71a1947d2..6b76f115341fd 100644 --- a/bin/ai/compat_1.0.nut +++ b/bin/ai/compat_1.0.nut @@ -131,3 +131,16 @@ AIGroup.CreateGroup <- function(vehicle_type) { return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID); } + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.1.nut b/bin/ai/compat_1.1.nut index f1bda9c7fed4b..9c568a7006e89 100644 --- a/bin/ai/compat_1.1.nut +++ b/bin/ai/compat_1.1.nut @@ -68,3 +68,16 @@ AIGroup.CreateGroup <- function(vehicle_type) { return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID); } + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.10.nut b/bin/ai/compat_1.10.nut index 2baaddb836a34..44bc2542ce70e 100644 --- a/bin/ai/compat_1.10.nut +++ b/bin/ai/compat_1.10.nut @@ -6,3 +6,16 @@ */ AILog.Info("1.10 API compatibility in effect."); + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.11.nut b/bin/ai/compat_1.11.nut index 887f3f7fd9980..3d8370ffc6e39 100644 --- a/bin/ai/compat_1.11.nut +++ b/bin/ai/compat_1.11.nut @@ -6,3 +6,16 @@ */ AILog.Info("1.11 API compatibility in effect."); + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.2.nut b/bin/ai/compat_1.2.nut index 550f79969ce75..fc52b04935d71 100644 --- a/bin/ai/compat_1.2.nut +++ b/bin/ai/compat_1.2.nut @@ -20,3 +20,16 @@ AIGroup.CreateGroup <- function(vehicle_type) { return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID); } + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.3.nut b/bin/ai/compat_1.3.nut index 6b2c7e8a71349..a06e98d2dd1f3 100644 --- a/bin/ai/compat_1.3.nut +++ b/bin/ai/compat_1.3.nut @@ -20,3 +20,16 @@ AIGroup.CreateGroup <- function(vehicle_type) { return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID); } + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.4.nut b/bin/ai/compat_1.4.nut index a9ab5a4757b82..6de24bf80c14d 100644 --- a/bin/ai/compat_1.4.nut +++ b/bin/ai/compat_1.4.nut @@ -20,3 +20,16 @@ AIGroup.CreateGroup <- function(vehicle_type) { return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID); } + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.5.nut b/bin/ai/compat_1.5.nut index 23944149f6ae8..8ff5a39d15ec1 100644 --- a/bin/ai/compat_1.5.nut +++ b/bin/ai/compat_1.5.nut @@ -20,3 +20,16 @@ AIGroup.CreateGroup <- function(vehicle_type) { return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID); } + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.6.nut b/bin/ai/compat_1.6.nut index bcbe91455c0e4..91744512a712f 100644 --- a/bin/ai/compat_1.6.nut +++ b/bin/ai/compat_1.6.nut @@ -20,3 +20,16 @@ AIGroup.CreateGroup <- function(vehicle_type) { return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID); } + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.7.nut b/bin/ai/compat_1.7.nut index 7c2fd9b825110..584a970f60d67 100644 --- a/bin/ai/compat_1.7.nut +++ b/bin/ai/compat_1.7.nut @@ -20,3 +20,16 @@ AIGroup.CreateGroup <- function(vehicle_type) { return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID); } + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.8.nut b/bin/ai/compat_1.8.nut index a118a63b57ae5..f57a0eab2786c 100644 --- a/bin/ai/compat_1.8.nut +++ b/bin/ai/compat_1.8.nut @@ -20,3 +20,16 @@ AIGroup.CreateGroup <- function(vehicle_type) { return AIGroup._CreateGroup(vehicle_type, AIGroup.GROUP_INVALID); } + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_1.9.nut b/bin/ai/compat_1.9.nut index a3d0941327c6c..0dde6dc6dacd1 100644 --- a/bin/ai/compat_1.9.nut +++ b/bin/ai/compat_1.9.nut @@ -6,3 +6,16 @@ */ AILog.Info("1.9 API compatibility in effect."); + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_12.nut b/bin/ai/compat_12.nut index 2ff41f8b4fc7e..d54895632ff2a 100644 --- a/bin/ai/compat_12.nut +++ b/bin/ai/compat_12.nut @@ -6,3 +6,16 @@ */ AILog.Info("12 API compatibility in effect."); + +/* 13 really checks RoadType against RoadType */ +AIRoad._HasRoadType <- AIRoad.HasRoadType; +AIRoad.HasRoadType <- function(tile, road_type) +{ + local list = AIRoadTypeList(AIRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (AIRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/ai/compat_13.nut b/bin/ai/compat_13.nut index 3081fb58e8a51..5f808e38a0f31 100644 --- a/bin/ai/compat_13.nut +++ b/bin/ai/compat_13.nut @@ -4,3 +4,5 @@ * 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 . */ + +AILog.Info("13 API compatibility in effect."); diff --git a/bin/ai/compat_14.nut b/bin/ai/compat_14.nut new file mode 100644 index 0000000000000..3081fb58e8a51 --- /dev/null +++ b/bin/ai/compat_14.nut @@ -0,0 +1,6 @@ +/* + * 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 . + */ diff --git a/bin/game/CMakeLists.txt b/bin/game/CMakeLists.txt index 55a992be324a3..0b48e978572fd 100644 --- a/bin/game/CMakeLists.txt +++ b/bin/game/CMakeLists.txt @@ -10,6 +10,8 @@ set(GS_COMPAT_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/compat_1.10.nut ${CMAKE_CURRENT_SOURCE_DIR}/compat_1.11.nut ${CMAKE_CURRENT_SOURCE_DIR}/compat_12.nut + ${CMAKE_CURRENT_SOURCE_DIR}/compat_13.nut + ${CMAKE_CURRENT_SOURCE_DIR}/compat_14.nut ) foreach(GS_COMPAT_SOURCE_FILE IN LISTS GS_COMPAT_SOURCE_FILES) diff --git a/bin/game/compat_1.10.nut b/bin/game/compat_1.10.nut index 92cef84c536a9..2559ff0a9cd4d 100644 --- a/bin/game/compat_1.10.nut +++ b/bin/game/compat_1.10.nut @@ -13,3 +13,16 @@ GSCompany.ChangeBankBalance <- function(company, delta, expenses_type) { return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID); } + +/* 13 really checks RoadType against RoadType */ +GSRoad._HasRoadType <- GSRoad.HasRoadType; +GSRoad.HasRoadType <- function(tile, road_type) +{ + local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (GSRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/game/compat_1.11.nut b/bin/game/compat_1.11.nut index fa240b5d2d48e..eac9a05d36b21 100644 --- a/bin/game/compat_1.11.nut +++ b/bin/game/compat_1.11.nut @@ -6,3 +6,16 @@ */ GSLog.Info("1.11 API compatibility in effect."); + +/* 13 really checks RoadType against RoadType */ +GSRoad._HasRoadType <- GSRoad.HasRoadType; +GSRoad.HasRoadType <- function(tile, road_type) +{ + local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (GSRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/game/compat_1.2.nut b/bin/game/compat_1.2.nut index 5fb29efedff1b..66e2ca5d6253a 100644 --- a/bin/game/compat_1.2.nut +++ b/bin/game/compat_1.2.nut @@ -35,3 +35,16 @@ GSCompany.ChangeBankBalance <- function(company, delta, expenses_type) { return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID); } + +/* 13 really checks RoadType against RoadType */ +GSRoad._HasRoadType <- GSRoad.HasRoadType; +GSRoad.HasRoadType <- function(tile, road_type) +{ + local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (GSRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/game/compat_1.3.nut b/bin/game/compat_1.3.nut index 7546e54c69dad..9986ea03e5c11 100644 --- a/bin/game/compat_1.3.nut +++ b/bin/game/compat_1.3.nut @@ -35,3 +35,16 @@ GSCompany.ChangeBankBalance <- function(company, delta, expenses_type) { return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID); } + +/* 13 really checks RoadType against RoadType */ +GSRoad._HasRoadType <- GSRoad.HasRoadType; +GSRoad.HasRoadType <- function(tile, road_type) +{ + local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (GSRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/game/compat_1.4.nut b/bin/game/compat_1.4.nut index c90b3e550b711..b3ec5c45cb1d6 100644 --- a/bin/game/compat_1.4.nut +++ b/bin/game/compat_1.4.nut @@ -28,3 +28,15 @@ GSCompany.ChangeBankBalance <- function(company, delta, expenses_type) return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID); } +/* 13 really checks RoadType against RoadType */ +GSRoad._HasRoadType <- GSRoad.HasRoadType; +GSRoad.HasRoadType <- function(tile, road_type) +{ + local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (GSRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/game/compat_1.5.nut b/bin/game/compat_1.5.nut index 0c62e56462a8c..2d25d7acf0d58 100644 --- a/bin/game/compat_1.5.nut +++ b/bin/game/compat_1.5.nut @@ -20,3 +20,16 @@ GSCompany.ChangeBankBalance <- function(company, delta, expenses_type) { return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID); } + +/* 13 really checks RoadType against RoadType */ +GSRoad._HasRoadType <- GSRoad.HasRoadType; +GSRoad.HasRoadType <- function(tile, road_type) +{ + local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (GSRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/game/compat_1.6.nut b/bin/game/compat_1.6.nut index 198b863a77564..d205832209f22 100644 --- a/bin/game/compat_1.6.nut +++ b/bin/game/compat_1.6.nut @@ -20,3 +20,16 @@ GSCompany.ChangeBankBalance <- function(company, delta, expenses_type) { return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID); } + +/* 13 really checks RoadType against RoadType */ +GSRoad._HasRoadType <- GSRoad.HasRoadType; +GSRoad.HasRoadType <- function(tile, road_type) +{ + local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (GSRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/game/compat_1.7.nut b/bin/game/compat_1.7.nut index 76dc424353a05..1108f41a7c085 100644 --- a/bin/game/compat_1.7.nut +++ b/bin/game/compat_1.7.nut @@ -20,3 +20,16 @@ GSCompany.ChangeBankBalance <- function(company, delta, expenses_type) { return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID); } + +/* 13 really checks RoadType against RoadType */ +GSRoad._HasRoadType <- GSRoad.HasRoadType; +GSRoad.HasRoadType <- function(tile, road_type) +{ + local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (GSRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/game/compat_1.8.nut b/bin/game/compat_1.8.nut index b9d27458a9137..139f91214bd2f 100644 --- a/bin/game/compat_1.8.nut +++ b/bin/game/compat_1.8.nut @@ -20,3 +20,16 @@ GSCompany.ChangeBankBalance <- function(company, delta, expenses_type) { return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID); } + +/* 13 really checks RoadType against RoadType */ +GSRoad._HasRoadType <- GSRoad.HasRoadType; +GSRoad.HasRoadType <- function(tile, road_type) +{ + local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (GSRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/game/compat_1.9.nut b/bin/game/compat_1.9.nut index 32eec114afca7..053e377d4c1a0 100644 --- a/bin/game/compat_1.9.nut +++ b/bin/game/compat_1.9.nut @@ -13,3 +13,16 @@ GSCompany.ChangeBankBalance <- function(company, delta, expenses_type) { return GSCompany._ChangeBankBalance(company, delta, expenses_type, GSMap.TILE_INVALID); } + +/* 13 really checks RoadType against RoadType */ +GSRoad._HasRoadType <- GSRoad.HasRoadType; +GSRoad.HasRoadType <- function(tile, road_type) +{ + local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (GSRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/game/compat_12.nut b/bin/game/compat_12.nut index df0858391493a..a11cd04a23655 100644 --- a/bin/game/compat_12.nut +++ b/bin/game/compat_12.nut @@ -6,3 +6,16 @@ */ GSLog.Info("12 API compatibility in effect."); + +/* 13 really checks RoadType against RoadType */ +GSRoad._HasRoadType <- GSRoad.HasRoadType; +GSRoad.HasRoadType <- function(tile, road_type) +{ + local list = GSRoadTypeList(GSRoad.GetRoadTramType(road_type)); + foreach (rt, _ in list) { + if (GSRoad._HasRoadType(tile, rt)) { + return true; + } + } + return false; +} diff --git a/bin/game/compat_13.nut b/bin/game/compat_13.nut index 3081fb58e8a51..0ee9faf2bdd7c 100644 --- a/bin/game/compat_13.nut +++ b/bin/game/compat_13.nut @@ -4,3 +4,5 @@ * 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 . */ + +GSLog.Info("13 API compatibility in effect."); diff --git a/bin/game/compat_14.nut b/bin/game/compat_14.nut new file mode 100644 index 0000000000000..3081fb58e8a51 --- /dev/null +++ b/bin/game/compat_14.nut @@ -0,0 +1,6 @@ +/* + * 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 . + */ diff --git a/changelog.txt b/changelog.txt index 883560397ee87..650c42586e00c 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,213 @@ +13.0-beta2 (2022-11-27) +------------------------------------------------------------------------ +Feature: Allow AI/GS to be fully modified in scenario editor (#10152) +Feature: Display power-to-weight ratio in ground vehicle details GUI (#10123) +Feature: Variable interface scaling (with chunky bevels!) (#10114) +Feature: Hotkey to honk a vehicle's horn (#10110) +Feature: Split AI/Game Script configuration windows and add them to world gen window (#10058) +Feature: [GS] Scriptable league tables (#10001) +Feature: Multi-track level crossings (#9931) +Feature: Improved local authority action window (#9928) +Feature: Automatic console command screenshot numbering with a filename ending in '#' (#9781) +Feature: Add buttons to toggle music in the Game Options menu (#9727) +Feature: Contextual actions for vehicles grouped by shared orders (#8425) +Feature: Add cargo filter support to vehicle list (#8308) +Feature: Show the cargoes the vehicles can carry in the vehicle list window (#8304) +Change: Allow building canal by area outside editor (#10173) +Change: Minor improvements to the new Finance GUI (#10168) +Change: Let AI developers edit non-editable AI/Game Script Parameters (#8895) +Change: Allow building docks on clearable watered object tiles (#8514) +Fix #8770: Center vehicle status bar icon (#10178) +Fix: Crash if error message window is too wide for screen. (#10172) +Fix #10155: Network games not syncing company settings properly (#10158) +Fix #10154: Network game desync related to setting a random company face (#10157) +Fix #10011: Incorrect infrastructure totals when overbuilding bay road stop (#10143) +Fix #10117: Object burst limit allowed one fewer object than the setting (#10120) +Fix #10023: Allow negative input in text fields when needed (#10112) +Fix #9908: Fix crash which could occur when a company was deleted when a depot window was open (#9912) + + +13.0-beta1 (2022-10-31) +------------------------------------------------------------------------ +Feature: Airport construction GUI displays infrastructure cost (#10094) +Feature: Purchase land multiple tiles at a time (#10027) +Feature: Add sticky pin & shade widgets to Object Selection UI panel (#10019, #10020) +Feature: Improved handling of HiDPI and mixed-DPI screens (#9994, #9996, #9997, #10064) +Feature: Alternative linkgraph colour schemes (#9866) +Feature: Allow Shift+Insert as paste in edit box (#9836) +Feature: Setting to make the local town authority rubber-stamp all actions (#9833) +Feature: Add/extend console commands to enable screenshot automation (#9771) +Feature: [Linkgraph] Show a tooltip with statistics when hovering a link (#9760) +Feature: Build objects by area (#9709) +Feature: Add setting to hide news about competitors vehicle crash (#9653) +Feature: Ctrl-click to remove fully autoreplaced vehicles from list (#9639) +Feature: Wide rivers on map generation (#9628) +Add: [Script] ScriptCargo::GetWeight to get cargo weights (#9930) +Add: Command line option to skip NewGRF scanning (#9879) +Add: Show video driver name in Game Options window (#9872) +Add: [NewGRF] Map seed as global variable (#9834) +Add: [Script] IndustryType::ResolveNewGRFID to resolve industry id from grf_local_id and grfid (#9798) +Add: [Script] ObjectType::ResolveNewGRFID to resolve object id from grfid and grf_local_id (#9795) +Update: To all the friends we have lost and those we have gained (#10000) +Change: Use the Simulation subcategory to openttd.desktop (#10015) +Change: Constantly update destination of 'any depot' orders (#9959) +Change: Use an indent, not a dash, to list train capacity (#9887) +Change: [NewGRF] Increase vehicle sprite stack from 4 layers to 8 (#9863) +Change: Don't pay Property Maintenance on stations when Infrastructure Maintenance is disabled (#9828) +Change: Improved layout of the finance window (#9827) +Change: [Admin] Bump admin port protocol due to command changes (#9754) +Change: Suppress vehicle age warnings for stopped vehicles (#9718) +Change: Make pf.yapf.rail_firstred_twoway_eol on by default (#9544) +Change: Deliver cargo to the closest industry first (#9536) +Fix: Lots of fixes to how windows handle resizing (#10040, #10042, #10046, #10051, #10056, #10068, #10070, #10098) +Fix: Console commands list_ai output was truncated with a suitably large number of AIs (#10075) +Fix #9876: MacBook Touch Bar crash / render issues w/ 32bpp graphics (#10060) +Fix: Reduce framerate overhead in Train::Tick (#10055) +Fix: Only open scenario editor date query once (#10050) +Fix #10048: Don't relocate company HQ on the same exact location (#10049) +Fix #10038: Missing upper bounds check when loading custom playlists (#10039) +Fix: Wrong string used to determine size of zoomed out station sign (#10036) +Fix: Disable "turn around" button for other companies' road vehicles (#10033) +Fix: Online Players list mouse hover behaviour (#10031) +Fix: [NewGRF] Weirdness of new stations (#10017) +Fix #9854: DrawStringMultiLine() could draw beyond its bounding box (#10014) +Fix: Incorrect player name in online players window (#10013) +Fix #8099: News window zoom level fixes (#10005) +Fix: [NewGRF] Upper 16 random bits should be the same for all station tiles in callback 140 (#9992) +Fix #9989: £0 Net Profit is neither negative nor positive (#9991) +Fix #9804: Only apply sprite_zoom_min setting when sprites available (#9988) +Fix #9972: Add missing fill/resize flags on Framerate window widgets (#9982) +Fix #9935: Use more selectivity when building SSE specific code (#9980) +Fix #9940: Print debuglevel parse errors to console when changed from console (#9979) +Fix #9977: Clearing the console with a large number of lines could cause a crash (#9978) +Fix #9974: Console command getsysdate did not work due to off-by-one error (#9975) +Fix: [NewGRF] Default value of RailVehicleInfo::railveh_type was inconsistent with other default properties (#9967) +Fix #8584: Vehicles with shared orders getting invalid or unexpected start dates (#9955) +Fix #9951: [NewGRF] Scenario editor random industries button broke NewGRF persistent storage (#9952) +Fix: Validation of various internal command parameters that could have allowed a rogue client to crash servers (#9942, #9943, #9944, #9945, #9946, #9947, #9948, #9950) +Fix #9937: Station industries_near incorrect after removing part moved sign (#9938) +Fix: [Script] ScriptRoad::HasRoadType really check for RoadType (#9934) +Fix #9363: Rebuild client list on reinit event (#9929) +Fix #9925: Industry tile layout validation for layouts of only one tile (#9926) +Fix #9918: Reset industy last production year on scenario start (#9920) +Fix #9914: Prevent more useless pathfinder run for blocked vehicles (#9917) +Fix: List a max of four share owners instead of three (#9905) +Fix: [NewGRF] Industry layouts with zero regular tiles should be invalid (#9902) +Fix #9869: Remove docking tile when doing a clear square (#9898) +Fix: New player companies use favorite manager face, if saved (#9895) +Fix: Towns don't build parallel, redundant bridges (#9891) +Fix #9712: Cap town bridge length at original 11-tile limit (#9890) +Fix #9883: Show cost/income float over end tile of rail or road construction (#9889) +Fix #9870: Don't update infrastructure totals when overbuilding object on canal (#9888) +Fix #9877: GS could trigger 'Cost: £0' cost message (#9878) +Fix 44f2ef1: [strgen] Allow gender for {CARGO_SHORT} (#9873) +Fix #9867: Industry::stations_near not filled at industry creation (#9868) +Fix #9853: Incorrect merge of guiflags and flags for osk_activation (#9855) +Fix #6544: Don't join AI company when loading network game in singleplayer (#9794) +Fix: Company values do not properly account for shares (#9770) +Fix #9546: Crash when no industries are present in game (#9726) +Fix #9708: [Linkgraph] Don't assume vehicles have a non-zero max speed (#9693) +Fix #9665: [Linkgraph] Fix travel times of non-direct journeys (#9693) +Fix #8797: Use logical rail length when placing signals (#9652) +Cleanup: [NewGRF] Remove unused flag sprites (#10052) + + +12.2 (2022-04-02) +------------------------------------------------------------------------ +Feature: Remember the last-used signal between games (#9792) +Change: [MacOS] Allow touchbar usage on all supported OS versions (#9776) +Change: Add a timestamp in name of crash files (#9761) +Fix #9736: Duplicate multiplayer window opens upon canceling password entry (#9842) +Fix: Removing long roads doesn't prioritise refusal of local authority over other errors (#9831) +Fix #9020: Glitchy station coverage highlight when changing selection (#9825) +Fix: Correct some Romanian town names (#9819) +Fix: Original music playback rate was slightly too fast (#9814) +Fix #9811: Use the NewGRF-defined vehicle center when dragging ships and aircraft (#9812) +Fix: Do not let shares in the company taking over another company disappear (#9808) +Fix #9802: Crash when using lots of NewGRF waypoint types (#9803) +Fix #9766: Don't write uninitialised data in config file (#9767) +Fix #9743: [MacOS] Don't try to render touchbar sprites with invalid zoom level (#9776) +Fix #9774: Building roadstop in estimation mode updates station acceptance (#9775) +Fix: If vehicles only refit to cargo-slots >= 32, the default cargo was wrong (#9744) +Fix #9735: Possible desync when replacing a depot on same tile (#9738) +Fix #9730: [Network] Connections can use an invalid socket due to a race condition (#9731) +Fix: Don't show sign edit window for GS-owned signs (#9716) +Fix #9702: Display order window for vehicle group on ctrl-click only when using shared orders (#9704) +Fix #9680: Crash when loading really old savegames with aircraft in certain places (#9699) +Fix: Update last servicing dates when using the date cheat (#9694) +Fix: Error message shows about missing glyphs while suitable fallback font is found (#9692) + + +12.1 (2021-11-08) +------------------------------------------------------------------------ +Feature: Button to toggle showing advanced signal types (#9617) +Change: Don't show screenshot GUI in screenshots (#9674) +Change: Suppress panning in intro game, while user is interacting with the GUI (#9645) +Change: Draw rotor in cursor when dragging helicopters in depots (#9612) +Fix: Invalid memory access when loading a currency NewGRF (#9675) +Fix #9579: Object and HQ construction is Construction cost, not Property Maintenance (#9673) +Fix #9669: Ships exiting a blocked depot/lock could exit in the wrong direction (#9672) +Fix: Every 16th client never reconnects after server restart (#9666) +Fix #9643: Screenshots were always written as BMP files (#9644) +Fix #9630: Intro game could zoom in/out more than allowed by settings (#9633) +Fix #9626: Incorrect loading of script saved data (#9629) +Fix: Emergency crash save had the wrong NewGRF list saved in it (#9627) +Fix #9595: Always use plural forms of cargo for subsidy strings (#9619) +Fix #9614: Refresh rate dropdown was still active when vsync was enabled (#9618) +Fix: Don't use 'server address' string in server list when displaying an invite code (#9615) + + +12.0 (2021-10-17) +------------------------------------------------------------------------ +Add: [Network] Keep the refresh button in lowered state while refreshing (#9600) +Add: Console command to list search directories for various things (#9583) +Fix: Try all possible reverse directions when a ship reaches a dead end (#9610) +Fix: Incorrect Romanian own name (#9598) +Fix #9591: Update station docking tiles upon placing a water object on a docking tile (#9594) +Fix #9548: [Squirrel] Crash during engine cleanup after reaching memory limit on realloc (#9592) +Fix #9588: [Squirrel] Reaching memory limit during script registration could prevent further script detections (#9589) +Fix: Make ships more likely to find their destination at the cost of slightly worse paths (#9576) +Change: Reverse ship when leaving docks if a better path exists (#9610) +Change: Allow all tiles around docks to be docking tiles (#9578) + + +12.0-RC1 (2021-09-25) +------------------------------------------------------------------------ +Feature: Display icon/text whether vehicle is lost in vehicle (list) window (#9543) +Feature: [MacOS] Add selected toolbar buttons to MacBook Pro Touch Bar (#9511) +Feature: Button to open order window from vehicle shared orders window (#9325) +Feature: Ctrl-Clicking shared order vehicle list opens order window (#9325) +Feature: Multiple rotating views on title screen (#8980) +Feature: Hide block signals in GUI by default (#8688) +Add: [Script] Allow GameScripts to build neutral objects (#9568) +Add: [Network] Allow sending chat messages via admin port (#9563) +Add: [AI/GS] Missing water related functions and objects (#8390) +Fix: Industry funding window did not update when changing funding method (#9572) +Fix #9562: [NewGRF] Handle case of invalid Action2 with zero results (#9564) +Fix: Incorrect error messages when placing water in scenario editor (#9560) +Fix #9484: Update locale currencies settings config map (#9559) +Fix: Prevent train reversing when entirely inside a train depot (#9557) +Fix: [Network] Add back 'Spectate' option to company toolbar menu (#9556) +Fix #9463: [Win32] Work around XAudio2 crashes (#9549) +Fix #8603: Don't give focus to text filter when opening Object GUI (#9547) +Fix #9241: Grove and forest tree brushes did not also create rainforest terrain (#9542) +Fix: [Network] Several crashes in our network code (#9534, #9456) +Fix #9527: Crash when trying to place multi-tile objects at map edge (#9529) +Fix: [Network] SendCmdNames only sent one name per packet (#9528) +Fix #9407: Desync when founding a town nearby a station (#9526) +Fix #9521: Don't load at just removed docks that were part of a multi-dock station (#9524) +Fix: Ships always tried to avoid docking tiles when pathfinding (even if nothing was on them) (#9522) +Fix: [Network] Convert server_advertise to server_game_type in config file (#9515) +Fix #9490: [Network] A full server couldn't be queried (#9508) +Fix: [Network] Don't show GameScript " (v0)" for old servers (#9507) +Fix: [Network] Show query errors in the server listing instead of error popup (#9506) +Fix: [Network] Crash when last-joined server was no longer available (#9503) +Fix #9501: [Network] Crash when more than one game-info query was pending (#9502) +Fix: Wrong error message when building canals over ship depots / locks (#9410) +Fix: Reduce cost of building canals over objects on sea (#9410) +Change: [Linkgraph] Delete links only served by vehicles stopped in depot (#9499) + + 12.0-beta2 (2021-08-19) ------------------------------------------------------------------------ Feature: [Linkgraph] Prioritize faster routes for passengers, mail and express cargo (#9457) diff --git a/cmake/CheckAtomic.cmake b/cmake/CheckAtomic.cmake new file mode 100644 index 0000000000000..52d93f4f5b100 --- /dev/null +++ b/cmake/CheckAtomic.cmake @@ -0,0 +1,87 @@ +# atomic builtins are required for threading support. + +INCLUDE(CheckCXXSourceCompiles) +INCLUDE(CheckLibraryExists) + +# Sometimes linking against libatomic is required for atomic ops, if +# the platform doesn't support lock-free atomics. + +function(check_working_cxx_atomics varname) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++17") + check_cxx_source_compiles(" +#include +std::atomic x; +std::atomic y; +std::atomic z; +int main() { + ++z; + ++y; + return ++x; +} +" ${varname}) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) +endfunction(check_working_cxx_atomics) + +function(check_working_cxx_atomics64 varname) + set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + set(CMAKE_REQUIRED_FLAGS "-std=c++17 ${CMAKE_REQUIRED_FLAGS}") + check_cxx_source_compiles(" +#include +#include +std::atomic x (0); +int main() { + uint64_t i = x.load(std::memory_order_relaxed); + (void)i; + return 0; +} +" ${varname}) + set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) +endfunction(check_working_cxx_atomics64) + + +# Check for (non-64-bit) atomic operations. +if(MSVC) + set(HAVE_CXX_ATOMICS_WITHOUT_LIB True) +else() + # First check if atomics work without the library. + check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB) + # If not, check if the library exists, and atomics work with it. + if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB) + check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC) + if(HAVE_LIBATOMIC) + list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") + check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB) + if (NOT HAVE_CXX_ATOMICS_WITH_LIB) + message(FATAL_ERROR "Host compiler must support std::atomic!") + endif() + else() + message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.") + endif() + endif() +endif() + +# Check for 64 bit atomic operations. +if(MSVC) + set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True) +else() + # First check if atomics work without the library. + check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB) + # If not, check if the library exists, and atomics work with it. + if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB) + check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64) + if(HAVE_CXX_LIBATOMICS64) + list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") + check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB) + if (NOT HAVE_CXX_ATOMICS64_WITH_LIB) + message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!") + endif() + else() + message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.") + endif() + endif() +endif() + +if(HAVE_CXX_ATOMICS_WITH_LIB OR HAVE_CXX_ATOMICS64_WITH_LIB) + target_link_libraries(openttd atomic) +endif() diff --git a/cmake/CompileFlags.cmake b/cmake/CompileFlags.cmake index ad4a46aca73c3..27d9a48efac75 100644 --- a/cmake/CompileFlags.cmake +++ b/cmake/CompileFlags.cmake @@ -44,8 +44,8 @@ macro(compile_flags) "$<$>:-fstack-protector>" # Prevent undefined references when _FORTIFY_SOURCE > 0 ) if(CMAKE_SIZEOF_VOID_P EQUAL 8) - add_link_options( - "$<$:-Wl,--disable-dynamicbase,--disable-high-entropy-va,--default-image-base-low>" # ASLR somehow breaks linking for x64 Debug builds + add_compile_options( + "$<$:-Wa,-mbig-obj>" # Switch to pe-bigobj-x86-64 as x64 Debug builds push pe-x86-64 to the limits (linking errors with ASLR, ...) ) endif() endif() @@ -56,6 +56,11 @@ macro(compile_flags) if(MSVC) add_compile_options(/W3) + if(MSVC_VERSION GREATER 1929 AND CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + # Starting with version 19.30, there is an optimisation bug, see #9966 for details + # This flag disables the broken optimisation to work around the bug + add_compile_options(/d2ssa-rse-) + endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") add_compile_options( -W diff --git a/cmake/InstallAndPackage.cmake b/cmake/InstallAndPackage.cmake index d98f32bbabf83..042d5ad313d47 100644 --- a/cmake/InstallAndPackage.cmake +++ b/cmake/InstallAndPackage.cmake @@ -132,6 +132,8 @@ set(CPACK_STRIP_FILES YES) set(CPACK_OUTPUT_FILE_PREFIX "bundles") if(APPLE) + # Stripping would produce unreadable stacktraces. + set(CPACK_STRIP_FILES NO) set(CPACK_GENERATOR "Bundle") include(PackageBundle) @@ -181,6 +183,10 @@ elseif(UNIX) set(CPACK_GENERATOR "DEB") include(PackageDeb) + elseif(LSB_RELEASE_ID STREQUAL "Fedora") + set(PLATFORM "fedora") + set(CPACK_GENERATOR "RPM") + include(PackageRPM) else() set(UNSUPPORTED_PLATFORM_NAME "LSB-based Linux distribution '${LSB_RELEASE_ID}'") endif() diff --git a/cmake/MSVCFilters.cmake b/cmake/MSVCFilters.cmake index db53fc2258146..b334f6a91a1c2 100644 --- a/cmake/MSVCFilters.cmake +++ b/cmake/MSVCFilters.cmake @@ -3,6 +3,7 @@ source_group("AI Core" REGULAR_EXPRESSION "src/ai/") source_group("Blitters" REGULAR_EXPRESSION "src/blitter/") source_group("Core Source Code" REGULAR_EXPRESSION "src/core/") +source_group("Font Cache" REGULAR_EXPRESSION "src/fontcache/") source_group("Game Core" REGULAR_EXPRESSION "src/game/") source_group("MD5" REGULAR_EXPRESSION "src/3rdparty/md5/") source_group("Misc" REGULAR_EXPRESSION "src/misc/") diff --git a/cmake/scripts/GenerateWidget.cmake b/cmake/scripts/GenerateWidget.cmake index f46a67e690b4c..b6748422f5d95 100644 --- a/cmake/scripts/GenerateWidget.cmake +++ b/cmake/scripts/GenerateWidget.cmake @@ -13,6 +13,7 @@ cmake_minimum_required(VERSION 3.5) # The parameter "enumname" specifies the enumeration to extract. This can also be a regular expression. # The parameter "filename" specifies the relative path to the file, where the enumeration is extracted from. This can also be a glob expression. # +# All files where enumerations are extracted from are automatically added via #include # if(NOT GENERATE_SOURCE_FILE) @@ -41,6 +42,7 @@ foreach(ENUM IN LISTS ENUM_LINES) string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" FILE ${FILE}) string(APPEND ${PLACE_HOLDER} "\n${ADD_INDENT}/* automatically generated from ${FILE} */") + list(APPEND INCLUDES "#include \"${FILE}\"") foreach(LINE IN LISTS SOURCE_LINES) string(REPLACE "${RM_INDENT}" "" LINE "${LINE}") @@ -116,4 +118,7 @@ foreach(ENUM IN LISTS ENUM_LINES) endforeach() endforeach() + list(REMOVE_DUPLICATES INCLUDES) + string(REPLACE ";" "\n" INCLUDES "${INCLUDES}") + configure_file(${GENERATE_SOURCE_FILE} ${GENERATE_BINARY_FILE}) diff --git a/cmake/scripts/SquirrelExport.cmake b/cmake/scripts/SquirrelExport.cmake index d0c2283550b18..d13bd8d4d0850 100644 --- a/cmake/scripts/SquirrelExport.cmake +++ b/cmake/scripts/SquirrelExport.cmake @@ -28,25 +28,27 @@ endmacro() macro(dump_class_templates NAME) string(REGEX REPLACE "^Script" "" REALNAME ${NAME}) - string(APPEND SQUIRREL_EXPORT "\n template <> inline ${NAME} *GetParam(ForceType<${NAME} *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return (${NAME} *)instance; }") - string(APPEND SQUIRREL_EXPORT "\n template <> inline ${NAME} &GetParam(ForceType<${NAME} &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return *(${NAME} *)instance; }") - string(APPEND SQUIRREL_EXPORT "\n template <> inline const ${NAME} *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return (${NAME} *)instance; }") - string(APPEND SQUIRREL_EXPORT "\n template <> inline const ${NAME} &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return *(${NAME} *)instance; }") + string(APPEND SQUIRREL_EXPORT "\n template <> struct Param<${NAME} *> { static inline ${NAME} *Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return (${NAME} *)instance; } };") + string(APPEND SQUIRREL_EXPORT "\n template <> struct Param<${NAME} &> { static inline ${NAME} &Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return *(${NAME} *)instance; } };") + string(APPEND SQUIRREL_EXPORT "\n template <> struct Param { static inline const ${NAME} *Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return (${NAME} *)instance; } };") + string(APPEND SQUIRREL_EXPORT "\n template <> struct Param { static inline const ${NAME} &Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, nullptr); return *(${NAME} *)instance; } };") if("${NAME}" STREQUAL "ScriptEvent") - string(APPEND SQUIRREL_EXPORT "\n template <> inline int Return<${NAME} *>(HSQUIRRELVM vm, ${NAME} *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, \"${REALNAME}\", res, nullptr, DefSQDestructorCallback<${NAME}>, true); return 1; }") + string(APPEND SQUIRREL_EXPORT "\n template <> struct Return<${NAME} *> { static inline int Set(HSQUIRRELVM vm, ${NAME} *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, \"${REALNAME}\", res, nullptr, DefSQDestructorCallback<${NAME}>, true); return 1; } };") elseif("${NAME}" STREQUAL "ScriptText") string(APPEND SQUIRREL_EXPORT "\n") - string(APPEND SQUIRREL_EXPORT "\n template <> inline Text *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) {") - string(APPEND SQUIRREL_EXPORT "\n if (sq_gettype(vm, index) == OT_INSTANCE) {") - string(APPEND SQUIRREL_EXPORT "\n return GetParam(ForceType(), vm, index, ptr);") + string(APPEND SQUIRREL_EXPORT "\n template <> struct Param {") + string(APPEND SQUIRREL_EXPORT "\n static inline Text *Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) {") + string(APPEND SQUIRREL_EXPORT "\n if (sq_gettype(vm, index) == OT_INSTANCE) {") + string(APPEND SQUIRREL_EXPORT "\n return Param::Get(vm, index, ptr);") + string(APPEND SQUIRREL_EXPORT "\n }") + string(APPEND SQUIRREL_EXPORT "\n if (sq_gettype(vm, index) == OT_STRING) {") + string(APPEND SQUIRREL_EXPORT "\n return new RawText(Param::Get(vm, index, ptr));") + string(APPEND SQUIRREL_EXPORT "\n }") + string(APPEND SQUIRREL_EXPORT "\n return nullptr;") string(APPEND SQUIRREL_EXPORT "\n }") - string(APPEND SQUIRREL_EXPORT "\n if (sq_gettype(vm, index) == OT_STRING) {") - string(APPEND SQUIRREL_EXPORT "\n return new RawText(GetParam(ForceType(), vm, index, ptr));") - string(APPEND SQUIRREL_EXPORT "\n }") - string(APPEND SQUIRREL_EXPORT "\n return nullptr;") - string(APPEND SQUIRREL_EXPORT "\n }") + string(APPEND SQUIRREL_EXPORT "\n };") else() - string(APPEND SQUIRREL_EXPORT "\n template <> inline int Return<${NAME} *>(HSQUIRRELVM vm, ${NAME} *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, \"${REALNAME}\", res, nullptr, DefSQDestructorCallback<${NAME}>, true); return 1; }") + string(APPEND SQUIRREL_EXPORT "\n template <> struct Return<${NAME} *> { static inline int Set(HSQUIRRELVM vm, ${NAME} *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, \"${REALNAME}\", res, nullptr, DefSQDestructorCallback<${NAME}>, true); return 1; } };") endif() endmacro() @@ -297,8 +299,8 @@ foreach(LINE IN LISTS SOURCE_LINES) endif() string(APPEND SQUIRREL_EXPORT "\n /* Allow enums to be used as Squirrel parameters */") foreach(ENUM IN LISTS ENUMS) - string(APPEND SQUIRREL_EXPORT "\n template <> inline ${ENUM} GetParam(ForceType<${ENUM}>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (${ENUM})tmp; }") - string(APPEND SQUIRREL_EXPORT "\n template <> inline int Return<${ENUM}>(HSQUIRRELVM vm, ${ENUM} res) { sq_pushinteger(vm, (int32)res); return 1; }") + string(APPEND SQUIRREL_EXPORT "\n template <> struct Param<${ENUM}> { static inline ${ENUM} Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (${ENUM})tmp; } };") + string(APPEND SQUIRREL_EXPORT "\n template <> struct Return<${ENUM}> { static inline int Set(HSQUIRRELVM vm, ${ENUM} res) { sq_pushinteger(vm, res); return 1; } };") endforeach() endif() @@ -342,7 +344,7 @@ foreach(LINE IN LISTS SOURCE_LINES) else() string(APPEND SQUIRREL_EXPORT "\n SQ${API_CLS}.PreRegister(engine, \"${API_SUPER_CLS}\");") endif() - if(NOT "${SUPER_CLS}" STREQUAL "ScriptEvent") + if(NOT "${SUPER_CLS}" MATCHES "^ScriptEvent") if("${CLS_PARAM_2}" STREQUAL "v") string(APPEND SQUIRREL_EXPORT "\n SQ${API_CLS}.AddSQAdvancedConstructor(engine);") else() @@ -625,7 +627,7 @@ foreach(LINE IN LISTS SOURCE_LINES) string(APPEND TYPES "p") elseif("${PARAM}" MATCHES "^Array") string(APPEND TYPES "a") - elseif("${PARAM}" MATCHES "^struct Array") + elseif("${PARAM}" MATCHES "^const Array") string(APPEND TYPES "a") elseif("${PARAM}" MATCHES "^Text") string(APPEND TYPES ".") diff --git a/docs/landscape.html b/docs/landscape.html index d30ffee162a28..3c0f76ccb8ae6 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -816,8 +816,6 @@

Landscape

  • m2 bits 5..4: ground density
  • -
  • m2 bits 3..0: update counter, incremented on every periodic processing.
    - on wraparound the growth status is updated (or, if it's 3, a random action is taken)
  • m3 bits 7..0: type of trees: @@ -1007,6 +1005,7 @@

    Landscape

  • m7: animation frame (railway stations/waypoints, airports)
  • m8 bits 11..6: Tramtype
  • m8 bits 5..0: track type for railway stations/waypoints
  • +
  • m8 bits 5..0: custom road stop id; 0 means standard graphics
  • diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html index fc0c6e0cfc86b..e7e55aabf318e 100644 --- a/docs/landscape_grid.html +++ b/docs/landscape_grid.html @@ -203,7 +203,7 @@

    Landscape

    - + diff --git a/media/baseset/openttd.grf b/media/baseset/openttd.grf index 837e4b12d2553..9e08fb17c3a80 100644 Binary files a/media/baseset/openttd.grf and b/media/baseset/openttd.grf differ diff --git a/media/baseset/openttd/flags.nfo b/media/baseset/openttd/flags.nfo deleted file mode 100644 index 3c125ec79a571..0000000000000 --- a/media/baseset/openttd/flags.nfo +++ /dev/null @@ -1,43 +0,0 @@ -// 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 . -// - -1 * 0 0C "Flag graphics" - -1 * 3 05 14 24 - -1 sprites/flags.png 8bpp 34 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 50 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 66 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 82 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 98 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 114 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 130 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 146 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 162 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 178 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 194 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 210 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 226 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 242 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 258 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 274 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 290 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 306 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 322 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 338 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 354 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 370 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 386 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 402 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 418 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 434 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 450 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 466 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 482 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 498 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 514 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 530 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 546 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 562 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 578 8 11 8 0 0 normal - -1 sprites/flags.png 8bpp 594 8 11 8 0 0 normal diff --git a/media/baseset/openttd/flags.png b/media/baseset/openttd/flags.png deleted file mode 100644 index 2e0401ffce5ca..0000000000000 Binary files a/media/baseset/openttd/flags.png and /dev/null differ diff --git a/media/baseset/openttd/oneway.nfo b/media/baseset/openttd/oneway.nfo index 46f3b8f947be7..56d2e2809ae77 100644 --- a/media/baseset/openttd/oneway.nfo +++ b/media/baseset/openttd/oneway.nfo @@ -4,10 +4,24 @@ // 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 . // -1 * 0 0C "One way road graphics" - -1 * 3 05 09 06 - -1 sprites/oneway.png 8bpp 34 8 24 16 -12 -8 normal - -1 sprites/oneway.png 8bpp 66 8 24 16 -12 -8 normal - -1 sprites/oneway.png 8bpp 98 8 24 16 -12 -8 normal - -1 sprites/oneway.png 8bpp 130 8 24 16 -12 -8 normal - -1 sprites/oneway.png 8bpp 162 8 24 16 -12 -8 normal - -1 sprites/oneway.png 8bpp 194 8 24 16 -12 -8 normal + -1 * 3 05 09 12 + -1 sprites/oneway.png 8bpp 34 8 24 16 -10 -9 normal + -1 sprites/oneway.png 8bpp 66 8 24 16 -13 -7 normal + -1 sprites/oneway.png 8bpp 98 8 24 16 -12 -8 normal + -1 sprites/oneway.png 8bpp 130 8 24 16 -15 -10 normal + -1 sprites/oneway.png 8bpp 162 8 24 16 -12 -9 normal + -1 sprites/oneway.png 8bpp 194 8 24 16 -11 -8 normal + + -1 sprites/oneway.png 8bpp 34 40 24 16 -13 -10 normal + -1 sprites/oneway.png 8bpp 66 40 24 16 -12 -8 normal + -1 sprites/oneway.png 8bpp 98 40 24 16 -12 -9 normal + -1 sprites/oneway.png 8bpp 130 40 24 16 -11 -8 normal + -1 sprites/oneway.png 8bpp 162 40 24 16 -9 -10 normal + -1 sprites/oneway.png 8bpp 194 40 24 16 -10 -9 normal + + -1 sprites/oneway.png 8bpp 34 72 24 16 -8 -11 normal + -1 sprites/oneway.png 8bpp 66 72 24 16 -11 -5 normal + -1 sprites/oneway.png 8bpp 98 72 24 16 -12 -8 normal + -1 sprites/oneway.png 8bpp 130 72 24 16 -12 -5 normal + -1 sprites/oneway.png 8bpp 162 72 24 16 -14 -10 normal + -1 sprites/oneway.png 8bpp 194 72 24 16 -12 -8 normal diff --git a/media/baseset/openttd/oneway.png b/media/baseset/openttd/oneway.png index 15542af8563cd..843747677fc02 100644 Binary files a/media/baseset/openttd/oneway.png and b/media/baseset/openttd/oneway.png differ diff --git a/media/baseset/openttd/openttd.nfo b/media/baseset/openttd/openttd.nfo index b0d80824e8e1a..c1ed751c55780 100644 --- a/media/baseset/openttd/openttd.nfo +++ b/media/baseset/openttd/openttd.nfo @@ -92,7 +92,6 @@ #include "roadstops.nfo" #include "aqueduct.nfo" #include "autorail.nfo" -#include "flags.nfo" #include "openttdgui.nfo" #include "airport_preview.nfo" #include "chars.nfo" diff --git a/media/baseset/orig_extra.grf b/media/baseset/orig_extra.grf index 728a8b2555bb3..881c4631cec0a 100644 Binary files a/media/baseset/orig_extra.grf and b/media/baseset/orig_extra.grf differ diff --git a/media/baseset/orig_extra/fix_gui_icons.nfo b/media/baseset/orig_extra/fix_gui_icons.nfo new file mode 100644 index 0000000000000..2fdb8880bd5da --- /dev/null +++ b/media/baseset/orig_extra/fix_gui_icons.nfo @@ -0,0 +1,12 @@ +// 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 . +// + -1 * 0 0C "Fix alignment of button icons." + +// Fix alignment of button icons. + -1 * 11 0A 03 01 DC 02 01 E2 02 01 E6 02 + -1 sprites/fix_gui_icons.png 8bpp 8 13 20 20 0 0 normal nocrop + -1 sprites/fix_gui_icons.png 8bpp 40 13 20 20 0 0 normal nocrop + -1 sprites/fix_gui_icons.png 8bpp 72 13 20 20 0 0 normal nocrop diff --git a/media/baseset/orig_extra/fix_gui_icons.png b/media/baseset/orig_extra/fix_gui_icons.png new file mode 100644 index 0000000000000..0630179616f43 Binary files /dev/null and b/media/baseset/orig_extra/fix_gui_icons.png differ diff --git a/media/baseset/orig_extra/orig_extra.nfo b/media/baseset/orig_extra/orig_extra.nfo index 903d96a572b28..e6ecca8a008c9 100644 --- a/media/baseset/orig_extra/orig_extra.nfo +++ b/media/baseset/orig_extra/orig_extra.nfo @@ -83,3 +83,4 @@ #include "rivers/arctic.nfo" #include "rivers/tropic.nfo" #include "rivers/toyland.nfo" +#include "fix_gui_icons.nfo" diff --git a/media/openttd.desktop b/media/openttd.desktop index e0aef004cdbd0..6882a0d5c7667 100644 --- a/media/openttd.desktop +++ b/media/openttd.desktop @@ -6,6 +6,6 @@ Name=OpenTTD Icon=${BINARY_NAME} Exec=${BINARY_NAME} Terminal=false -Categories=Game; +Categories=Game;Simulation; Keywords=game;simulation;transport;tycoon;deluxe;economics;multiplayer;money;train;ship;bus;truck;aircraft;cargo; @Comment_STR_DESKTOP_SHORTCUT_COMMENT@ diff --git a/os/emscripten/Dockerfile b/os/emscripten/Dockerfile index 5d54b54114898..ae3579ec0a1b5 100644 --- a/os/emscripten/Dockerfile +++ b/os/emscripten/Dockerfile @@ -1,4 +1,4 @@ -FROM emscripten/emsdk:2.0.34 +FROM emscripten/emsdk:3.1.28 COPY emsdk-liblzma.patch / RUN cd /emsdk/upstream/emscripten && patch -p1 < /emsdk-liblzma.patch diff --git a/os/emscripten/README.md b/os/emscripten/README.md index c78dc6727b3ff..cf8e3ed6920f4 100644 --- a/os/emscripten/README.md +++ b/os/emscripten/README.md @@ -1,40 +1,38 @@ ## How to build with Emscripten -Building with Emscripten works with emsdk 2.0.31 and above. +Please use docker with the supplied `Dockerfile` to build for emscripten. +It takes care of a few things: +- Use a version of emscripten we know works +- Patch in LibLZMA support (as this is not supported by upstream) -Currently there is no LibLZMA support upstream; for this we suggest to apply -the provided patch in this folder to your emsdk installation. - -For convenience, a Dockerfile is supplied that does this patches for you -against upstream emsdk docker. Best way to use it: - -Build the docker image: +First, build the docker image by navigating in the folder this `README.md` is in, and executing: ``` docker build -t emsdk-lzma . ``` -Build the host tools first: +Next, navigate back to the root folder of this project. + +Now we build the host tools first: ``` mkdir build-host docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build-host emsdk-lzma cmake .. -DOPTION_TOOLS_ONLY=ON - docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build-host emsdk-lzma make -j5 tools + docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build-host emsdk-lzma make -j$(nproc) tools ``` -Next, build the game with emscripten: - +Finally, we build the actual game: ``` mkdir build docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build emsdk-lzma emcmake cmake .. -DHOST_BINARY_DIR=../build-host -DCMAKE_BUILD_TYPE=Release -DOPTION_USE_ASSERTS=OFF - docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build emsdk-lzma emmake make -j5 + docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build emsdk-lzma emmake make -j$(nproc) ``` -And now you have in your build folder files like "openttd.html". +In the `build` folder you will now see `openttd.html`. -To run it locally, you would have to start a local webserver, like: +To run it locally, you would have to start a local webserver; something like: ``` cd build python3 -m http.server ```` -Now you can play the game via http://127.0.0.1:8000/openttd.html . +You can now play the game via http://127.0.0.1:8000/openttd.html . diff --git a/os/emscripten/emsdk-liblzma.patch b/os/emscripten/emsdk-liblzma.patch index aa75fa5a49f8f..fbb24e7ca94ac 100644 --- a/os/emscripten/emsdk-liblzma.patch +++ b/os/emscripten/emsdk-liblzma.patch @@ -13,7 +13,7 @@ of emsdk. diff --git a/tools/settings.py b/tools/settings.py --- a/tools/settings.py +++ b/tools/settings.py -@@ -38,6 +38,7 @@ +@@ -40,6 +40,7 @@ PORTS_SETTINGS = { 'USE_SDL_NET', 'USE_SDL_GFX', 'USE_LIBJPEG', @@ -24,24 +24,23 @@ diff --git a/tools/settings.py b/tools/settings.py diff --git a/src/settings.js b/src/settings.js --- a/src/settings.js +++ b/src/settings.js -@@ -1382,8 +1382,12 @@ var USE_BZIP2 = 0; - // 1 = use libjpeg from emscripten-ports - // [link] - var USE_LIBJPEG = 0; +@@ -1450,6 +1450,10 @@ var USE_GIFLIB = false; + // [compile+link] + var USE_LIBJPEG = false; +// 1 = use liblzma from emscripten-ports -+// [link] -+var USE_LIBLZMA = 0; ++// [compile+link] ++var USE_LIBLZMA = false; + // 1 = use libpng from emscripten-ports - // [link] - var USE_LIBPNG = 0; + // [compile+link] + var USE_LIBPNG = false; diff --git a/tools/ports/liblzma.py b/tools/ports/liblzma.py new file mode 100644 --- /dev/null +++ b/tools/ports/liblzma.py -@@ -0,0 +1,160 @@ +@@ -0,0 +1,151 @@ +# Copyright 2020 The Emscripten Authors. All rights reserved. +# Emscripten is available under two separate licenses, the MIT license and the +# University of Illinois/NCSA Open Source License. Both these licenses can be @@ -52,8 +51,8 @@ new file mode 100644 +import logging +from pathlib import Path + -+VERSION = '5.2.5' -+HASH = '7443674247deda2935220fbc4dfc7665e5bb5a260be8ad858c8bd7d7b9f0f868f04ea45e62eb17c0a5e6a2de7c7500ad2d201e2d668c48ca29bd9eea5a73a3ce' ++VERSION = '5.4.0' ++HASH = '29b2cd25bb5b234b329ffe9547692d2c29be393db9d8d4ce70a66dfdaebd54433e79a89d80c57e58cd4559c3c68b9845507d5fedf3eec1c528a81e3d9ddbd811' + + +def needed(settings): @@ -61,40 +60,31 @@ new file mode 100644 + + +def get(ports, settings, shared): -+ ports.fetch_project('liblzma', 'https://tukaani.org/xz/xz-' + VERSION + '.tar.gz', 'xz-' + VERSION, sha512hash=HASH) ++ ports.fetch_project('liblzma', f'https://tukaani.org/xz/xz-{VERSION}.tar.gz', sha512hash=HASH) + + def create(final): + logging.info('building port: liblzma') + + ports.clear_project_build('liblzma') + -+ source_path = os.path.join(ports.get_dir(), 'liblzma', 'xz-' + VERSION) -+ dest_path = os.path.join(ports.get_build_dir(), 'liblzma') -+ -+ shared.try_delete(dest_path) -+ os.makedirs(dest_path) -+ shutil.rmtree(dest_path, ignore_errors=True) -+ shutil.copytree(source_path, dest_path) ++ source_path = os.path.join(ports.get_dir(), 'liblzma', f'xz-{VERSION}', 'src', 'liblzma') ++ ports.write_file(os.path.join(source_path, 'config.h'), config_h) ++ ports.install_headers(os.path.join(source_path, 'api'), pattern='lzma.h') ++ ports.install_headers(os.path.join(source_path, 'api', 'lzma'), pattern='*.h', target='lzma') + + build_flags = ['-DHAVE_CONFIG_H', '-DTUKLIB_SYMBOL_PREFIX=lzma_', '-fvisibility=hidden'] -+ exclude_dirs = ['xzdec', 'xz', 'lzmainfo'] -+ exclude_files = ['crc32_small.c', 'crc64_small.c', 'crc32_tablegen.c', 'crc64_tablegen.c', 'price_tablegen.c', 'fastpos_tablegen.c' ++ exclude_files = ['crc32_small.c', 'crc64_small.c', 'crc32_tablegen.c', 'crc64_tablegen.c', 'price_tablegen.c', 'fastpos_tablegen.c', + 'tuklib_exit.c', 'tuklib_mbstr_fw.c', 'tuklib_mbstr_width.c', 'tuklib_open_stdxxx.c', 'tuklib_progname.c'] -+ include_dirs_rel = ['../common', 'api', 'common', 'check', 'lz', 'rangecoder', 'lzma', 'delta', 'simple'] -+ -+ Path(dest_path, os.path.join('src', 'config.h')).write_text(config_h) -+ -+ include_dirs = [os.path.join(dest_path, 'src', 'liblzma', p) for p in include_dirs_rel] -+ ports.build_port(os.path.join(dest_path, 'src'), final, flags=build_flags, exclude_dirs=exclude_dirs, exclude_files=exclude_files, includes=include_dirs) ++ include_dirs_rel = ['../common', 'api', 'check', 'common', 'delta', 'lz', 'lzma', 'rangecoder', 'simple'] + -+ ports.install_headers(os.path.join(dest_path, 'src', 'liblzma', 'api'), 'lzma.h') -+ ports.install_headers(os.path.join(dest_path, 'src', 'liblzma', 'api', 'lzma'), '*.h', 'lzma') ++ include_dirs = [os.path.join(source_path, p) for p in include_dirs_rel] ++ ports.build_port(source_path, final, 'liblzma', flags=build_flags, exclude_files=exclude_files, includes=include_dirs) + -+ return [shared.Cache.get_lib('liblzma.a', create, what='port')] ++ return [shared.cache.get_lib('liblzma.a', create, what='port')] + + +def clear(ports, settings, shared): -+ shared.Cache.erase_lib('liblzma.a') ++ shared.cache.erase_lib('liblzma.a') + + +def process_args(ports): @@ -105,7 +95,7 @@ new file mode 100644 + return 'liblzma (USE_LIBLZMA=1; public domain)' + + -+config_h = r''' ++config_h = ''' +#define ASSUME_RAM 128 +#define ENABLE_NLS 1 +#define HAVE_CHECK_CRC32 1 @@ -177,9 +167,9 @@ new file mode 100644 +#define PACKAGE "xz" +#define PACKAGE_BUGREPORT "lasse.collin@tukaani.org" +#define PACKAGE_NAME "XZ Utils" -+#define PACKAGE_STRING "XZ Utils 5.2.5" ++#define PACKAGE_STRING "XZ Utils 5.4.0" +#define PACKAGE_TARNAME "xz" -+#define PACKAGE_VERSION "5.2.5" ++#define PACKAGE_VERSION "5.4.0" +#define SIZEOF_SIZE_T 4 +#define STDC_HEADERS 1 +#define TUKLIB_CPUCORES_SYSCONF 1 @@ -200,5 +190,5 @@ new file mode 100644 +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif -+#define VERSION "5.2.5" ++#define VERSION "5.4.0" +''' diff --git a/os/gog/linux.json b/os/gog/linux.json new file mode 100755 index 0000000000000..47e80fd255de3 --- /dev/null +++ b/os/gog/linux.json @@ -0,0 +1,64 @@ +{ + "project": { + "baseProductId": "1293297882", + "clientId": "CLIENT_ID", + "clientSecret": "CLIENT_SECRET", + "version": "VERSION", + "installDirectory": "OpenTTD", + "name": "OpenTTD", + "platform": "gnu-linux", + "tags": [ + "editor_v_1_4_0" + ], + "languageMode": "together", + "products": [ + { + "name": "OpenTTD", + "productId": "1293297882", + "depots": [ + { + "name": "Linux", + "folder": "linux", + "languages": [ + "en-US" + ] + }, + { + "name": "OpenGFX", + "folder": "opengfx", + "languages": [ + "en-US" + ] + }, + { + "name": "OpenMSX", + "folder": "openmsx", + "languages": [ + "en-US" + ] + }, + { + "name": "OpenSFX", + "folder": "opensfx", + "languages": [ + "en-US" + ] + } + ], + "tasks": [ + { + "type": "FileTask", + "name": "OpenTTD", + "languages": [ + "en-US" + ], + "category": "game", + "path": "openttd", + "isPrimary": true + } + ], + "supportDepots": [] + } + ] + } +} diff --git a/os/gog/macos.json b/os/gog/macos.json new file mode 100755 index 0000000000000..8ce9a02be793d --- /dev/null +++ b/os/gog/macos.json @@ -0,0 +1,65 @@ +{ + "project": { + "baseProductId": "1293297882", + "clientId": "CLIENT_ID", + "clientSecret": "CLIENT_SECRET", + "version": "VERSION", + "installDirectory": "OpenTTD", + "name": "OpenTTD", + "platform": "osx", + "tags": [ + "editor_v_1_4_0" + ], + "languageMode": "together", + "products": [ + { + "name": "OpenTTD", + "productId": "1293297882", + "depots": [ + { + "name": "MacOS", + "folder": "macos", + "languages": [ + "en-US" + ] + }, + { + "name": "OpenGFX", + "folder": "opengfx", + "languages": [ + "en-US" + ] + }, + { + "name": "OpenMSX", + "folder": "openmsx", + "languages": [ + "en-US" + ] + }, + { + "name": "OpenSFX", + "folder": "opensfx", + "languages": [ + "en-US" + ] + } + ], + "tasks": [ + { + "type": "FileTask", + "name": "OpenTTD", + "languages": [ + "en-US" + ], + "category": "game", + "path": "OpenTTD.app/Contents/MacOS/openttd", + "isPrimary": true + } + ], + "supportDepots": [] + } + ] + } +} + diff --git a/os/gog/windows.json b/os/gog/windows.json new file mode 100755 index 0000000000000..8582abb06049e --- /dev/null +++ b/os/gog/windows.json @@ -0,0 +1,94 @@ +{ + "project": { + "baseProductId": "1293297882", + "clientId": "CLIENT_ID", + "clientSecret": "CLIENT_SECRET", + "version": "VERSION", + "installDirectory": "OpenTTD", + "name": "OpenTTD", + "platform": "windows", + "tags": [ + "editor_v_1_4_0" + ], + "languageMode": "together", + "products": [ + { + "name": "OpenTTD", + "productId": "1293297882", + "depots": [ + { + "name": "Win32", + "folder": "win32", + "languages": [ + "en-US" + ], + "osBitness": [ + "32" + ] + }, + { + "name": "Win64", + "folder": "win64", + "languages": [ + "en-US" + ], + "osBitness": [ + "64" + ] + }, + { + "name": "OpenGFX", + "folder": "opengfx", + "languages": [ + "en-US" + ], + "osBitness": [ + "32", + "64" + ] + }, + { + "name": "OpenMSX", + "folder": "openmsx", + "languages": [ + "en-US" + ], + "osBitness": [ + "32", + "64" + ] + }, + { + "name": "OpenSFX", + "folder": "opensfx", + "languages": [ + "en-US" + ], + "osBitness": [ + "32", + "64" + ] + } + ], + "tasks": [ + { + "type": "FileTask", + "name": "OpenTTD", + "languages": [ + "en-US" + ], + "category": "game", + "path": "openttd.exe", + "isPrimary": true, + "osBitness": [ + "32", + "64" + ] + } + ], + "supportDepots": [] + } + ], + "scriptInterpreter": true + } +} diff --git a/os/macosx/Info.plist.in b/os/macosx/Info.plist.in index 0148ab289a6f6..71619d8936674 100644 --- a/os/macosx/Info.plist.in +++ b/os/macosx/Info.plist.in @@ -32,6 +32,6 @@ NSHighResolutionCapable True LSMinimumSystemVersion - 10.14.0 + 10.13.0 diff --git a/os/windows/openttd.manifest b/os/windows/openttd.manifest index ee1c7ea2242e6..cb536a819d6b9 100644 --- a/os/windows/openttd.manifest +++ b/os/windows/openttd.manifest @@ -10,6 +10,7 @@ True/PM + PerMonitorV2,PerMonitor diff --git a/os/windows/winstore/generate-assets.ps1 b/os/windows/winstore/generate-assets.ps1 index 89c48e6ecfd29..bd12caf80acfe 100644 --- a/os/windows/winstore/generate-assets.ps1 +++ b/os/windows/winstore/generate-assets.ps1 @@ -45,4 +45,4 @@ ResizeImage $logoPath 1240 600 "assets\Wide310x150Logo.png" # Copy the logo for the store for the common package New-Item -Path "." -Name "assets-common" -ItemType "directory" -Force -Copy-Item "assets\StoreLogo.png" -Destination "assets-common\StoreLogo.png" +Copy-Item "assets\StoreLogo.png" -Destination "assets-common\StoreLogoCommon.png" diff --git a/regression/regression/info.nut b/regression/regression/info.nut index 8799d98628359..9c775eede5b8f 100644 --- a/regression/regression/info.nut +++ b/regression/regression/info.nut @@ -4,7 +4,7 @@ class Regression extends AIInfo { function GetShortName() { return "REGR"; } function GetDescription() { return "This runs regression-tests on some commands. On the same map the result should always be the same."; } function GetVersion() { return 1; } - function GetAPIVersion() { return "13"; } + function GetAPIVersion() { return "14"; } function GetDate() { return "2007-03-18"; } function CreateInstance() { return "Regression"; } function UseAsRandomAI() { return false; } diff --git a/regression/regression/main.nut b/regression/regression/main.nut index 9b68226953e29..7621c49c6f78e 100644 --- a/regression/regression/main.nut +++ b/regression/regression/main.nut @@ -341,6 +341,7 @@ function Regression::Cargo() print(" GetCargoIncome(10, 10): " + AICargo.GetCargoIncome(i, 10, 10)); print(" GetCargoIncome(100, 10): " + AICargo.GetCargoIncome(i, 100, 10)); print(" GetCargoIncome(10, 100): " + AICargo.GetCargoIncome(i, 10, 100)); + print(" GetWeight(100): " + AICargo.GetWeight(i, 100)); print(" GetRoadVehicleTypeForCargo(): " + AIRoad.GetRoadVehicleTypeForCargo(i)); } } @@ -561,6 +562,25 @@ function Regression::Prices() print(" BT_CLEAR_WATER: " + AITile.GetBuildCost(AITile.BT_CLEAR_WATER)); } +function Regression::Commands() +{ + print(""); + print("--Commands--"); + + print(" -Command accounting-"); + local test = AITestMode(); + local costs = AIAccounting(); + AITile.DemolishTile(2834); + print(" Command cost: " + costs.GetCosts()); + { + local inner = AIAccounting(); + print(" New inner cost scope: " + costs.GetCosts()); + AITile.DemolishTile(2835); + print(" Further command cost: " + costs.GetCosts()); + } + print(" Saved cost of outer scope: " + costs.GetCosts()); +} + function cost_callback(old_path, new_tile, new_direction, self) { if (old_path == null) return 0; return old_path.GetCost() + 1; } function estimate_callback(tile, direction, goals, self) { return goals[0] - tile; } function neighbours_callback(path, cur_tile, self) { return [[cur_tile + 1, 1]]; } @@ -1683,6 +1703,7 @@ function Regression::Vehicle() print(" BuildVehicle(): " + AIVehicle.BuildVehicle(33417, 153)); print(" IsValidVehicle(12): " + AIVehicle.IsValidVehicle(12)); print(" CloneVehicle(): " + AIVehicle.CloneVehicle(33417, 12, true)); + print(" BuildVehicle(): " + AIVehicle.BuildVehicle(-1, 153)); local bank_after = AICompany.GetBankBalance(AICompany.COMPANY_SELF); @@ -1939,6 +1960,7 @@ function Regression::Start() /* Do this first as it gains maximum loan (which is faked to quite a lot). */ this.Company(); + this.Commands(); this.Airport(); this.Bridge(); this.BridgeList(); diff --git a/regression/regression/result.txt b/regression/regression/result.txt index cca295fa01062..9942857cfb37c 100644 --- a/regression/regression/result.txt +++ b/regression/regression/result.txt @@ -88,24 +88,24 @@ abs( 21): 21 --AIBase-- - Rand(): -54346916 - Rand(): -937374575 - Rand(): 823953997 + Rand(): 2232656694 + Rand(): 2514636170 + Rand(): 3897038727 RandRange(0): 0 RandRange(0): 0 RandRange(0): 0 RandRange(1): 0 RandRange(1): 0 RandRange(1): 0 - RandRange(2): 1 - RandRange(2): 1 - RandRange(2): 1 - RandRange(1000000): 966676 - RandRange(1000000): 289525 - RandRange(1000000): 170283 - Chance(1, 2): false + RandRange(2): 0 + RandRange(2): 0 + RandRange(2): 0 + RandRange(1000000): 666804 + RandRange(1000000): 624059 + RandRange(1000000): 697029 Chance(1, 2): true Chance(1, 2): false + Chance(1, 2): true --List-- IsEmpty(): true @@ -420,144 +420,144 @@ 1098 => 46116 1099 => 46158 Randomize ListDump: - 1 => -200078348 - 2 => -29799264 - 1000 => 1630721656 - 1001 => 959306175 - 1002 => 1527421791 - 1003 => 1259692483 - 1004 => -1289244298 - 1005 => -1572996668 - 1006 => -2069479746 - 1007 => -1819131606 - 1008 => -1007163964 - 1009 => -1185394870 - 1010 => -1471365065 - 1011 => 364354366 - 1012 => -1478084253 - 1013 => 405281367 - 1014 => -11170062 - 1015 => 156767750 - 1016 => 1288924796 - 1017 => 1796884876 - 1018 => -1947073702 - 1019 => -1999614238 - 1020 => -231292809 - 1021 => 966621566 - 1022 => -606766557 - 1023 => -1138727825 - 1024 => -749544262 - 1025 => 2004771271 - 1026 => 686734186 - 1027 => 923274744 - 1028 => -1672035149 - 1029 => -1642064950 - 1030 => 1363389551 - 1031 => -559500928 - 1032 => 1656196991 - 1033 => 1655354425 - 1034 => -1027156689 - 1035 => 1952644328 - 1036 => 1217870217 - 1037 => 242274100 - 1038 => 201816080 - 1039 => 2127464758 - 1040 => 446043650 - 1041 => -319728455 - 1042 => 204701002 - 1043 => -571265398 - 1044 => -1422217131 - 1045 => -391208397 - 1046 => -1822628371 - 1047 => -1499755350 - 1048 => -1422137641 - 1049 => 1621693134 - 1051 => -1428728134 - 1052 => -147587573 - 1053 => 681719500 - 1054 => 1172011190 - 1055 => -1834344882 - 1056 => 1157634586 - 1057 => 1902133676 - 1058 => -1967780161 - 1059 => -1618025531 - 1060 => -810220453 - 1061 => 1582854921 - 1062 => -410004643 - 1063 => 1159917159 - 1064 => -1377804984 - 1065 => -738843914 - 1066 => -1578756103 - 1067 => -464090986 - 1068 => 1711504679 - 1069 => 545330655 - 1070 => 379462570 - 1071 => 514511099 - 1072 => -1813251176 - 1073 => 1424958266 - 1074 => -825255131 - 1075 => 539054595 - 1076 => -1764192010 - 1077 => -1243277769 - 1078 => 2017874281 - 1079 => -1972353607 - 1080 => 1879761467 - 1081 => 1638986560 - 1082 => -1832287507 - 1083 => -492411882 - 1084 => 658940812 - 1085 => -1044199400 - 1086 => 1586504918 - 1087 => -125492611 - 1088 => -1562883174 - 1089 => -1013778441 - 1090 => 1560228607 - 1091 => -550265689 - 1092 => 524767105 - 1093 => -713387661 - 1094 => 1425927738 - 1095 => 942653932 - 1096 => 1233220698 - 1097 => 1313602368 - 1098 => -140318584 - 1099 => 1199179892 + 1 => 688298322 + 2 => 2585420314 + 1000 => 1701392078 + 1001 => 2664118875 + 1002 => 3408466361 + 1003 => 4098642324 + 1004 => 3858929894 + 1005 => 3774625512 + 1006 => 2809742492 + 1007 => 3983931060 + 1008 => 2791524857 + 1009 => 4184021601 + 1010 => 4212142121 + 1011 => 46859773 + 1012 => 3095744278 + 1013 => 3104411371 + 1014 => 326384434 + 1015 => 1486817960 + 1016 => 2883541699 + 1017 => 3786540442 + 1018 => 820019294 + 1019 => 710762995 + 1020 => 3534100264 + 1021 => 3585356150 + 1022 => 732190215 + 1023 => 236336673 + 1024 => 740596257 + 1025 => 1135321785 + 1026 => 2067474156 + 1027 => 2899283689 + 1028 => 4054438597 + 1029 => 928616892 + 1030 => 1712486685 + 1031 => 1994118287 + 1032 => 1333321243 + 1033 => 194124284 + 1034 => 615083294 + 1035 => 628086450 + 1036 => 498957825 + 1037 => 1359697121 + 1038 => 1888433963 + 1039 => 941623020 + 1040 => 2369304004 + 1041 => 3523427032 + 1042 => 3236625937 + 1043 => 182127597 + 1044 => 646955927 + 1045 => 2870345582 + 1046 => 623062612 + 1047 => 2308011710 + 1048 => 3026140316 + 1049 => 3838191076 + 1051 => 3182411967 + 1052 => 2762833244 + 1053 => 1960404034 + 1054 => 1573325453 + 1055 => 3978347993 + 1056 => 699712177 + 1057 => 863274966 + 1058 => 1728276475 + 1059 => 4048271407 + 1060 => 1919485436 + 1061 => 111273464 + 1062 => 125435213 + 1063 => 155132602 + 1064 => 4123293220 + 1065 => 655046914 + 1066 => 1577399562 + 1067 => 1028818150 + 1068 => 447058239 + 1069 => 3237047027 + 1070 => 2968751973 + 1071 => 4096278708 + 1072 => 1523643051 + 1073 => 231373233 + 1074 => 1121759962 + 1075 => 1449439846 + 1076 => 2679696543 + 1077 => 2785673432 + 1078 => 2116903943 + 1079 => 672822173 + 1080 => 3325393385 + 1081 => 1589904755 + 1082 => 1148782015 + 1083 => 663503316 + 1084 => 933352745 + 1085 => 577717039 + 1086 => 402172048 + 1087 => 1812250453 + 1088 => 667300501 + 1089 => 2456141519 + 1090 => 3438492520 + 1091 => 420696035 + 1092 => 2131427774 + 1093 => 3859663748 + 1094 => 4134083418 + 1095 => 1969629634 + 1096 => 3739173141 + 1097 => 3459847605 + 1098 => 2834059387 + 1099 => 3148043212 KeepTop(10): - 1 => -200078348 - 2 => -29799264 - 1000 => 1630721656 - 1001 => 959306175 - 1002 => 1527421791 - 1003 => 1259692483 - 1004 => -1289244298 - 1005 => -1572996668 - 1006 => -2069479746 - 1007 => -1819131606 + 1 => 688298322 + 2 => 2585420314 + 1000 => 1701392078 + 1001 => 2664118875 + 1002 => 3408466361 + 1003 => 4098642324 + 1004 => 3858929894 + 1005 => 3774625512 + 1006 => 2809742492 + 1007 => 3983931060 KeepBottom(8): - 1000 => 1630721656 - 1001 => 959306175 - 1002 => 1527421791 - 1003 => 1259692483 - 1004 => -1289244298 - 1005 => -1572996668 - 1006 => -2069479746 - 1007 => -1819131606 + 1000 => 1701392078 + 1001 => 2664118875 + 1002 => 3408466361 + 1003 => 4098642324 + 1004 => 3858929894 + 1005 => 3774625512 + 1006 => 2809742492 + 1007 => 3983931060 RemoveBottom(2): - 1000 => 1630721656 - 1001 => 959306175 - 1002 => 1527421791 - 1003 => 1259692483 - 1004 => -1289244298 - 1005 => -1572996668 + 1000 => 1701392078 + 1001 => 2664118875 + 1002 => 3408466361 + 1003 => 4098642324 + 1004 => 3858929894 + 1005 => 3774625512 RemoveTop(2): - 1002 => 1527421791 - 1003 => 1259692483 - 1004 => -1289244298 - 1005 => -1572996668 + 1002 => 3408466361 + 1003 => 4098642324 + 1004 => 3858929894 + 1005 => 3774625512 RemoveList({1003, 1004}): - 1002 => 1527421791 - 1005 => -1572996668 + 1002 => 3408466361 + 1005 => 3774625512 KeepList({1003, 1004, 1005}): - 1005 => -1572996668 + 1005 => 3774625512 AddList({1005, 4000, 4001, 4002}): 1005 => 1005 4000 => 8000 @@ -588,7 +588,7 @@ ERROR: IsEnd() is invalid as Begin() is never called SetName(): false GetLastErrorString(): ERR_NAME_IS_NOT_UNIQUE GetName(): Regression - GetPresidentName(): E. McAlpine + GetPresidentName(): J. Green SetPresidentName(): true GetPresidentName(): Regression AI GetBankBalance(): 100000 @@ -788,6 +788,13 @@ ERROR: IsEnd() is invalid as Begin() is never called GetQuarterlyPerformanceRating(): 0 GetQuarterlyCompanyValue(): 0 +--Commands-- + -Command accounting- + Command cost: 7500 + New inner cost scope: 0 + Further command cost: 30 + Saved cost of outer scope: 7500 + --AIAirport-- IsHangarTile(): false IsAirportTile(): false @@ -1118,6 +1125,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): -1 GetCargoIncome(100, 10): -1 GetCargoIncome(10, 100): -1 + GetWeight(100): -1 GetRoadVehicleTypeForCargo(): 1 Cargo 0 IsValidCargo(): true @@ -1130,6 +1138,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): 3 GetCargoIncome(100, 10): 38 GetCargoIncome(10, 100): 3 + GetWeight(100): 6 GetRoadVehicleTypeForCargo(): 0 Cargo 1 IsValidCargo(): true @@ -1142,6 +1151,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): 7 GetCargoIncome(100, 10): 71 GetCargoIncome(10, 100): 6 + GetWeight(100): 100 GetRoadVehicleTypeForCargo(): 1 Cargo 2 IsValidCargo(): true @@ -1154,6 +1164,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): 5 GetCargoIncome(100, 10): 55 GetCargoIncome(10, 100): 5 + GetWeight(100): 25 GetRoadVehicleTypeForCargo(): 1 Cargo 3 IsValidCargo(): true @@ -1166,6 +1177,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): 5 GetCargoIncome(100, 10): 53 GetCargoIncome(10, 100): 5 + GetWeight(100): 100 GetRoadVehicleTypeForCargo(): 1 Cargo 4 IsValidCargo(): true @@ -1178,6 +1190,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): 5 GetCargoIncome(100, 10): 52 GetCargoIncome(10, 100): 4 + GetWeight(100): 18 GetRoadVehicleTypeForCargo(): 1 Cargo 5 IsValidCargo(): true @@ -1190,6 +1203,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): 7 GetCargoIncome(100, 10): 74 GetCargoIncome(10, 100): 6 + GetWeight(100): 50 GetRoadVehicleTypeForCargo(): 1 Cargo 6 IsValidCargo(): true @@ -1202,6 +1216,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): 5 GetCargoIncome(100, 10): 58 GetCargoIncome(10, 100): 4 + GetWeight(100): 100 GetRoadVehicleTypeForCargo(): 1 Cargo 7 IsValidCargo(): true @@ -1214,6 +1229,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): 6 GetCargoIncome(100, 10): 60 GetCargoIncome(10, 100): 5 + GetWeight(100): 100 GetRoadVehicleTypeForCargo(): 1 Cargo 8 IsValidCargo(): true @@ -1226,6 +1242,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): 6 GetCargoIncome(100, 10): 62 GetCargoIncome(10, 100): 5 + GetWeight(100): 100 GetRoadVehicleTypeForCargo(): 1 Cargo 9 IsValidCargo(): true @@ -1238,6 +1255,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): 6 GetCargoIncome(100, 10): 69 GetCargoIncome(10, 100): 6 + GetWeight(100): 100 GetRoadVehicleTypeForCargo(): 1 Cargo 10 IsValidCargo(): true @@ -1250,6 +1268,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): 9 GetCargoIncome(100, 10): 90 GetCargoIncome(10, 100): 7 + GetWeight(100): 12 GetRoadVehicleTypeForCargo(): 1 Cargo 11 IsValidCargo(): false @@ -1262,6 +1281,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): -1 GetCargoIncome(100, 10): -1 GetCargoIncome(10, 100): -1 + GetWeight(100): -1 GetRoadVehicleTypeForCargo(): 1 Cargo 12 IsValidCargo(): false @@ -1274,6 +1294,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): -1 GetCargoIncome(100, 10): -1 GetCargoIncome(10, 100): -1 + GetWeight(100): -1 GetRoadVehicleTypeForCargo(): 1 Cargo 13 IsValidCargo(): false @@ -1286,6 +1307,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): -1 GetCargoIncome(100, 10): -1 GetCargoIncome(10, 100): -1 + GetWeight(100): -1 GetRoadVehicleTypeForCargo(): 1 Cargo 14 IsValidCargo(): false @@ -1298,6 +1320,7 @@ ERROR: IsEnd() is invalid as Begin() is never called GetCargoIncome(10, 10): -1 GetCargoIncome(100, 10): -1 GetCargoIncome(10, 100): -1 + GetWeight(100): -1 GetRoadVehicleTypeForCargo(): 1 --CargoList-- @@ -9272,6 +9295,7 @@ ERROR: IsEnd() is invalid as Begin() is never called BuildVehicle(): 12 IsValidVehicle(12): true CloneVehicle(): 13 + BuildVehicle(): 1048575 --Accounting-- GetCosts(): 11894 Should be: 11894 diff --git a/regression/stationlist/info.nut b/regression/stationlist/info.nut index 099a7d12ec28c..f3a168487611d 100644 --- a/regression/stationlist/info.nut +++ b/regression/stationlist/info.nut @@ -4,7 +4,7 @@ class StationList extends AIInfo { function GetShortName() { return "REGS"; } function GetDescription() { return "This runs stationlist-tests on some commands. On the same map the result should always be the same."; } function GetVersion() { return 1; } - function GetAPIVersion() { return "13"; } + function GetAPIVersion() { return "14"; } function GetDate() { return "2007-03-18"; } function CreateInstance() { return "StationList"; } function UseAsRandomAI() { return false; } diff --git a/src/3rdparty/fmt/core.h b/src/3rdparty/fmt/core.h index 0a81e0ccd953a..bddad78ec452a 100644 --- a/src/3rdparty/fmt/core.h +++ b/src/3rdparty/fmt/core.h @@ -529,7 +529,6 @@ void check_format_string(S); struct error_handler { constexpr error_handler() = default; - constexpr error_handler(const error_handler&) = default; // This function is intentionally not constexpr to give a compile-time error. FMT_NORETURN FMT_API void on_error(const char* message); diff --git a/src/3rdparty/squirrel/squirrel/sqclass.h b/src/3rdparty/squirrel/squirrel/sqclass.h index 4fb6ecbd97928..dad4ba08afee5 100644 --- a/src/3rdparty/squirrel/squirrel/sqclass.h +++ b/src/3rdparty/squirrel/squirrel/sqclass.h @@ -10,6 +10,7 @@ struct SQClassMember { val = o.val; attrs = o.attrs; } + SQClassMember& operator=(SQClassMember &o) = delete; SQObjectPtr val; SQObjectPtr attrs; }; diff --git a/src/3rdparty/squirrel/squirrel/sqcompiler.cpp b/src/3rdparty/squirrel/squirrel/sqcompiler.cpp index 3af111a28a80b..9ba1597120462 100644 --- a/src/3rdparty/squirrel/squirrel/sqcompiler.cpp +++ b/src/3rdparty/squirrel/squirrel/sqcompiler.cpp @@ -607,7 +607,6 @@ class SQCompiler switch(_token) { case TK_STRING_LITERAL: { - //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1)); _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1))); Lex(); } @@ -840,7 +839,6 @@ class SQCompiler unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0); SQInteger table = _fs->TopTarget(); //<AddInstruction(_OP_NEWSLOTA, flags, table, key, val); - //_fs->PopTarget(); } if(separator == ',') //hack recognizes a table from the separator _fs->SetIntructionParam(tpos, 1, nkeys); @@ -1053,7 +1051,6 @@ class SQCompiler if(tonextcondjmp != -1) _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp); if(_token == TK_DEFAULT) { - // _fs->AddLineInfos(_lex._currentline, _lineinfo); Lex(); Expect(':'); SQInteger stacksize = _fs->GetStackSize(); _last_stacksize = _fs->GetStackSize(); @@ -1167,11 +1164,6 @@ class SQCompiler } SQTable *enums = _table(_ss(_vm)->_consts); SQObjectPtr strongid = id; - /*SQObjectPtr dummy; - if(enums->Get(strongid,dummy)) { - dummy.Null(); strongid.Null(); - Error("enumeration already exists"); - }*/ enums->NewSlot(SQObjectPtr(strongid),SQObjectPtr(table)); strongid.Null(); Lex(); @@ -1318,7 +1310,6 @@ class SQCompiler funcstate->AddLineInfos(_lex._prevtoken == '\n'?_lex._lasttokenline:_lex._currentline, _lineinfo, true); funcstate->AddInstruction(_OP_RETURN, -1); funcstate->SetStackSize(0); - //_fs->->_stacksize = _fs->_stacksize; SQFunctionProto *func = funcstate->BuildProto(); #ifdef _DEBUG_DUMP funcstate->Dump(func); diff --git a/src/3rdparty/squirrel/squirrel/sqlexer.cpp b/src/3rdparty/squirrel/squirrel/sqlexer.cpp index a4bac822798f2..c4fb852991f28 100644 --- a/src/3rdparty/squirrel/squirrel/sqlexer.cpp +++ b/src/3rdparty/squirrel/squirrel/sqlexer.cpp @@ -177,7 +177,6 @@ SQInteger SQLexer::Lex() else if ( CUR_CHAR == '-' ) { NEXT(); RETURN_TOKEN(TK_NEWSLOT); } else if ( CUR_CHAR == '<' ) { NEXT(); RETURN_TOKEN(TK_SHIFTL); } else if ( CUR_CHAR == '/' ) { NEXT(); RETURN_TOKEN(TK_ATTR_OPEN); } - //else if ( CUR_CHAR == '[' ) { NEXT(); ReadMultilineString(); RETURN_TOKEN(TK_STRING_LITERAL); } else { RETURN_TOKEN('<') } case '>': NEXT(); diff --git a/src/3rdparty/squirrel/squirrel/sqobject.cpp b/src/3rdparty/squirrel/squirrel/sqobject.cpp index 298efe610c1e9..ca105fd5ef16a 100644 --- a/src/3rdparty/squirrel/squirrel/sqobject.cpp +++ b/src/3rdparty/squirrel/squirrel/sqobject.cpp @@ -446,11 +446,11 @@ bool SQFunctionProto::Load(SQVM *v,SQUserPointer up,SQREADFUNC read,SQObjectPtr for(i = 0; i < noutervalues; i++){ SQUnsignedInteger type; - SQObjectPtr name; + SQObjectPtr value_name; _CHECK_IO(SafeRead(v,read,up, &type, sizeof(SQUnsignedInteger))); _CHECK_IO(ReadObject(v, up, read, o)); - _CHECK_IO(ReadObject(v, up, read, name)); - f->_outervalues[i] = SQOuterVar(name,o, (SQOuterType)type); + _CHECK_IO(ReadObject(v, up, read, value_name)); + f->_outervalues[i] = SQOuterVar(value_name,o, (SQOuterType)type); } _CHECK_IO(CheckTag(v,read,up,SQ_CLOSURESTREAM_PART)); diff --git a/src/3rdparty/squirrel/squirrel/sqstate.cpp b/src/3rdparty/squirrel/squirrel/sqstate.cpp index 0f95c396c9112..ce2fdfa55d49c 100644 --- a/src/3rdparty/squirrel/squirrel/sqstate.cpp +++ b/src/3rdparty/squirrel/squirrel/sqstate.cpp @@ -246,9 +246,9 @@ void SQSharedState::DelayFinalFree(SQCollectable *collectable) if (!this->_collectable_free_processing) { this->_collectable_free_processing = true; while (!this->_collectable_free_queue.empty()) { - SQCollectable *collectable = this->_collectable_free_queue.back(); + SQCollectable *collectable_to_free = this->_collectable_free_queue.back(); this->_collectable_free_queue.pop_back(); - collectable->FinalFree(); + collectable_to_free->FinalFree(); } this->_collectable_free_processing = false; } @@ -450,10 +450,10 @@ void RefTable::Resize(SQUnsignedInteger size) SQUnsignedInteger oldnumofslots = _numofslots; AllocNodes(size); //rehash - SQUnsignedInteger nfound = 0; + [[maybe_unused]] SQUnsignedInteger nfound = 0; for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) { if(type(t->obj) != OT_NULL) { - //add back; + //add back assert(t->refs != 0); RefNode *nn = Add(::HashObj(t->obj)&(_numofslots-1),t->obj); nn->refs = t->refs; @@ -513,7 +513,7 @@ void RefTable::AllocNodes(SQUnsignedInteger size) bucks[n] = nullptr; temp->refs = 0; new (&temp->obj) SQObjectPtr; - temp->next = temp+1; + temp->next = &temp[1]; temp++; } bucks[n] = nullptr; diff --git a/src/3rdparty/squirrel/squirrel/sqvm.cpp b/src/3rdparty/squirrel/squirrel/sqvm.cpp index 1f81a2e9a6980..e643e259841f9 100644 --- a/src/3rdparty/squirrel/squirrel/sqvm.cpp +++ b/src/3rdparty/squirrel/squirrel/sqvm.cpp @@ -140,7 +140,6 @@ void SQVM::Finalize() SQVM::~SQVM() { Finalize(); - //sq_free(_callsstack,_alloccallsstacksize*sizeof(CallInfo)); REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain,this); } @@ -712,7 +711,6 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn return false; } if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) { - //SQFunctionProto *f = _funcproto(_closure(temp_reg)->_function); SQGenerator *gen = SQGenerator::Create(_ss(this), _closure(temp_reg)); _GUARD(gen->Yield(this)); Return(1, ci->_target, temp_reg); @@ -747,8 +745,10 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn if (ShouldSuspend()) { _suspended = SQTrue; _suspended_traps = traps; return true; } const SQInstruction &_i_ = *ci->_ip++; - //dumpstack(_stackbase); - //printf("%s %d %d %d %d\n",g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3); +#ifdef _DEBUG_DUMP + dumpstack(_stackbase); + printf("%s %d %d %d %d\n",g_InstrDesc[_i_.op].name,arg0,arg1,arg2,arg3); +#endif switch(_i_.op) { case _OP_LINE: @@ -1053,7 +1053,9 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn exception_trap: { SQObjectPtr currerror = _lasterror; -// dumpstack(_stackbase); +#ifdef _DEBUG_DUMP + dumpstack(_stackbase); +#endif SQInteger n = 0; SQInteger last_top = _top; if(ci) { @@ -1062,11 +1064,11 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn if(traps) { do { if(ci->_etraps > 0) { - SQExceptionTrap &et = _etraps.top(); - ci->_ip = et._ip; - _top = et._stacksize; - _stackbase = et._stackbase; - _stack._vals[_stackbase+et._extarget] = currerror; + SQExceptionTrap &trap = _etraps.top(); + ci->_ip = trap._ip; + _top = trap._stacksize; + _stackbase = trap._stackbase; + _stack._vals[_stackbase+trap._extarget] = currerror; _etraps.pop_back(); traps--; ci->_etraps--; CLEARSTACK(last_top); goto exception_restore; diff --git a/src/3rdparty/squirrel/squirrel/sqvm.h b/src/3rdparty/squirrel/squirrel/sqvm.h index dbfe2309c7cc5..6389058923a1a 100644 --- a/src/3rdparty/squirrel/squirrel/sqvm.h +++ b/src/3rdparty/squirrel/squirrel/sqvm.h @@ -36,7 +36,6 @@ struct SQVM : public CHAINABLE_OBJ }; struct CallInfo{ - //CallInfo() { _generator._type = OT_NULL;} SQInstruction *_ip; SQObjectPtr *_literals; SQObjectPtr _closure; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9dc9ef29cae67..34d7f755f36ea 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,7 @@ add_subdirectory(3rdparty) add_subdirectory(ai) add_subdirectory(blitter) add_subdirectory(core) +add_subdirectory(fontcache) add_subdirectory(game) add_subdirectory(lang) add_subdirectory(linkgraph) @@ -29,11 +30,6 @@ add_files( viewport_sprite_sorter_sse4.cpp CONDITION SSE_FOUND ) -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") - set_compile_flags( - viewport_sprite_sorter_sse4.cpp - COMPILE_FLAGS -msse4.1) -endif() add_files( aircraft.h @@ -162,7 +158,6 @@ add_files( fios_gui.cpp fontcache.cpp fontcache.h - fontcache_internal.h fontdetection.h framerate_gui.cpp framerate_type.h @@ -221,6 +216,12 @@ add_files( landscape_cmd.h landscape_type.h language.h + league_base.h + league_cmd.h + league_cmd.cpp + league_gui.h + league_gui.cpp + league_type.h livery.h main_gui.cpp map.cpp @@ -273,6 +274,8 @@ add_files( newgrf_properties.h newgrf_railtype.cpp newgrf_railtype.h + newgrf_roadstop.cpp + newgrf_roadstop.h newgrf_roadtype.cpp newgrf_roadtype.h newgrf_sound.cpp diff --git a/src/ai/ai.hpp b/src/ai/ai.hpp index 59886486fe547..e090303bd9560 100644 --- a/src/ai/ai.hpp +++ b/src/ai/ai.hpp @@ -13,10 +13,6 @@ #include "../script/api/script_event_types.hpp" #include "../core/string_compare_type.hpp" #include "ai_scanner.hpp" -#include - -/** A list that maps AI names to their AIInfo object. */ -typedef std::map ScriptInfoList; /** * Main AI class. Contains all functions needed to start, stop, save and load AIs. @@ -128,20 +124,15 @@ class AI { */ static void Save(CompanyID company); - /** - * Load data for an AI from a savegame. - */ - static void Load(CompanyID company, int version); - /** * Get the number of days before the next AI should start. */ static int GetStartNextTime(); /** Wrapper function for AIScanner::GetAIConsoleList */ - static char *GetConsoleList(char *p, const char *last, bool newest_only = false); + static std::string GetConsoleList(bool newest_only = false); /** Wrapper function for AIScanner::GetAIConsoleLibraryList */ - static char *GetConsoleLibraryList(char *p, const char *last); + static std::string GetConsoleLibraryList(); /** Wrapper function for AIScanner::GetAIInfoList */ static const ScriptInfoList *GetInfoList(); /** Wrapper function for AIScanner::GetUniqueAIInfoList */ diff --git a/src/ai/ai_core.cpp b/src/ai/ai_core.cpp index e45738776df60..220e7bdbd2312 100644 --- a/src/ai/ai_core.cpp +++ b/src/ai/ai_core.cpp @@ -57,10 +57,12 @@ assert(c->ai_instance == nullptr); c->ai_instance = new AIInstance(); c->ai_instance->Initialize(info); + c->ai_instance->LoadOnStack(config->GetToLoadData()); + config->SetToLoadData(nullptr); cur_company.Restore(); - InvalidateWindowData(WC_AI_DEBUG, 0, -1); + InvalidateWindowData(WC_SCRIPT_DEBUG, 0, -1); return; } @@ -80,18 +82,16 @@ PerformanceMeasurer framerate((PerformanceElement)(PFE_AI0 + c->index)); cur_company.Change(c->index); c->ai_instance->GameLoop(); + /* Occasionally collect garbage; every 255 ticks do one company. + * Effectively collecting garbage once every two months per AI. */ + if ((AI::frame_counter & 255) == 0 && (CompanyID)GB(AI::frame_counter, 8, 4) == c->index) { + c->ai_instance->CollectGarbage(); + } } else { PerformanceMeasurer::SetInactive((PerformanceElement)(PFE_AI0 + c->index)); } } cur_company.Restore(); - - /* Occasionally collect garbage; every 255 ticks do one company. - * Effectively collecting garbage once every two months per AI. */ - if ((AI::frame_counter & 255) == 0) { - CompanyID cid = (CompanyID)GB(AI::frame_counter, 8, 4); - if (Company::IsValidAiID(cid)) Company::Get(cid)->ai_instance->CollectGarbage(); - } } /* static */ uint AI::GetTick() @@ -113,8 +113,8 @@ cur_company.Restore(); - InvalidateWindowData(WC_AI_DEBUG, 0, -1); - CloseWindowById(WC_AI_SETTINGS, company); + InvalidateWindowData(WC_SCRIPT_DEBUG, 0, -1); + CloseWindowById(WC_SCRIPT_SETTINGS, company); } /* static */ void AI::Pause(CompanyID company) @@ -289,21 +289,6 @@ } } -/* static */ void AI::Load(CompanyID company, int version) -{ - if (!_networking || _network_server) { - Company *c = Company::GetIfValid(company); - assert(c != nullptr && c->ai_instance != nullptr); - - Backup cur_company(_current_company, company, FILE_LINE); - c->ai_instance->Load(version); - cur_company.Restore(); - } else { - /* Read, but ignore, the load data */ - AIInstance::LoadEmpty(); - } -} - /* static */ int AI::GetStartNextTime() { /* Find the first company which doesn't exist yet */ @@ -315,14 +300,14 @@ return DAYS_IN_YEAR; } -/* static */ char *AI::GetConsoleList(char *p, const char *last, bool newest_only) +/* static */ std::string AI::GetConsoleList(bool newest_only) { - return AI::scanner_info->GetConsoleList(p, last, newest_only); + return AI::scanner_info->GetConsoleList(newest_only); } -/* static */ char *AI::GetConsoleLibraryList(char *p, const char *last) +/* static */ std::string AI::GetConsoleLibraryList() { - return AI::scanner_library->GetConsoleList(p, last, true); + return AI::scanner_library->GetConsoleList(true); } /* static */ const ScriptInfoList *AI::GetInfoList() @@ -353,9 +338,9 @@ AI::scanner_library->RescanDir(); ResetConfig(); - InvalidateWindowData(WC_AI_LIST, 0, 1); - SetWindowClassesDirty(WC_AI_DEBUG); - InvalidateWindowClassesData(WC_AI_SETTINGS); + InvalidateWindowData(WC_SCRIPT_LIST, 0, 1); + SetWindowClassesDirty(WC_SCRIPT_DEBUG); + InvalidateWindowClassesData(WC_SCRIPT_SETTINGS); } /** diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index c4a8667620477..da60bb9f98468 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.cpp @@ -8,687 +8,37 @@ /** @file ai_gui.cpp %Window for configuring the AIs */ #include "../stdafx.h" -#include "../table/sprites.h" #include "../error.h" -#include "../settings_gui.h" -#include "../querystring_gui.h" -#include "../stringfilter_type.h" #include "../company_base.h" -#include "../company_gui.h" -#include "../strings_func.h" #include "../window_func.h" -#include "../gfx_func.h" -#include "../command_func.h" #include "../network/network.h" #include "../settings_func.h" #include "../network/network_content.h" -#include "../textfile_gui.h" -#include "../widgets/dropdown_type.h" -#include "../widgets/dropdown_func.h" -#include "../hotkeys.h" #include "../core/geometry_func.hpp" -#include "../guitimer_func.h" -#include "../company_cmd.h" -#include "../misc_cmd.h" #include "ai.hpp" #include "ai_gui.hpp" -#include "../script/api/script_log.hpp" #include "ai_config.hpp" #include "ai_info.hpp" -#include "ai_instance.hpp" -#include "../game/game.hpp" -#include "../game/game_config.hpp" -#include "../game/game_info.hpp" -#include "../game/game_instance.hpp" - -#include "table/strings.h" - -#include - -#include "../safeguards.h" - -static ScriptConfig *GetConfig(CompanyID slot) -{ - if (slot == OWNER_DEITY) return GameConfig::GetConfig(); - return AIConfig::GetConfig(slot); -} - -/** - * Window that let you choose an available AI. - */ -struct AIListWindow : public Window { - const ScriptInfoList *info_list; ///< The list of Scripts. - int selected; ///< The currently selected Script. - CompanyID slot; ///< The company we're selecting a new Script for. - int line_height; ///< Height of a row in the matrix widget. - Scrollbar *vscroll; ///< Cache of the vertical scrollbar. - - /** - * Constructor for the window. - * @param desc The description of the window. - * @param slot The company we're changing the AI for. - */ - AIListWindow(WindowDesc *desc, CompanyID slot) : Window(desc), - slot(slot) - { - if (slot == OWNER_DEITY) { - this->info_list = Game::GetUniqueInfoList(); - } else { - this->info_list = AI::GetUniqueInfoList(); - } - - this->CreateNestedTree(); - this->vscroll = this->GetScrollbar(WID_AIL_SCROLLBAR); - this->FinishInitNested(); // Initializes 'this->line_height' as side effect. - - this->vscroll->SetCount((int)this->info_list->size() + 1); - - /* Try if we can find the currently selected AI */ - this->selected = -1; - if (GetConfig(slot)->HasScript()) { - ScriptInfo *info = GetConfig(slot)->GetInfo(); - int i = 0; - for (const auto &item : *this->info_list) { - if (item.second == info) { - this->selected = i; - break; - } - - i++; - } - } - } - - void SetStringParameters(int widget) const override - { - switch (widget) { - case WID_AIL_CAPTION: - SetDParam(0, (this->slot == OWNER_DEITY) ? STR_AI_LIST_CAPTION_GAMESCRIPT : STR_AI_LIST_CAPTION_AI); - break; - } - } - - void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override - { - if (widget == WID_AIL_LIST) { - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; - - resize->width = 1; - resize->height = this->line_height; - size->height = 5 * this->line_height; - } - } - - void DrawWidget(const Rect &r, int widget) const override - { - switch (widget) { - case WID_AIL_LIST: { - /* Draw a list of all available AIs. */ - int y = this->GetWidget(WID_AIL_LIST)->pos_y; - /* First AI in the list is hardcoded to random */ - if (this->vscroll->IsVisible(0)) { - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_LEFT, y + WD_MATRIX_TOP, this->slot == OWNER_DEITY ? STR_AI_CONFIG_NONE : STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_ORANGE); - y += this->line_height; - } - int i = 0; - for (const auto &item : *this->info_list) { - i++; - if (this->vscroll->IsVisible(i)) { - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, item.second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE); - y += this->line_height; - } - } - break; - } - case WID_AIL_INFO_BG: { - AIInfo *selected_info = nullptr; - int i = 0; - for (const auto &item : *this->info_list) { - i++; - if (this->selected == i - 1) selected_info = static_cast(item.second); - } - /* Some info about the currently selected AI. */ - if (selected_info != nullptr) { - int y = r.top + WD_FRAMERECT_TOP; - SetDParamStr(0, selected_info->GetAuthor()); - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_AUTHOR); - y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; - SetDParam(0, selected_info->GetVersion()); - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_VERSION); - y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; - if (selected_info->GetURL() != nullptr) { - SetDParamStr(0, selected_info->GetURL()); - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_URL); - y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; - } - SetDParamStr(0, selected_info->GetDescription()); - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, r.bottom - WD_FRAMERECT_BOTTOM, STR_JUST_RAW_STRING, TC_WHITE); - } - break; - } - } - } - - /** - * Changes the AI of the current slot. - */ - void ChangeAI() - { - if (this->selected == -1) { - GetConfig(slot)->Change(nullptr); - } else { - ScriptInfoList::const_iterator it = this->info_list->begin(); - for (int i = 0; i < this->selected; i++) it++; - GetConfig(slot)->Change((*it).second->GetName(), (*it).second->GetVersion()); - } - InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_AI); - InvalidateWindowClassesData(WC_AI_SETTINGS); - CloseWindowByClass(WC_QUERY_STRING); - InvalidateWindowClassesData(WC_TEXTFILE); - } - - void OnClick(Point pt, int widget, int click_count) override - { - switch (widget) { - case WID_AIL_LIST: { // Select one of the AIs - int sel = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_AIL_LIST) - 1; - if (sel < (int)this->info_list->size()) { - this->selected = sel; - this->SetDirty(); - if (click_count > 1) { - this->ChangeAI(); - this->Close(); - } - } - break; - } - - case WID_AIL_ACCEPT: { - this->ChangeAI(); - this->Close(); - break; - } - - case WID_AIL_CANCEL: - this->Close(); - break; - } - } - - void OnResize() override - { - this->vscroll->SetCapacityFromWidget(this, WID_AIL_LIST); - } - - /** - * Some data on this window has become invalid. - * @param data Information about the changed data. - * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. - */ - void OnInvalidateData(int data = 0, bool gui_scope = true) override - { - if (_game_mode == GM_NORMAL && Company::IsValidID(this->slot)) { - this->Close(); - return; - } - - if (!gui_scope) return; - - this->vscroll->SetCount((int)this->info_list->size() + 1); - - /* selected goes from -1 .. length of ai list - 1. */ - this->selected = std::min(this->selected, this->vscroll->GetCount() - 2); - } -}; - -/** Widgets for the AI list window. */ -static const NWidgetPart _nested_ai_list_widgets[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), - NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_AIL_CAPTION), SetDataTip(STR_AI_LIST_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIL_LIST), SetMinimalSize(188, 112), SetFill(1, 1), SetResize(1, 1), SetMatrixDataTip(1, 0, STR_AI_LIST_TOOLTIP), SetScrollbar(WID_AIL_SCROLLBAR), - NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_AIL_SCROLLBAR), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_MAUVE, WID_AIL_INFO_BG), SetMinimalTextLines(8, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM), SetResize(1, 0), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_AIL_ACCEPT), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_LIST_ACCEPT, STR_AI_LIST_ACCEPT_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_AIL_CANCEL), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_LIST_CANCEL, STR_AI_LIST_CANCEL_TOOLTIP), - EndContainer(), - NWidget(WWT_RESIZEBOX, COLOUR_MAUVE), - EndContainer(), -}; - -/** Window definition for the ai list window. */ -static WindowDesc _ai_list_desc( - WDP_CENTER, "settings_script_list", 200, 234, - WC_AI_LIST, WC_NONE, - 0, - _nested_ai_list_widgets, lengthof(_nested_ai_list_widgets) -); - -/** - * Open the AI list window to chose an AI for the given company slot. - * @param slot The slot to change the AI of. - */ -static void ShowAIListWindow(CompanyID slot) -{ - CloseWindowByClass(WC_AI_LIST); - new AIListWindow(&_ai_list_desc, slot); -} - -/** - * Window for settings the parameters of an AI. - */ -struct AISettingsWindow : public Window { - CompanyID slot; ///< The currently show company's setting. - ScriptConfig *ai_config; ///< The configuration we're modifying. - int clicked_button; ///< The button we clicked. - bool clicked_increase; ///< Whether we clicked the increase or decrease button. - bool clicked_dropdown; ///< Whether the dropdown is open. - bool closing_dropdown; ///< True, if the dropdown list is currently closing. - GUITimer timeout; ///< Timeout for unclicking the button. - int clicked_row; ///< The clicked row of settings. - int line_height; ///< Height of a row in the matrix widget. - Scrollbar *vscroll; ///< Cache of the vertical scrollbar. - typedef std::vector VisibleSettingsList; - VisibleSettingsList visible_settings; ///< List of visible AI settings - - /** - * Constructor for the window. - * @param desc The description of the window. - * @param slot The company we're changing the settings for. - */ - AISettingsWindow(WindowDesc *desc, CompanyID slot) : Window(desc), - slot(slot), - clicked_button(-1), - clicked_dropdown(false), - closing_dropdown(false), - timeout(0) - { - this->ai_config = GetConfig(slot); - - this->CreateNestedTree(); - this->vscroll = this->GetScrollbar(WID_AIS_SCROLLBAR); - this->FinishInitNested(slot); // Initializes 'this->line_height' as side effect. - - this->RebuildVisibleSettings(); - } - - void SetStringParameters(int widget) const override - { - switch (widget) { - case WID_AIS_CAPTION: - SetDParam(0, (this->slot == OWNER_DEITY) ? STR_AI_SETTINGS_CAPTION_GAMESCRIPT : STR_AI_SETTINGS_CAPTION_AI); - break; - } - } - - /** - * Rebuilds the list of visible settings. AI settings with the flag - * AICONFIG_AI_DEVELOPER set will only be visible if the game setting - * gui.ai_developer_tools is enabled. - */ - void RebuildVisibleSettings() - { - visible_settings.clear(); - - for (const auto &item : *this->ai_config->GetConfigList()) { - bool no_hide = (item.flags & SCRIPTCONFIG_DEVELOPER) == 0; - if (no_hide || _settings_client.gui.ai_developer_tools) { - visible_settings.push_back(&item); - } - } - - this->vscroll->SetCount((int)this->visible_settings.size()); - } - - void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override - { - if (widget == WID_AIS_BACKGROUND) { - this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; - - resize->width = 1; - resize->height = this->line_height; - size->height = 5 * this->line_height; - } - } - - void DrawWidget(const Rect &r, int widget) const override - { - if (widget != WID_AIS_BACKGROUND) return; - - ScriptConfig *config = this->ai_config; - VisibleSettingsList::const_iterator it = this->visible_settings.begin(); - int i = 0; - for (; !this->vscroll->IsVisible(i); i++) it++; - - bool rtl = _current_text_dir == TD_RTL; - uint buttons_left = rtl ? r.right - SETTING_BUTTON_WIDTH - 3 : r.left + 4; - uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8); - uint text_right = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT); - - - int y = r.top; - int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; - int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; - for (; this->vscroll->IsVisible(i) && it != visible_settings.end(); i++, it++) { - const ScriptConfigItem &config_item = **it; - int current_value = config->GetSetting((config_item).name); - bool editable = this->IsEditableItem(config_item); - - StringID str; - TextColour colour; - uint idx = 0; - if (StrEmpty(config_item.description)) { - if (!strcmp(config_item.name, "start_date")) { - /* Build-in translation */ - str = STR_AI_SETTINGS_START_DELAY; - colour = TC_LIGHT_BLUE; - } else { - str = STR_JUST_STRING; - colour = TC_ORANGE; - } - } else { - str = STR_AI_SETTINGS_SETTING; - colour = TC_LIGHT_BLUE; - SetDParamStr(idx++, config_item.description); - } - - if ((config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0) { - DrawBoolButton(buttons_left, y + button_y_offset, current_value != 0, editable); - SetDParam(idx++, current_value == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON); - } else { - if (config_item.complete_labels) { - DrawDropDownButton(buttons_left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && clicked_dropdown, editable); - } else { - DrawArrowButtons(buttons_left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value); - } - if (config_item.labels != nullptr && config_item.labels->Contains(current_value)) { - SetDParam(idx++, STR_JUST_RAW_STRING); - SetDParamStr(idx++, config_item.labels->Find(current_value)->second); - } else { - SetDParam(idx++, STR_JUST_INT); - SetDParam(idx++, current_value); - } - } - - DrawString(text_left, text_right, y + text_y_offset, str, colour); - y += this->line_height; - } - } - - void OnPaint() override - { - if (this->closing_dropdown) { - this->closing_dropdown = false; - this->clicked_dropdown = false; - } - this->DrawWidgets(); - } - - void OnClick(Point pt, int widget, int click_count) override - { - switch (widget) { - case WID_AIS_BACKGROUND: { - const NWidgetBase *wid = this->GetWidget(WID_AIS_BACKGROUND); - int num = (pt.y - wid->pos_y) / this->line_height + this->vscroll->GetPosition(); - if (num >= (int)this->visible_settings.size()) break; - - VisibleSettingsList::const_iterator it = this->visible_settings.begin(); - for (int i = 0; i < num; i++) it++; - const ScriptConfigItem config_item = **it; - if (!this->IsEditableItem(config_item)) return; - - if (this->clicked_row != num) { - this->CloseChildWindows(WC_QUERY_STRING); - HideDropDownMenu(this); - this->clicked_row = num; - this->clicked_dropdown = false; - } - - bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0; - - int x = pt.x - wid->pos_x; - if (_current_text_dir == TD_RTL) x = wid->current_x - 1 - x; - x -= 4; - - /* One of the arrows is clicked (or green/red rect in case of bool value) */ - int old_val = this->ai_config->GetSetting(config_item.name); - if (!bool_item && IsInsideMM(x, 0, SETTING_BUTTON_WIDTH) && config_item.complete_labels) { - if (this->clicked_dropdown) { - /* unclick the dropdown */ - HideDropDownMenu(this); - this->clicked_dropdown = false; - this->closing_dropdown = false; - } else { - const NWidgetBase *wid = this->GetWidget(WID_AIS_BACKGROUND); - int rel_y = (pt.y - (int)wid->pos_y) % this->line_height; - - Rect wi_rect; - wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x); - wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1; - wi_rect.top = pt.y - rel_y + (this->line_height - SETTING_BUTTON_HEIGHT) / 2; - wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1; - - /* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */ - if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) { - this->clicked_dropdown = true; - this->closing_dropdown = false; - - DropDownList list; - for (int i = config_item.min_value; i <= config_item.max_value; i++) { - list.emplace_back(new DropDownListCharStringItem(config_item.labels->Find(i)->second, i, false)); - } - - ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE, true); - } - } - } else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) { - int new_val = old_val; - if (bool_item) { - new_val = !new_val; - } else if (x >= SETTING_BUTTON_WIDTH / 2) { - /* Increase button clicked */ - new_val += config_item.step_size; - if (new_val > config_item.max_value) new_val = config_item.max_value; - this->clicked_increase = true; - } else { - /* Decrease button clicked */ - new_val -= config_item.step_size; - if (new_val < config_item.min_value) new_val = config_item.min_value; - this->clicked_increase = false; - } - - if (new_val != old_val) { - this->ai_config->SetSetting(config_item.name, new_val); - this->clicked_button = num; - this->timeout.SetInterval(150); - } - } else if (!bool_item && !config_item.complete_labels) { - /* Display a query box so users can enter a custom value. */ - SetDParam(0, old_val); - ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 10, this, CS_NUMERAL, QSF_NONE); - } - this->SetDirty(); - break; - } - - case WID_AIS_ACCEPT: - this->Close(); - break; - - case WID_AIS_RESET: - this->ai_config->ResetEditableSettings(_game_mode == GM_MENU || ((this->slot != OWNER_DEITY) && !Company::IsValidID(this->slot))); - this->SetDirty(); - break; - } - } - - void OnQueryTextFinished(char *str) override - { - if (StrEmpty(str)) return; - VisibleSettingsList::const_iterator it = this->visible_settings.begin(); - for (int i = 0; i < this->clicked_row; i++) it++; - const ScriptConfigItem config_item = **it; - if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return; - int32 value = atoi(str); - this->ai_config->SetSetting(config_item.name, value); - this->SetDirty(); - } - - void OnDropdownSelect(int widget, int index) override - { - assert(this->clicked_dropdown); - VisibleSettingsList::const_iterator it = this->visible_settings.begin(); - for (int i = 0; i < this->clicked_row; i++) it++; - const ScriptConfigItem config_item = **it; - if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return; - this->ai_config->SetSetting(config_item.name, index); - this->SetDirty(); - } - - void OnDropdownClose(Point pt, int widget, int index, bool instant_close) override - { - /* We cannot raise the dropdown button just yet. OnClick needs some hint, whether - * the same dropdown button was clicked again, and then not open the dropdown again. - * So, we only remember that it was closed, and process it on the next OnPaint, which is - * after OnClick. */ - assert(this->clicked_dropdown); - this->closing_dropdown = true; - this->SetDirty(); - } - - void OnResize() override - { - this->vscroll->SetCapacityFromWidget(this, WID_AIS_BACKGROUND); - } - - void OnRealtimeTick(uint delta_ms) override - { - if (this->timeout.Elapsed(delta_ms)) { - this->clicked_button = -1; - this->SetDirty(); - } - } - - /** - * Some data on this window has become invalid. - * @param data Information about the changed data. - * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. - */ - void OnInvalidateData(int data = 0, bool gui_scope = true) override - { - this->RebuildVisibleSettings(); - HideDropDownMenu(this); - this->CloseChildWindows(WC_QUERY_STRING); - } - -private: - bool IsEditableItem(const ScriptConfigItem &config_item) const - { - return _game_mode == GM_MENU || ((this->slot != OWNER_DEITY) && !Company::IsValidID(this->slot)) || (config_item.flags & SCRIPTCONFIG_INGAME) != 0; - } -}; - -/** Widgets for the AI settings window. */ -static const NWidgetPart _nested_ai_settings_widgets[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), - NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_AIS_CAPTION), SetDataTip(STR_AI_SETTINGS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIS_BACKGROUND), SetMinimalSize(188, 182), SetResize(1, 1), SetFill(1, 0), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_AIS_SCROLLBAR), - NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_AIS_SCROLLBAR), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_AIS_ACCEPT), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL), - NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_AIS_RESET), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_SETTINGS_RESET, STR_NULL), - EndContainer(), - NWidget(WWT_RESIZEBOX, COLOUR_MAUVE), - EndContainer(), -}; - -/** Window definition for the AI settings window. */ -static WindowDesc _ai_settings_desc( - WDP_CENTER, "settings_script", 500, 208, - WC_AI_SETTINGS, WC_NONE, - 0, - _nested_ai_settings_widgets, lengthof(_nested_ai_settings_widgets) -); - -/** - * Open the AI settings window to change the AI settings for an AI. - * @param slot The CompanyID of the AI to change the settings. - */ -static void ShowAISettingsWindow(CompanyID slot) -{ - CloseWindowByClass(WC_AI_LIST); - CloseWindowByClass(WC_AI_SETTINGS); - new AISettingsWindow(&_ai_settings_desc, slot); -} - - -/** Window for displaying the textfile of a AI. */ -struct ScriptTextfileWindow : public TextfileWindow { - CompanyID slot; ///< View the textfile of this CompanyID slot. - - ScriptTextfileWindow(TextfileType file_type, CompanyID slot) : TextfileWindow(file_type), slot(slot) - { - this->OnInvalidateData(); - } - - void SetStringParameters(int widget) const override - { - if (widget == WID_TF_CAPTION) { - SetDParam(0, (slot == OWNER_DEITY) ? STR_CONTENT_TYPE_GAME_SCRIPT : STR_CONTENT_TYPE_AI); - SetDParamStr(1, GetConfig(slot)->GetInfo()->GetName()); - } - } - - void OnInvalidateData(int data = 0, bool gui_scope = true) override - { - const char *textfile = GetConfig(slot)->GetTextfile(file_type, slot); - if (textfile == nullptr) { - this->Close(); - } else { - this->LoadTextfile(textfile, (slot == OWNER_DEITY) ? GAME_DIR : AI_DIR); - } - } -}; +#include "../script/script_gui.h" +#include "table/strings.h" -/** - * Open the AI version of the textfile window. - * @param file_type The type of textfile to display. - * @param slot The slot the Script is using. - */ -void ShowScriptTextfileWindow(TextfileType file_type, CompanyID slot) -{ - CloseWindowById(WC_TEXTFILE, file_type); - new ScriptTextfileWindow(file_type, slot); -} +#include "../safeguards.h" /** Widgets for the configure AI window. */ static const NWidgetPart _nested_ai_config_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), - NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_CAPTION_AI, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), EndContainer(), NWidget(WWT_PANEL, COLOUR_MAUVE, WID_AIC_BACKGROUND), NWidget(NWID_VERTICAL), SetPIP(4, 4, 4), NWidget(NWID_HORIZONTAL), SetPIP(7, 0, 7), - NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_DECREASE), SetFill(0, 1), SetDataTip(AWV_DECREASE, STR_NULL), - NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_INCREASE), SetFill(0, 1), SetDataTip(AWV_INCREASE, STR_NULL), + NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_DECREASE), SetDataTip(AWV_DECREASE, STR_NULL), + NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_INCREASE), SetDataTip(AWV_INCREASE, STR_NULL), NWidget(NWID_SPACER), SetMinimalSize(6, 0), - NWidget(WWT_TEXT, COLOUR_MAUVE, WID_AIC_NUMBER), SetDataTip(STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS, STR_NULL), SetFill(1, 0), SetPadding(1, 0, 0, 0), + NWidget(WWT_TEXT, COLOUR_MAUVE, WID_AIC_NUMBER), SetDataTip(STR_AI_CONFIG_MAX_COMPETITORS, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_UP), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_UP, STR_AI_CONFIG_MOVE_UP_TOOLTIP), @@ -702,16 +52,13 @@ static const NWidgetPart _nested_ai_config_widgets[] = { EndContainer(), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 9), - NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_GAMESCRIPT, STR_NULL), SetPadding(0, 5, 4, 5), - NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIC_GAMELIST), SetMinimalSize(288, 14), SetFill(1, 0), SetMatrixDataTip(1, 1, STR_AI_CONFIG_GAMELIST_TOOLTIP), - EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CHANGE), SetFill(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_CONFIG_CHANGE, STR_AI_CONFIG_CHANGE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CHANGE), SetFill(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_CONFIG_CHANGE_AI, STR_AI_CONFIG_CHANGE_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CONFIGURE), SetFill(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_CONFIG_CONFIGURE, STR_AI_CONFIG_CONFIGURE_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CLOSE), SetFill(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CLOSE), SetFill(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL), NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), EndContainer(), @@ -748,8 +95,8 @@ struct AIConfigWindow : public Window { void Close() override { - CloseWindowByClass(WC_AI_LIST); - CloseWindowByClass(WC_AI_SETTINGS); + CloseWindowByClass(WC_SCRIPT_LIST); + CloseWindowByClass(WC_SCRIPT_SETTINGS); this->Window::Close(); } @@ -759,53 +106,22 @@ struct AIConfigWindow : public Window { case WID_AIC_NUMBER: SetDParam(0, GetGameSettings().difficulty.max_no_competitors); break; - case WID_AIC_CHANGE: - switch (selected_slot) { - case OWNER_DEITY: - SetDParam(0, STR_AI_CONFIG_CHANGE_GAMESCRIPT); - break; - - case INVALID_COMPANY: - SetDParam(0, STR_AI_CONFIG_CHANGE_NONE); - break; - - default: - SetDParam(0, STR_AI_CONFIG_CHANGE_AI); - break; - } - break; } } void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { - case WID_AIC_GAMELIST: - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; - size->height = 1 * this->line_height; + case WID_AIC_DECREASE: + case WID_AIC_INCREASE: + *size = maxdim(*size, NWidgetScrollbar::GetHorizontalDimension()); break; case WID_AIC_LIST: - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = FONT_HEIGHT_NORMAL + padding.height; resize->height = this->line_height; size->height = 8 * this->line_height; break; - - case WID_AIC_CHANGE: { - SetDParam(0, STR_AI_CONFIG_CHANGE_GAMESCRIPT); - Dimension dim = GetStringBoundingBox(STR_AI_CONFIG_CHANGE); - - SetDParam(0, STR_AI_CONFIG_CHANGE_NONE); - dim = maxdim(dim, GetStringBoundingBox(STR_AI_CONFIG_CHANGE)); - - SetDParam(0, STR_AI_CONFIG_CHANGE_AI); - dim = maxdim(dim, GetStringBoundingBox(STR_AI_CONFIG_CHANGE)); - - dim.width += padding.width; - dim.height += padding.height; - *size = maxdim(*size, dim); - break; - } } } @@ -816,8 +132,6 @@ struct AIConfigWindow : public Window { */ static bool IsEditable(CompanyID slot) { - if (slot == OWNER_DEITY) return _game_mode != GM_NORMAL || Game::GetInstance() != nullptr; - if (_game_mode != GM_NORMAL) { return slot > 0 && slot <= GetGameSettings().difficulty.max_no_competitors; } @@ -833,22 +147,8 @@ struct AIConfigWindow : public Window { void DrawWidget(const Rect &r, int widget) const override { switch (widget) { - case WID_AIC_GAMELIST: { - StringID text = STR_AI_CONFIG_NONE; - - if (GameConfig::GetConfig()->GetInfo() != nullptr) { - SetDParamStr(0, GameConfig::GetConfig()->GetInfo()->GetName()); - text = STR_JUST_RAW_STRING; - } - - DrawString(r.left + 10, r.right - 10, r.top + WD_MATRIX_TOP, text, - (this->selected_slot == OWNER_DEITY) ? TC_WHITE : (IsEditable(OWNER_DEITY) ? TC_ORANGE : TC_SILVER)); - - break; - } - case WID_AIC_LIST: { - int y = r.top; + Rect tr = r.Shrink(WidgetDimensions::scaled.matrix); for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < MAX_COMPANIES; i++) { StringID text; @@ -860,9 +160,9 @@ struct AIConfigWindow : public Window { } else { text = STR_AI_CONFIG_RANDOM_AI; } - DrawString(r.left + 10, r.right - 10, y + WD_MATRIX_TOP, text, + DrawString(tr, text, (this->selected_slot == i) ? TC_WHITE : (IsEditable((CompanyID)i) ? TC_ORANGE : TC_SILVER)); - y += this->line_height; + tr.top += this->line_height; } break; } @@ -872,7 +172,7 @@ struct AIConfigWindow : public Window { void OnClick(Point pt, int widget, int click_count) override { if (widget >= WID_AIC_TEXTFILE && widget < WID_AIC_TEXTFILE + TFT_END) { - if (this->selected_slot == INVALID_COMPANY || GetConfig(this->selected_slot) == nullptr) return; + if (this->selected_slot == INVALID_COMPANY || AIConfig::GetConfig(this->selected_slot) == nullptr) return; ShowScriptTextfileWindow((TextfileType)(widget - WID_AIC_TEXTFILE), this->selected_slot); return; @@ -891,17 +191,10 @@ struct AIConfigWindow : public Window { break; } - case WID_AIC_GAMELIST: { - this->selected_slot = OWNER_DEITY; - this->InvalidateData(); - if (click_count > 1 && this->selected_slot != INVALID_COMPANY && _game_mode != GM_NORMAL) ShowAIListWindow((CompanyID)this->selected_slot); - break; - } - case WID_AIC_LIST: { // Select a slot this->selected_slot = (CompanyID)this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget); this->InvalidateData(); - if (click_count > 1 && this->selected_slot != INVALID_COMPANY) ShowAIListWindow((CompanyID)this->selected_slot); + if (click_count > 1 && this->selected_slot != INVALID_COMPANY) ShowScriptListWindow((CompanyID)this->selected_slot); break; } @@ -924,11 +217,11 @@ struct AIConfigWindow : public Window { break; case WID_AIC_CHANGE: // choose other AI - ShowAIListWindow((CompanyID)this->selected_slot); + ShowScriptListWindow((CompanyID)this->selected_slot); break; case WID_AIC_CONFIGURE: // change the settings for an AI - ShowAISettingsWindow((CompanyID)this->selected_slot); + ShowScriptSettingsWindow((CompanyID)this->selected_slot); break; case WID_AIC_CLOSE: @@ -939,7 +232,7 @@ struct AIConfigWindow : public Window { if (!_network_available) { ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR); } else { - ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_AI, CONTENT_TYPE_GAME); + ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_AI); } break; } @@ -960,13 +253,13 @@ struct AIConfigWindow : public Window { this->SetWidgetDisabledState(WID_AIC_DECREASE, GetGameSettings().difficulty.max_no_competitors == 0); this->SetWidgetDisabledState(WID_AIC_INCREASE, GetGameSettings().difficulty.max_no_competitors == MAX_COMPANIES - 1); - this->SetWidgetDisabledState(WID_AIC_CHANGE, (this->selected_slot == OWNER_DEITY && _game_mode == GM_NORMAL) || this->selected_slot == INVALID_COMPANY); - this->SetWidgetDisabledState(WID_AIC_CONFIGURE, this->selected_slot == INVALID_COMPANY || GetConfig(this->selected_slot)->GetConfigList()->size() == 0); - this->SetWidgetDisabledState(WID_AIC_MOVE_UP, this->selected_slot == OWNER_DEITY || this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot - 1))); - this->SetWidgetDisabledState(WID_AIC_MOVE_DOWN, this->selected_slot == OWNER_DEITY || this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot + 1))); + this->SetWidgetDisabledState(WID_AIC_CHANGE, this->selected_slot == INVALID_COMPANY); + this->SetWidgetDisabledState(WID_AIC_CONFIGURE, this->selected_slot == INVALID_COMPANY || AIConfig::GetConfig(this->selected_slot)->GetConfigList()->size() == 0); + this->SetWidgetDisabledState(WID_AIC_MOVE_UP, this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot - 1))); + this->SetWidgetDisabledState(WID_AIC_MOVE_DOWN, this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot + 1))); for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) { - this->SetWidgetDisabledState(WID_AIC_TEXTFILE + tft, this->selected_slot == INVALID_COMPANY || (GetConfig(this->selected_slot)->GetTextfile(tft, this->selected_slot) == nullptr)); + this->SetWidgetDisabledState(WID_AIC_TEXTFILE + tft, this->selected_slot == INVALID_COMPANY || (AIConfig::GetConfig(this->selected_slot)->GetTextfile(tft, this->selected_slot) == nullptr)); } } }; @@ -978,601 +271,3 @@ void ShowAIConfigWindow() new AIConfigWindow(); } -/** - * Set the widget colour of a button based on the - * state of the script. (dead or alive) - * @param button the button to update. - * @param dead true if the script is dead, otherwise false. - * @param paused true if the script is paused, otherwise false. - * @return true if the colour was changed and the window need to be marked as dirty. - */ -static bool SetScriptButtonColour(NWidgetCore &button, bool dead, bool paused) -{ - /* Dead scripts are indicated with red background and - * paused scripts are indicated with yellow background. */ - Colours colour = dead ? COLOUR_RED : - (paused ? COLOUR_YELLOW : COLOUR_GREY); - if (button.colour != colour) { - button.colour = colour; - return true; - } - return false; -} - -/** - * Window with everything an AI prints via ScriptLog. - */ -struct AIDebugWindow : public Window { - static const int top_offset; ///< Offset of the text at the top of the WID_AID_LOG_PANEL. - static const int bottom_offset; ///< Offset of the text at the bottom of the WID_AID_LOG_PANEL. - - static const uint MAX_BREAK_STR_STRING_LENGTH = 256; ///< Maximum length of the break string. - - static CompanyID ai_debug_company; ///< The AI that is (was last) being debugged. - int redraw_timer; ///< Timer for redrawing the window, otherwise it'll happen every tick. - int last_vscroll_pos; ///< Last position of the scrolling. - bool autoscroll; ///< Whether automatically scrolling should be enabled or not. - bool show_break_box; ///< Whether the break/debug box is visible. - static bool break_check_enabled; ///< Stop an AI when it prints a matching string - static char break_string[MAX_BREAK_STR_STRING_LENGTH]; ///< The string to match to the AI output - QueryString break_editbox; ///< Break editbox - static StringFilter break_string_filter; ///< Log filter for break. - static bool case_sensitive_break_check; ///< Is the matching done case-sensitive - int highlight_row; ///< The output row that matches the given string, or -1 - Scrollbar *vscroll; ///< Cache of the vertical scrollbar. - - ScriptLog::LogData *GetLogPointer() const - { - if (ai_debug_company == OWNER_DEITY) return (ScriptLog::LogData *)Game::GetInstance()->GetLogPointer(); - return (ScriptLog::LogData *)Company::Get(ai_debug_company)->ai_instance->GetLogPointer(); - } - - /** - * Check whether the currently selected AI/GS is dead. - * @return true if dead. - */ - bool IsDead() const - { - if (ai_debug_company == OWNER_DEITY) { - GameInstance *game = Game::GetInstance(); - return game == nullptr || game->IsDead(); - } - return !Company::IsValidAiID(ai_debug_company) || Company::Get(ai_debug_company)->ai_instance->IsDead(); - } - - /** - * Check whether a company is a valid AI company or GS. - * @param company Company to check for validity. - * @return true if company is valid for debugging. - */ - bool IsValidDebugCompany(CompanyID company) const - { - switch (company) { - case INVALID_COMPANY: return false; - case OWNER_DEITY: return Game::GetInstance() != nullptr; - default: return Company::IsValidAiID(company); - } - } - - /** - * Ensure that \c ai_debug_company refers to a valid AI company or GS, or is set to #INVALID_COMPANY. - * If no valid company is selected, it selects the first valid AI or GS if any. - */ - void SelectValidDebugCompany() - { - /* Check if the currently selected company is still active. */ - if (this->IsValidDebugCompany(ai_debug_company)) return; - - ai_debug_company = INVALID_COMPANY; - - for (const Company *c : Company::Iterate()) { - if (c->is_ai) { - ChangeToAI(c->index); - return; - } - } - - /* If no AI is available, see if there is a game script. */ - if (Game::GetInstance() != nullptr) ChangeToAI(OWNER_DEITY); - } - - /** - * Constructor for the window. - * @param desc The description of the window. - * @param number The window number (actually unused). - */ - AIDebugWindow(WindowDesc *desc, WindowNumber number) : Window(desc), break_editbox(MAX_BREAK_STR_STRING_LENGTH) - { - this->CreateNestedTree(); - this->vscroll = this->GetScrollbar(WID_AID_SCROLLBAR); - this->show_break_box = _settings_client.gui.ai_developer_tools; - this->GetWidget(WID_AID_BREAK_STRING_WIDGETS)->SetDisplayedPlane(this->show_break_box ? 0 : SZSP_HORIZONTAL); - this->FinishInitNested(number); - - if (!this->show_break_box) break_check_enabled = false; - - this->last_vscroll_pos = 0; - this->autoscroll = true; - this->highlight_row = -1; - - this->querystrings[WID_AID_BREAK_STR_EDIT_BOX] = &this->break_editbox; - - SetWidgetsDisabledState(!this->show_break_box, WID_AID_BREAK_STR_ON_OFF_BTN, WID_AID_BREAK_STR_EDIT_BOX, WID_AID_MATCH_CASE_BTN, WIDGET_LIST_END); - - /* Restore the break string value from static variable */ - this->break_editbox.text.Assign(this->break_string); - - this->SelectValidDebugCompany(); - this->InvalidateData(-1); - } - - void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override - { - if (widget == WID_AID_LOG_PANEL) { - resize->height = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; - size->height = 14 * resize->height + this->top_offset + this->bottom_offset; - } - } - - void OnPaint() override - { - this->SelectValidDebugCompany(); - - /* Draw standard stuff */ - this->DrawWidgets(); - - if (this->IsShaded()) return; // Don't draw anything when the window is shaded. - - bool dirty = false; - - /* Paint the company icons */ - for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) { - NWidgetCore *button = this->GetWidget(i + WID_AID_COMPANY_BUTTON_START); - - bool valid = Company::IsValidAiID(i); - - /* Check whether the validity of the company changed */ - dirty |= (button->IsDisabled() == valid); - - /* Mark dead/paused AIs by setting the background colour. */ - bool dead = valid && Company::Get(i)->ai_instance->IsDead(); - bool paused = valid && Company::Get(i)->ai_instance->IsPaused(); - /* Re-paint if the button was updated. - * (note that it is intentional that SetScriptButtonColour is always called) */ - dirty |= SetScriptButtonColour(*button, dead, paused); - - /* Draw company icon only for valid AI companies */ - if (!valid) continue; - - byte offset = (i == ai_debug_company) ? 1 : 0; - DrawCompanyIcon(i, button->pos_x + button->current_x / 2 - 7 + offset, this->GetWidget(WID_AID_COMPANY_BUTTON_START + i)->pos_y + 2 + offset); - } - - /* Set button colour for Game Script. */ - GameInstance *game = Game::GetInstance(); - bool valid = game != nullptr; - bool dead = valid && game->IsDead(); - bool paused = valid && game->IsPaused(); - - NWidgetCore *button = this->GetWidget(WID_AID_SCRIPT_GAME); - dirty |= (button->IsDisabled() == valid) || SetScriptButtonColour(*button, dead, paused); - - if (dirty) this->InvalidateData(-1); - - /* If there are no active companies, don't display anything else. */ - if (ai_debug_company == INVALID_COMPANY) return; - - ScriptLog::LogData *log = this->GetLogPointer(); - - int scroll_count = (log == nullptr) ? 0 : log->used; - if (this->vscroll->GetCount() != scroll_count) { - this->vscroll->SetCount(scroll_count); - - /* We need a repaint */ - this->SetWidgetDirty(WID_AID_SCROLLBAR); - } - - if (log == nullptr) return; - - /* Detect when the user scrolls the window. Enable autoscroll when the - * bottom-most line becomes visible. */ - if (this->last_vscroll_pos != this->vscroll->GetPosition()) { - this->autoscroll = this->vscroll->GetPosition() >= log->used - this->vscroll->GetCapacity(); - } - if (this->autoscroll) { - int scroll_pos = std::max(0, log->used - this->vscroll->GetCapacity()); - if (scroll_pos != this->vscroll->GetPosition()) { - this->vscroll->SetPosition(scroll_pos); - - /* We need a repaint */ - this->SetWidgetDirty(WID_AID_SCROLLBAR); - this->SetWidgetDirty(WID_AID_LOG_PANEL); - } - } - this->last_vscroll_pos = this->vscroll->GetPosition(); - } - - void SetStringParameters(int widget) const override - { - switch (widget) { - case WID_AID_NAME_TEXT: - if (ai_debug_company == OWNER_DEITY) { - const GameInfo *info = Game::GetInfo(); - assert(info != nullptr); - SetDParam(0, STR_AI_DEBUG_NAME_AND_VERSION); - SetDParamStr(1, info->GetName()); - SetDParam(2, info->GetVersion()); - } else if (ai_debug_company == INVALID_COMPANY || !Company::IsValidAiID(ai_debug_company)) { - SetDParam(0, STR_EMPTY); - } else { - const AIInfo *info = Company::Get(ai_debug_company)->ai_info; - assert(info != nullptr); - SetDParam(0, STR_AI_DEBUG_NAME_AND_VERSION); - SetDParamStr(1, info->GetName()); - SetDParam(2, info->GetVersion()); - } - break; - } - } - - void DrawWidget(const Rect &r, int widget) const override - { - if (ai_debug_company == INVALID_COMPANY) return; - - switch (widget) { - case WID_AID_LOG_PANEL: { - ScriptLog::LogData *log = this->GetLogPointer(); - if (log == nullptr) return; - - int y = this->top_offset; - for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < log->used; i++) { - int pos = (i + log->pos + 1 - log->used + log->count) % log->count; - if (log->lines[pos] == nullptr) break; - - TextColour colour; - switch (log->type[pos]) { - case ScriptLog::LOG_SQ_INFO: colour = TC_BLACK; break; - case ScriptLog::LOG_SQ_ERROR: colour = TC_RED; break; - case ScriptLog::LOG_INFO: colour = TC_BLACK; break; - case ScriptLog::LOG_WARNING: colour = TC_YELLOW; break; - case ScriptLog::LOG_ERROR: colour = TC_RED; break; - default: colour = TC_BLACK; break; - } - - /* Check if the current line should be highlighted */ - if (pos == this->highlight_row) { - GfxFillRect(r.left + 1, r.top + y, r.right - 1, r.top + y + this->resize.step_height - WD_PAR_VSEP_NORMAL, PC_BLACK); - if (colour == TC_BLACK) colour = TC_WHITE; // Make black text readable by inverting it to white. - } - - DrawString(r.left + 7, r.right - 7, r.top + y, log->lines[pos], colour, SA_LEFT | SA_FORCE); - y += this->resize.step_height; - } - break; - } - } - } - - /** - * Change all settings to select another AI. - * @param show_ai The new AI to show. - */ - void ChangeToAI(CompanyID show_ai) - { - if (!this->IsValidDebugCompany(show_ai)) return; - - ai_debug_company = show_ai; - - this->highlight_row = -1; // The highlight of one AI make little sense for another AI. - - /* Close AI settings window to prevent confusion */ - CloseWindowByClass(WC_AI_SETTINGS); - - this->InvalidateData(-1); - - this->autoscroll = true; - this->last_vscroll_pos = this->vscroll->GetPosition(); - } - - void OnClick(Point pt, int widget, int click_count) override - { - /* Also called for hotkeys, so check for disabledness */ - if (this->IsWidgetDisabled(widget)) return; - - /* Check which button is clicked */ - if (IsInsideMM(widget, WID_AID_COMPANY_BUTTON_START, WID_AID_COMPANY_BUTTON_END + 1)) { - ChangeToAI((CompanyID)(widget - WID_AID_COMPANY_BUTTON_START)); - } - - switch (widget) { - case WID_AID_SCRIPT_GAME: - ChangeToAI(OWNER_DEITY); - break; - - case WID_AID_RELOAD_TOGGLE: - if (ai_debug_company == OWNER_DEITY) break; - /* First kill the company of the AI, then start a new one. This should start the current AI again */ - Command::Post(CCA_DELETE, ai_debug_company, CRR_MANUAL, INVALID_CLIENT_ID); - Command::Post(CCA_NEW_AI, ai_debug_company, CRR_NONE, INVALID_CLIENT_ID); - break; - - case WID_AID_SETTINGS: - ShowAISettingsWindow(ai_debug_company); - break; - - case WID_AID_BREAK_STR_ON_OFF_BTN: - this->break_check_enabled = !this->break_check_enabled; - this->InvalidateData(-1); - break; - - case WID_AID_MATCH_CASE_BTN: - this->case_sensitive_break_check = !this->case_sensitive_break_check; - this->InvalidateData(-1); - break; - - case WID_AID_CONTINUE_BTN: - /* Unpause current AI / game script and mark the corresponding script button dirty. */ - if (!this->IsDead()) { - if (ai_debug_company == OWNER_DEITY) { - Game::Unpause(); - } else { - AI::Unpause(ai_debug_company); - } - } - - /* If the last AI/Game Script is unpaused, unpause the game too. */ - if ((_pause_mode & PM_PAUSED_NORMAL) == PM_PAUSED_NORMAL) { - bool all_unpaused = !Game::IsPaused(); - if (all_unpaused) { - for (const Company *c : Company::Iterate()) { - if (c->is_ai && AI::IsPaused(c->index)) { - all_unpaused = false; - break; - } - } - if (all_unpaused) { - /* All scripts have been unpaused => unpause the game. */ - Command::Post(PM_PAUSED_NORMAL, false); - } - } - } - - this->highlight_row = -1; - this->InvalidateData(-1); - break; - } - } - - void OnEditboxChanged(int wid) override - { - if (wid == WID_AID_BREAK_STR_EDIT_BOX) { - /* Save the current string to static member so it can be restored next time the window is opened. */ - strecpy(this->break_string, this->break_editbox.text.buf, lastof(this->break_string)); - break_string_filter.SetFilterTerm(this->break_string); - } - } - - /** - * Some data on this window has become invalid. - * @param data Information about the changed data. - * This is the company ID of the AI/GS which wrote a new log message, or -1 in other cases. - * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. - */ - void OnInvalidateData(int data = 0, bool gui_scope = true) override - { - /* If the log message is related to the active company tab, check the break string. - * This needs to be done in gameloop-scope, so the AI is suspended immediately. */ - if (!gui_scope && data == ai_debug_company && this->IsValidDebugCompany(ai_debug_company) && this->break_check_enabled && !this->break_string_filter.IsEmpty()) { - /* Get the log instance of the active company */ - ScriptLog::LogData *log = this->GetLogPointer(); - - if (log != nullptr) { - this->break_string_filter.ResetState(); - this->break_string_filter.AddLine(log->lines[log->pos]); - if (this->break_string_filter.GetState()) { - /* Pause execution of script. */ - if (!this->IsDead()) { - if (ai_debug_company == OWNER_DEITY) { - Game::Pause(); - } else { - AI::Pause(ai_debug_company); - } - } - - /* Pause the game. */ - if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { - Command::Post(PM_PAUSED_NORMAL, true); - } - - /* Highlight row that matched */ - this->highlight_row = log->pos; - } - } - } - - if (!gui_scope) return; - - this->SelectValidDebugCompany(); - - ScriptLog::LogData *log = ai_debug_company != INVALID_COMPANY ? this->GetLogPointer() : nullptr; - this->vscroll->SetCount((log == nullptr) ? 0 : log->used); - - /* Update company buttons */ - for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) { - this->SetWidgetDisabledState(i + WID_AID_COMPANY_BUTTON_START, !Company::IsValidAiID(i)); - this->SetWidgetLoweredState(i + WID_AID_COMPANY_BUTTON_START, ai_debug_company == i); - } - - this->SetWidgetDisabledState(WID_AID_SCRIPT_GAME, Game::GetGameInstance() == nullptr); - this->SetWidgetLoweredState(WID_AID_SCRIPT_GAME, ai_debug_company == OWNER_DEITY); - - this->SetWidgetLoweredState(WID_AID_BREAK_STR_ON_OFF_BTN, this->break_check_enabled); - this->SetWidgetLoweredState(WID_AID_MATCH_CASE_BTN, this->case_sensitive_break_check); - - this->SetWidgetDisabledState(WID_AID_SETTINGS, ai_debug_company == INVALID_COMPANY); - extern CompanyID _local_company; - this->SetWidgetDisabledState(WID_AID_RELOAD_TOGGLE, ai_debug_company == INVALID_COMPANY || ai_debug_company == OWNER_DEITY || ai_debug_company == _local_company); - this->SetWidgetDisabledState(WID_AID_CONTINUE_BTN, ai_debug_company == INVALID_COMPANY || - (ai_debug_company == OWNER_DEITY ? !Game::IsPaused() : !AI::IsPaused(ai_debug_company))); - } - - void OnResize() override - { - this->vscroll->SetCapacityFromWidget(this, WID_AID_LOG_PANEL); - } - - static HotkeyList hotkeys; -}; - -const int AIDebugWindow::top_offset = WD_FRAMERECT_TOP + 2; -const int AIDebugWindow::bottom_offset = WD_FRAMERECT_BOTTOM; -CompanyID AIDebugWindow::ai_debug_company = INVALID_COMPANY; -char AIDebugWindow::break_string[MAX_BREAK_STR_STRING_LENGTH] = ""; -bool AIDebugWindow::break_check_enabled = true; -bool AIDebugWindow::case_sensitive_break_check = false; -StringFilter AIDebugWindow::break_string_filter(&AIDebugWindow::case_sensitive_break_check); - -/** Make a number of rows with buttons for each company for the AI debug window. */ -NWidgetBase *MakeCompanyButtonRowsAIDebug(int *biggest_index) -{ - return MakeCompanyButtonRows(biggest_index, WID_AID_COMPANY_BUTTON_START, WID_AID_COMPANY_BUTTON_END, COLOUR_GREY, 8, STR_AI_DEBUG_SELECT_AI_TOOLTIP); -} - -/** - * Handler for global hotkeys of the AIDebugWindow. - * @param hotkey Hotkey - * @return ES_HANDLED if hotkey was accepted. - */ -static EventState AIDebugGlobalHotkeys(int hotkey) -{ - if (_game_mode != GM_NORMAL) return ES_NOT_HANDLED; - Window *w = ShowAIDebugWindow(INVALID_COMPANY); - if (w == nullptr) return ES_NOT_HANDLED; - return w->OnHotkey(hotkey); -} - -static Hotkey aidebug_hotkeys[] = { - Hotkey('1', "company_1", WID_AID_COMPANY_BUTTON_START), - Hotkey('2', "company_2", WID_AID_COMPANY_BUTTON_START + 1), - Hotkey('3', "company_3", WID_AID_COMPANY_BUTTON_START + 2), - Hotkey('4', "company_4", WID_AID_COMPANY_BUTTON_START + 3), - Hotkey('5', "company_5", WID_AID_COMPANY_BUTTON_START + 4), - Hotkey('6', "company_6", WID_AID_COMPANY_BUTTON_START + 5), - Hotkey('7', "company_7", WID_AID_COMPANY_BUTTON_START + 6), - Hotkey('8', "company_8", WID_AID_COMPANY_BUTTON_START + 7), - Hotkey('9', "company_9", WID_AID_COMPANY_BUTTON_START + 8), - Hotkey((uint16)0, "company_10", WID_AID_COMPANY_BUTTON_START + 9), - Hotkey((uint16)0, "company_11", WID_AID_COMPANY_BUTTON_START + 10), - Hotkey((uint16)0, "company_12", WID_AID_COMPANY_BUTTON_START + 11), - Hotkey((uint16)0, "company_13", WID_AID_COMPANY_BUTTON_START + 12), - Hotkey((uint16)0, "company_14", WID_AID_COMPANY_BUTTON_START + 13), - Hotkey((uint16)0, "company_15", WID_AID_COMPANY_BUTTON_START + 14), - Hotkey('S', "settings", WID_AID_SETTINGS), - Hotkey('0', "game_script", WID_AID_SCRIPT_GAME), - Hotkey((uint16)0, "reload", WID_AID_RELOAD_TOGGLE), - Hotkey('B', "break_toggle", WID_AID_BREAK_STR_ON_OFF_BTN), - Hotkey('F', "break_string", WID_AID_BREAK_STR_EDIT_BOX), - Hotkey('C', "match_case", WID_AID_MATCH_CASE_BTN), - Hotkey(WKC_RETURN, "continue", WID_AID_CONTINUE_BTN), - HOTKEY_LIST_END -}; -HotkeyList AIDebugWindow::hotkeys("aidebug", aidebug_hotkeys, AIDebugGlobalHotkeys); - -/** Widgets for the AI debug window. */ -static const NWidgetPart _nested_ai_debug_widgets[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_GREY), - NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_AI_DEBUG, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_SHADEBOX, COLOUR_GREY), - NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), - NWidget(WWT_STICKYBOX, COLOUR_GREY), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_AID_VIEW), - NWidgetFunction(MakeCompanyButtonRowsAIDebug), SetPadding(0, 2, 1, 2), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_AID_SCRIPT_GAME), SetMinimalSize(100, 20), SetResize(1, 0), SetDataTip(STR_AI_GAME_SCRIPT, STR_AI_GAME_SCRIPT_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_AID_NAME_TEXT), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_JUST_STRING, STR_AI_DEBUG_NAME_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_AID_SETTINGS), SetMinimalSize(100, 20), SetDataTip(STR_AI_DEBUG_SETTINGS, STR_AI_DEBUG_SETTINGS_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_AID_RELOAD_TOGGLE), SetMinimalSize(100, 20), SetDataTip(STR_AI_DEBUG_RELOAD, STR_AI_DEBUG_RELOAD_TOOLTIP), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(NWID_VERTICAL), - /* Log panel */ - NWidget(WWT_PANEL, COLOUR_GREY, WID_AID_LOG_PANEL), SetMinimalSize(287, 180), SetResize(1, 1), SetScrollbar(WID_AID_SCROLLBAR), - EndContainer(), - /* Break string widgets */ - NWidget(NWID_SELECTION, INVALID_COLOUR, WID_AID_BREAK_STRING_WIDGETS), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_IMGBTN_2, COLOUR_GREY, WID_AID_BREAK_STR_ON_OFF_BTN), SetFill(0, 1), SetDataTip(SPR_FLAG_VEH_STOPPED, STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP), - NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_LABEL, COLOUR_GREY), SetPadding(2, 2, 2, 4), SetDataTip(STR_AI_DEBUG_BREAK_ON_LABEL, 0x0), - NWidget(WWT_EDITBOX, COLOUR_GREY, WID_AID_BREAK_STR_EDIT_BOX), SetFill(1, 1), SetResize(1, 0), SetPadding(2, 2, 2, 2), SetDataTip(STR_AI_DEBUG_BREAK_STR_OSKTITLE, STR_AI_DEBUG_BREAK_STR_TOOLTIP), - EndContainer(), - EndContainer(), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_AID_MATCH_CASE_BTN), SetMinimalSize(100, 0), SetFill(0, 1), SetDataTip(STR_AI_DEBUG_MATCH_CASE, STR_AI_DEBUG_MATCH_CASE_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_AID_CONTINUE_BTN), SetMinimalSize(100, 0), SetFill(0, 1), SetDataTip(STR_AI_DEBUG_CONTINUE, STR_AI_DEBUG_CONTINUE_TOOLTIP), - EndContainer(), - EndContainer(), - EndContainer(), - NWidget(NWID_VERTICAL), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_AID_SCROLLBAR), - NWidget(WWT_RESIZEBOX, COLOUR_GREY), - EndContainer(), - EndContainer(), -}; - -/** Window definition for the AI debug window. */ -static WindowDesc _ai_debug_desc( - WDP_AUTO, "script_debug", 600, 450, - WC_AI_DEBUG, WC_NONE, - 0, - _nested_ai_debug_widgets, lengthof(_nested_ai_debug_widgets), - &AIDebugWindow::hotkeys -); - -/** - * Open the AI debug window and select the given company. - * @param show_company Display debug information about this AI company. - */ -Window *ShowAIDebugWindow(CompanyID show_company) -{ - if (!_networking || _network_server) { - AIDebugWindow *w = (AIDebugWindow *)BringWindowToFrontById(WC_AI_DEBUG, 0); - if (w == nullptr) w = new AIDebugWindow(&_ai_debug_desc, 0); - if (show_company != INVALID_COMPANY) w->ChangeToAI(show_company); - return w; - } else { - ShowErrorMessage(STR_ERROR_AI_DEBUG_SERVER_ONLY, INVALID_STRING_ID, WL_INFO); - } - - return nullptr; -} - -/** - * Reset the AI windows to their initial state. - */ -void InitializeAIGui() -{ - AIDebugWindow::ai_debug_company = INVALID_COMPANY; -} - -/** Open the AI debug window if one of the AI scripts has crashed. */ -void ShowAIDebugWindowIfAIError() -{ - /* Network clients can't debug AIs. */ - if (_networking && !_network_server) return; - - for (const Company *c : Company::Iterate()) { - if (c->is_ai && c->ai_instance->IsDead()) { - ShowAIDebugWindow(c->index); - break; - } - } - - GameInstance *g = Game::GetGameInstance(); - if (g != nullptr && g->IsDead()) { - ShowAIDebugWindow(OWNER_DEITY); - } -} diff --git a/src/ai/ai_gui.hpp b/src/ai/ai_gui.hpp index 12c8ca859bda6..6eb28c38416e6 100644 --- a/src/ai/ai_gui.hpp +++ b/src/ai/ai_gui.hpp @@ -10,11 +10,6 @@ #ifndef AI_GUI_HPP #define AI_GUI_HPP -#include "../company_type.h" - -Window* ShowAIDebugWindow(CompanyID show_company = INVALID_COMPANY); void ShowAIConfigWindow(); -void ShowAIDebugWindowIfAIError(); -void InitializeAIGui(); #endif /* AI_GUI_HPP */ diff --git a/src/ai/ai_info.cpp b/src/ai/ai_info.cpp index fcd1b5a1a9d0d..b8bc1fb83d93b 100644 --- a/src/ai/ai_info.cpp +++ b/src/ai/ai_info.cpp @@ -25,7 +25,7 @@ */ static bool CheckAPIVersion(const char *api_version) { - static const std::set versions = { "0.7", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "12", "13" }; + static const std::set versions = { "0.7", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "12", "13", "14" }; return versions.find(api_version) != versions.end(); } diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp index 0e8355d7335d8..411afe3aa03a5 100644 --- a/src/ai/ai_instance.cpp +++ b/src/ai/ai_instance.cpp @@ -14,11 +14,11 @@ #include "../script/squirrel_class.hpp" #include "ai_config.hpp" -#include "ai_gui.hpp" #include "ai.hpp" #include "../script/script_storage.hpp" #include "../script/script_cmd.h" +#include "../script/script_gui.h" #include "ai_info.hpp" #include "ai_instance.hpp" @@ -61,7 +61,10 @@ void AIInstance::Died() { ScriptInstance::Died(); - ShowAIDebugWindow(_current_company); + /* Intro is not supposed to use AI, but it may have 'dummy' AI which instant dies. */ + if (_game_mode == GM_MENU) return; + + ShowScriptDebugWindow(_current_company); const AIInfo *info = AIConfig::GetConfig(_current_company, AIConfig::SSS_FORCE_GAME)->GetInfo(); if (info != nullptr) { @@ -77,7 +80,6 @@ void AIInstance::Died() void AIInstance::LoadDummyScript() { ScriptAllocatorScope alloc_scope(this->engine); - extern void Script_CreateDummy(HSQUIRRELVM vm, StringID string, const char *type); Script_CreateDummy(this->engine->GetVM(), STR_ERROR_AI_NO_AI_FOUND, "AI"); } @@ -95,11 +97,10 @@ ScriptInfo *AIInstance::FindLibrary(const char *library, int version) * DoCommand callback function for all commands executed by AIs. * @param cmd cmd as given to DoCommandPInternal. * @param result The result of the command. - * @param tile The tile on which the command was executed. * @param data Command data as given to Command<>::Post. * @param result_data Additional returned data from the command. */ -void CcAI(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, CommandDataBuffer result_data) +void CcAI(Commands cmd, const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data) { /* * The company might not exist anymore. Check for this. @@ -110,7 +111,7 @@ void CcAI(Commands cmd, const CommandCost &result, TileIndex tile, const Command const Company *c = Company::GetIfValid(_current_company); if (c == nullptr || c->ai_instance == nullptr) return; - if (c->ai_instance->DoCommandCallback(result, tile, data, std::move(result_data), cmd)) { + if (c->ai_instance->DoCommandCallback(result, data, std::move(result_data), cmd)) { c->ai_instance->Continue(); } } diff --git a/src/ai/ai_scanner.cpp b/src/ai/ai_scanner.cpp index e99b9f8f6188b..dc5eab49fac8f 100644 --- a/src/ai/ai_scanner.cpp +++ b/src/ai/ai_scanner.cpp @@ -10,9 +10,11 @@ #include "../stdafx.h" #include "../debug.h" #include "../network/network.h" +#include "../openttd.h" #include "../core/random_func.hpp" #include "../script/squirrel_class.hpp" +#include "../script/api/script_object.hpp" #include "ai_info.hpp" #include "ai_scanner.hpp" @@ -33,7 +35,6 @@ void AIScannerInfo::Initialize() /* Create the dummy AI */ this->main_script = "%_dummy"; - extern void Script_CreateDummyInfo(HSQUIRRELVM vm, const char *type, const char *dir); Script_CreateDummyInfo(this->engine->GetVM(), "AI", "ai"); } @@ -59,6 +60,11 @@ void AIScannerInfo::RegisterAPI(class Squirrel *engine) AIInfo *AIScannerInfo::SelectRandomAI() const { + if (_game_mode == GM_MENU) { + Debug(script, 0, "The intro game should not use AI, loading 'dummy' AI."); + return this->info_dummy; + } + uint num_random_ais = 0; for (const auto &item : info_single_list) { AIInfo *i = static_cast(item.second); @@ -71,12 +77,7 @@ AIInfo *AIScannerInfo::SelectRandomAI() const } /* Find a random AI */ - uint pos; - if (_networking) { - pos = InteractiveRandomRange(num_random_ais); - } else { - pos = RandomRange(num_random_ais); - } + uint pos = ScriptObject::GetRandomizer(OWNER_NONE).Next(num_random_ais); /* Find the Nth item from the array */ ScriptInfoList::const_iterator it = this->info_single_list.begin(); diff --git a/src/aircraft.h b/src/aircraft.h index f21bb964fc9e9..6701570e98a2d 100644 --- a/src/aircraft.h +++ b/src/aircraft.h @@ -111,7 +111,7 @@ struct Aircraft FINAL : public SpecializedVehicle { void OnNewDay(); uint Crash(bool flooded = false); TileIndex GetOrderStationLocation(StationID station); - bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse); + ClosestDepot FindClosestDepot(); /** * Check if the aircraft type is a normal flying device; eg @@ -140,5 +140,6 @@ struct Aircraft FINAL : public SpecializedVehicle { void GetRotorImage(const Aircraft *v, EngineImageType image_type, VehicleSpriteSeq *result); Station *GetTargetAirportIfValid(const Aircraft *v); +void HandleMissingAircraftOrders(Aircraft *v); #endif /* AIRCRAFT_H */ diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index e08b890d74387..0ec1116efbe04 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -231,7 +231,7 @@ void DrawAircraftEngine(int left, int right, int preferred_x, int y, EngineID en VehicleSpriteSeq rotor_seq; GetCustomRotorIcon(engine, image_type, &rotor_seq); if (!rotor_seq.IsValid()) rotor_seq.Set(SPR_ROTOR_STOPPED); - rotor_seq.Draw(preferred_x, y - ScaleGUITrad(5), PAL_NONE, false); + rotor_seq.Draw(preferred_x, y - ScaleSpriteTrad(5), PAL_NONE, false); } } @@ -252,8 +252,8 @@ void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoff Rect rect; seq.GetBounds(&rect); - width = UnScaleGUI(rect.right - rect.left + 1); - height = UnScaleGUI(rect.bottom - rect.top + 1); + width = UnScaleGUI(rect.Width()); + height = UnScaleGUI(rect.Height()); xoffs = UnScaleGUI(rect.left); yoffs = UnScaleGUI(rect.top); } @@ -388,7 +388,7 @@ CommandCost CmdBuildAircraft(DoCommandFlag flags, TileIndex tile, const Engine * } -bool Aircraft::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) +ClosestDepot Aircraft::FindClosestDepot() { const Station *st = GetTargetAirportIfValid(this); /* If the station is not a valid airport or if it has no hangars */ @@ -396,15 +396,12 @@ bool Aircraft::FindClosestDepot(TileIndex *location, DestinationID *destination, /* the aircraft has to search for a hangar on its own */ StationID station = FindNearestHangar(this); - if (station == INVALID_STATION) return false; + if (station == INVALID_STATION) return ClosestDepot(); st = Station::Get(station); } - if (location != nullptr) *location = st->xy; - if (destination != nullptr) *destination = st->index; - - return true; + return ClosestDepot(st->xy, st->index); } static void CheckIfAircraftNeedsService(Aircraft *v) @@ -536,12 +533,12 @@ void SetAircraftPosition(Aircraft *v, int x, int y, int z) Aircraft *u = v->Next(); - int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE); - int safe_y = Clamp(y - 1, 0, MapMaxY() * TILE_SIZE); + int safe_x = Clamp(x, 0, Map::MaxX() * TILE_SIZE); + int safe_y = Clamp(y - 1, 0, Map::MaxY() * TILE_SIZE); u->x_pos = x; u->y_pos = y - ((v->z_pos - GetSlopePixelZ(safe_x, safe_y)) >> 3); - safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE); + safe_y = Clamp(u->y_pos, 0, Map::MaxY() * TILE_SIZE); u->z_pos = GetSlopePixelZ(safe_x, safe_y); u->sprite_cache.sprite_seq.CopyWithoutPalette(v->sprite_cache.sprite_seq); // the shadow is never coloured @@ -703,8 +700,8 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE, */ int GetTileHeightBelowAircraft(const Vehicle *v) { - int safe_x = Clamp(v->x_pos, 0, MapMaxX() * TILE_SIZE); - int safe_y = Clamp(v->y_pos, 0, MapMaxY() * TILE_SIZE); + int safe_x = Clamp(v->x_pos, 0, Map::MaxX() * TILE_SIZE); + int safe_y = Clamp(v->y_pos, 0, Map::MaxY() * TILE_SIZE); return TileHeight(TileVirtXY(safe_x, safe_y)) * TILE_HEIGHT; } @@ -1171,7 +1168,7 @@ static bool HandleCrashedAircraft(Aircraft *v) /* make aircraft crash down to the ground */ if (v->crashed_counter < 500 && st == nullptr && ((v->crashed_counter % 3) == 0) ) { - int z = GetSlopePixelZ(Clamp(v->x_pos, 0, MapMaxX() * TILE_SIZE), Clamp(v->y_pos, 0, MapMaxY() * TILE_SIZE)); + int z = GetSlopePixelZ(Clamp(v->x_pos, 0, Map::MaxX() * TILE_SIZE), Clamp(v->y_pos, 0, Map::MaxY() * TILE_SIZE)); v->z_pos -= 1; if (v->z_pos == z) { v->crashed_counter = 500; diff --git a/src/aircraft_gui.cpp b/src/aircraft_gui.cpp index 422f42200294e..4192fd24731b9 100644 --- a/src/aircraft_gui.cpp +++ b/src/aircraft_gui.cpp @@ -25,59 +25,58 @@ * Draw the details for the given vehicle at the given position * * @param v current vehicle - * @param left The left most coordinate to draw - * @param right The right most coordinate to draw - * @param y The y coordinate + * @param r the Rect to draw within */ -void DrawAircraftDetails(const Aircraft *v, int left, int right, int y) +void DrawAircraftDetails(const Aircraft *v, const Rect &r) { - int y_offset = (v->Next()->cargo_cap != 0) ? -(FONT_HEIGHT_NORMAL + 1): 0; Money feeder_share = 0; + int y = r.top; for (const Aircraft *u = v; u != nullptr; u = u->Next()) { if (u->IsNormalAircraft()) { - SetDParam(0, u->engine_type); + SetDParam(0, PackEngineNameDParam(u->engine_type, EngineNameContext::VehicleDetails)); SetDParam(1, u->build_year); SetDParam(2, u->value); - DrawString(left, right, y, STR_VEHICLE_INFO_BUILT_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_BUILT_VALUE); + y += FONT_HEIGHT_NORMAL; SetDParam(0, u->cargo_type); SetDParam(1, u->cargo_cap); SetDParam(2, u->Next()->cargo_type); SetDParam(3, u->Next()->cargo_cap); SetDParam(4, GetCargoSubtypeText(u)); - DrawString(left, right, y + FONT_HEIGHT_NORMAL, (u->Next()->cargo_cap != 0) ? STR_VEHICLE_INFO_CAPACITY_CAPACITY : STR_VEHICLE_INFO_CAPACITY); + DrawString(r.left, r.right, y, (u->Next()->cargo_cap != 0) ? STR_VEHICLE_INFO_CAPACITY_CAPACITY : STR_VEHICLE_INFO_CAPACITY); + y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; } if (u->cargo_cap != 0) { uint cargo_count = u->cargo.StoredCount(); - y_offset += FONT_HEIGHT_NORMAL + 1; if (cargo_count != 0) { /* Cargo names (fix pluralness) */ SetDParam(0, u->cargo_type); SetDParam(1, cargo_count); SetDParam(2, u->cargo.Source()); - DrawString(left, right, y + 2 * FONT_HEIGHT_NORMAL + 1 + y_offset, STR_VEHICLE_DETAILS_CARGO_FROM); + DrawString(r.left, r.right, y, STR_VEHICLE_DETAILS_CARGO_FROM); + y += FONT_HEIGHT_NORMAL; feeder_share += u->cargo.FeederShare(); } } } + y += WidgetDimensions::scaled.vsep_normal; SetDParam(0, feeder_share); - DrawString(left, right, y + 3 * FONT_HEIGHT_NORMAL + 3 + y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); } /** * Draws an image of an aircraft * @param v Front vehicle - * @param left The minimum horizontal position - * @param right The maximum horizontal position - * @param y Vertical position to draw at + * @param r Rect to draw at * @param selection Selected vehicle to draw a frame around */ -void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type) +void DrawAircraftImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type) { bool rtl = _current_text_dir == TD_RTL; @@ -87,27 +86,29 @@ void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID s Rect rect; seq.GetBounds(&rect); - int width = UnScaleGUI(rect.right - rect.left + 1); + int width = UnScaleGUI(rect.Width()); int x_offs = UnScaleGUI(rect.left); - int x = rtl ? right - width - x_offs : left - x_offs; + int x = rtl ? r.right - width - x_offs : r.left - x_offs; + /* This magic -1 offset is related to the sprite_y_offsets in build_vehicle_gui.cpp */ + int y = ScaleSpriteTrad(-1) + CenterBounds(r.top, r.bottom, 0); bool helicopter = v->subtype == AIR_HELICOPTER; - int y_offs = ScaleGUITrad(10); int heli_offs = 0; PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); - seq.Draw(x, y + y_offs, pal, (v->vehstatus & VS_CRASHED) != 0); + seq.Draw(x, y, pal, (v->vehstatus & VS_CRASHED) != 0); if (helicopter) { const Aircraft *a = Aircraft::From(v); VehicleSpriteSeq rotor_seq; GetCustomRotorSprite(a, image_type, &rotor_seq); if (!rotor_seq.IsValid()) rotor_seq.Set(SPR_ROTOR_STOPPED); - heli_offs = ScaleGUITrad(5); - rotor_seq.Draw(x, y + y_offs - heli_offs, PAL_NONE, false); + heli_offs = ScaleSpriteTrad(5); + rotor_seq.Draw(x, y - heli_offs, PAL_NONE, false); } if (v->index == selection) { x += x_offs; - y += UnScaleGUI(rect.top) + y_offs - heli_offs; - DrawFrameRect(x - 1, y - 1, x + width + 1, y + UnScaleGUI(rect.bottom - rect.top + 1) + heli_offs + 1, COLOUR_WHITE, FR_BORDERONLY); + y += UnScaleGUI(rect.top) - heli_offs; + Rect hr = {x, y, x + width - 1, y + UnScaleGUI(rect.Height()) + heli_offs - 1}; + DrawFrameRect(hr.Expand(WidgetDimensions::scaled.bevel), COLOUR_WHITE, FR_BORDERONLY); } } diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index 6700cd3bd0dca..ca747ca262894 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -8,6 +8,7 @@ /** @file airport_gui.cpp The GUI for airports. */ #include "stdafx.h" +#include "economy_func.h" #include "window_gui.h" #include "station_gui.h" #include "terraform_gui.h" @@ -29,6 +30,7 @@ #include "command_func.h" #include "airport_cmd.h" #include "station_cmd.h" +#include "zoom_func.h" #include "widgets/airport_widget.h" @@ -338,10 +340,10 @@ class BuildAirportWindow : public PickerWindowBase { const AirportSpec *as = AirportSpec::Get(i); if (!as->enabled) continue; - size->width = std::max(size->width, GetStringBoundingBox(as->name).width); + size->width = std::max(size->width, GetStringBoundingBox(as->name).width + padding.width); } - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = FONT_HEIGHT_NORMAL + padding.height; size->height = 5 * this->line_height; break; } @@ -354,8 +356,8 @@ class BuildAirportWindow : public PickerWindowBase { SpriteID sprite = GetCustomAirportSprite(as, layout); if (sprite != 0) { Dimension d = GetSpriteSize(sprite); - d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += WidgetDimensions::scaled.framerect.Horizontal(); + d.height += WidgetDimensions::scaled.framerect.Vertical(); *size = maxdim(d, *size); } } @@ -386,15 +388,17 @@ class BuildAirportWindow : public PickerWindowBase { { switch (widget) { case WID_AP_AIRPORT_LIST: { - int y = r.top; + Rect row = r.WithHeight(this->line_height).Shrink(WidgetDimensions::scaled.bevel); + Rect text = r.WithHeight(this->line_height).Shrink(WidgetDimensions::scaled.matrix); AirportClass *apclass = AirportClass::Get(_selected_airport_class); for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < apclass->GetSpecCount(); i++) { const AirportSpec *as = apclass->GetSpec(i); if (!as->IsAvailable()) { - GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->line_height - 2, PC_BLACK, FILLRECT_CHECKER); + GfxFillRect(row, PC_BLACK, FILLRECT_CHECKER); } - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK); - y += this->line_height; + DrawString(text, as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK); + row = row.Translate(0, this->line_height); + text = text.Translate(0, this->line_height); } break; } @@ -402,7 +406,7 @@ class BuildAirportWindow : public PickerWindowBase { case WID_AP_AIRPORT_SPRITE: if (this->preview_sprite != 0) { Dimension d = GetSpriteSize(this->preview_sprite); - DrawSprite(this->preview_sprite, COMPANY_SPRITE_COLOUR(_local_company), (r.left + r.right - d.width) / 2, (r.top + r.bottom - d.height) / 2); + DrawSprite(this->preview_sprite, COMPANY_SPRITE_COLOUR(_local_company), CenterBounds(r.left, r.right, d.width), CenterBounds(r.top, r.bottom, d.height)); } break; @@ -423,11 +427,8 @@ class BuildAirportWindow : public PickerWindowBase { { this->DrawWidgets(); - uint16 top = this->GetWidget(WID_AP_BTN_DOHILIGHT)->pos_y + this->GetWidget(WID_AP_BTN_DOHILIGHT)->current_y + WD_PAR_VSEP_NORMAL; - NWidgetBase *panel_nwi = this->GetWidget(WID_AP_BOTTOMPANEL); - - int right = panel_nwi->pos_x + panel_nwi->current_x; - int bottom = panel_nwi->pos_y + panel_nwi->current_y; + Rect r = this->GetWidget(WID_AP_ACCEPTANCE)->GetCurrentRect(); + int top = r.top + WidgetDimensions::scaled.vsep_normal; if (_selected_airport_index != -1) { const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index); @@ -437,20 +438,27 @@ class BuildAirportWindow : public PickerWindowBase { if (_settings_game.economy.station_noise_level) { /* show the noise of the selected airport */ SetDParam(0, as->noise_level); - DrawString(panel_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_STATION_BUILD_NOISE); - top += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; + DrawString(r.left, r.right, top, STR_STATION_BUILD_NOISE); + top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; + } + + if (_settings_game.economy.infrastructure_maintenance) { + Money monthly = _price[PR_INFRASTRUCTURE_AIRPORT] * as->maintenance_cost >> 3; + SetDParam(0, monthly * 12); + DrawString(r.left, r.right, top, STR_STATION_BUILD_INFRASTRUCTURE_COST); + top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; } /* strings such as 'Size' and 'Coverage Area' */ - top = DrawStationCoverageAreaText(panel_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, SCT_ALL, rad, false) + WD_PAR_VSEP_NORMAL; - top = DrawStationCoverageAreaText(panel_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, SCT_ALL, rad, true) + WD_PAR_VSEP_NORMAL; + top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, false) + WidgetDimensions::scaled.vsep_normal; + top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, true) + WidgetDimensions::scaled.vsep_normal; } /* Resize background if the window is too small. * Never make the window smaller to avoid oscillating if the size change affects the acceptance. * (This is the case, if making the window bigger moves the mouse into the window.) */ - if (top > bottom) { - ResizeWindow(this, 0, top - bottom, false); + if (top > r.bottom) { + ResizeWindow(this, 0, top - r.bottom, false); } } @@ -596,8 +604,8 @@ static const NWidgetPart _nested_build_airport_widgets[] = { NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_EXTRA_TEXT), SetFill(1, 0), SetMinimalSize(150, 0), EndContainer(), /* Bottom panel. */ - NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_AP_BOTTOMPANEL), SetPIP(2, 2, 2), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_AP_BOTTOMPANEL), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0), NWidget(NWID_HORIZONTAL), NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), @@ -608,7 +616,7 @@ static const NWidgetPart _nested_build_airport_widgets[] = { EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetResize(0, 1), SetFill(1, 0), + NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_ACCEPTANCE), SetPadding(WidgetDimensions::unscaled.framerect), SetResize(0, 1), SetFill(1, 0), EndContainer(), }; diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index 69c82c6e729c6..bb17af7c52d18 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -160,41 +160,6 @@ CargoArray GetCapacityOfArticulatedParts(EngineID engine) return capacity; } -/** - * Get the default cargoes and refits of an articulated vehicle. - * The refits are linked to a cargo rather than an articulated part to prevent a long list of parts. - * @param engine Model to investigate. - * @param[out] cargoes Total amount of units that can be transported, summed by cargo. - * @param[out] refits Whether a (possibly partial) refit for each cargo is possible. - * @param cargo_type Selected refitted cargo type - * @param cargo_capacity Capacity of selected refitted cargo type - */ -void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, CargoTypes *refits, CargoID cargo_type, uint cargo_capacity) -{ - cargoes->Clear(); - *refits = 0; - - const Engine *e = Engine::Get(engine); - - if (cargo_type < NUM_CARGO && cargo_capacity > 0) { - (*cargoes)[cargo_type] += cargo_capacity; - if (IsEngineRefittable(engine)) SetBit(*refits, cargo_type); - } - - if (!e->IsGroundVehicle() || !HasBit(e->info.callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) return; - - for (uint i = 1; i < MAX_ARTICULATED_PARTS; i++) { - EngineID artic_engine = GetNextArticulatedPart(i, engine); - if (artic_engine == INVALID_ENGINE) break; - - cargo_capacity = GetVehicleDefaultCapacity(artic_engine, &cargo_type); - if (cargo_type < NUM_CARGO && cargo_capacity > 0) { - (*cargoes)[cargo_type] += cargo_capacity; - if (IsEngineRefittable(artic_engine)) SetBit(*refits, cargo_type); - } - } -} - /** * Checks whether any of the articulated parts is refittable * @param engine the first part diff --git a/src/autoreplace.cpp b/src/autoreplace.cpp index e1b73448ddaae..977b5e674a04e 100644 --- a/src/autoreplace.cpp +++ b/src/autoreplace.cpp @@ -69,7 +69,18 @@ EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group, /* We didn't find anything useful in the vehicle's own group so we will try ALL_GROUP */ er = GetEngineReplacement(erl, engine, ALL_GROUP); } - if (replace_when_old != nullptr) *replace_when_old = er == nullptr ? false : er->replace_when_old; + if (replace_when_old != nullptr) { + if (er == nullptr) { + /* Not replacing */ + *replace_when_old = false; + } else if (er->to == engine) { + /* When replacing with same model, only ever do it when old */ + *replace_when_old = true; + } else { + /* Use player setting */ + *replace_when_old = er->replace_when_old; + } + } return er == nullptr ? INVALID_ENGINE : er->to; } diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 654003e39e571..c9ba7c36b8230 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -60,9 +60,6 @@ bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company) { assert(Engine::IsValidID(from) && Engine::IsValidID(to)); - /* we can't replace an engine into itself (that would be autorenew) */ - if (from == to) return false; - const Engine *e_from = Engine::Get(from); const Engine *e_to = Engine::Get(to); VehicleType type = e_from->type; @@ -346,7 +343,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic /* Build the new vehicle */ VehicleID new_veh_id; - std::tie(cost, new_veh_id, std::ignore, std::ignore) = Command::Do(DC_EXEC | DC_AUTOREPLACE, old_veh->tile, e, true, CT_INVALID, INVALID_CLIENT_ID); + std::tie(cost, new_veh_id, std::ignore, std::ignore, std::ignore) = Command::Do(DC_EXEC | DC_AUTOREPLACE, old_veh->tile, e, true, CT_INVALID, INVALID_CLIENT_ID); if (cost.Failed()) return cost; Vehicle *new_veh = Vehicle::Get(new_veh_id); @@ -422,6 +419,7 @@ static CommandCost CopyHeadSpecificThings(Vehicle *old_head, Vehicle *new_head, if (cost.Succeeded() && old_head != new_head && (flags & DC_EXEC) != 0) { /* Copy other things which cannot be copied by a command and which shall not stay resetted from the build vehicle command */ new_head->CopyVehicleConfigAndStatistics(old_head); + GroupStatistics::AddProfitLastYear(new_head); /* Switch vehicle windows/news to the new vehicle, so they are not closed/deleted when the old vehicle is sold */ ChangeVehicleViewports(old_head->index, new_head->index); @@ -444,7 +442,7 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b Train *old_v = Train::From(*single_unit); assert(!old_v->IsArticulatedPart() && !old_v->IsRearDualheaded()); - CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0); + CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, (Money)0); /* Build and refit replacement vehicle */ Vehicle *new_v = nullptr; @@ -496,7 +494,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon Vehicle *old_head = *chain; assert(old_head->IsPrimaryVehicle()); - CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0); + CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, (Money)0); if (old_head->type == VEH_TRAIN) { /* Store the length of the old vehicle chain, rounded up to whole tiles */ @@ -755,7 +753,7 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, VehicleID veh_id) w = (!free_wagon && w->type == VEH_TRAIN ? Train::From(w)->GetNextUnit() : nullptr); } - CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0); + CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, (Money)0); bool nothing_to_do = true; if (any_replacements) { @@ -780,7 +778,6 @@ CommandCost CmdAutoreplaceVehicle(DoCommandFlag flags, VehicleID veh_id) RestoreRandomSeeds(saved_seeds); if (cost.Succeeded() && (flags & DC_EXEC) != 0) { - CommandCost ret; if (free_wagon) { ret = ReplaceFreeUnit(&v, flags, ¬hing_to_do); } else { diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 4dae0eedc70e9..be339cc4a7c8b 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.cpp @@ -33,11 +33,11 @@ #include "safeguards.h" -void DrawEngineList(VehicleType type, int x, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group); +void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group); -static bool EngineNumberSorter(const EngineID &a, const EngineID &b) +static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - return Engine::Get(a)->list_position < Engine::Get(b)->list_position; + return Engine::Get(a.engine_id)->list_position < Engine::Get(b.engine_id)->list_position; } /** @@ -113,6 +113,26 @@ class ReplaceVehicleWindow : public Window { return true; } + void AddChildren(const GUIEngineList &source, GUIEngineList &target, EngineID parent, int indent, int side) + { + for (const auto &item : source) { + if (item.variant_id != parent || item.engine_id == parent) continue; + + const Engine *e = Engine::Get(item.engine_id); + EngineDisplayFlags flags = item.flags; + if (e->display_last_variant != INVALID_ENGINE) flags &= ~EngineDisplayFlags::Shaded; + target.emplace_back(e->display_last_variant == INVALID_ENGINE ? item.engine_id : e->display_last_variant, item.engine_id, flags, indent); + + /* Add variants if not folded */ + if ((item.flags & (EngineDisplayFlags::HasVariants | EngineDisplayFlags::IsFolded)) == EngineDisplayFlags::HasVariants) { + /* Add this engine again as a child */ + if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) { + target.emplace_back(item.engine_id, item.engine_id, EngineDisplayFlags::None, indent + 1); + } + AddChildren(source, target, item.engine_id, indent + 1, side); + } + } + } /** * Generate an engines list @@ -120,12 +140,12 @@ class ReplaceVehicleWindow : public Window { */ void GenerateReplaceVehList(bool draw_left) { + std::vector variants; EngineID selected_engine = INVALID_ENGINE; VehicleType type = (VehicleType)this->window_number; byte side = draw_left ? 0 : 1; - GUIEngineList *list = &this->engines[side]; - list->clear(); + GUIEngineList list; for (const Engine *e : Engine::IterateType(type)) { if (!draw_left && !this->show_hidden_engines && e->IsHidden(_local_company)) continue; @@ -155,15 +175,37 @@ class ReplaceVehicleWindow : public Window { if (!CheckAutoreplaceValidity(this->sel_engine[0], eid, _local_company)) continue; } - list->push_back(eid); + EngineDisplayFlags flags = (side == 0) ? EngineDisplayFlags::None : e->display_flags; + if (side == 1 && eid == this->sel_engine[0]) flags |= EngineDisplayFlags::Shaded; + list.emplace_back(eid, e->info.variant_id, flags, 0); + + if (side == 1 && e->info.variant_id != INVALID_ENGINE) variants.push_back(e->info.variant_id); if (eid == this->sel_engine[side]) selected_engine = eid; // The selected engine is still in the list } + + if (side == 1) { + /* ensure primary engine of variant group is in list */ + for (const auto &variant : variants) { + if (std::find(list.begin(), list.end(), variant) == list.end()) { + const Engine *e = Engine::Get(variant); + list.emplace_back(variant, e->info.variant_id, e->display_flags | EngineDisplayFlags::Shaded, 0); + } + } + } + this->sel_engine[side] = selected_engine; // update which engine we selected (the same or none, if it's not in the list anymore) if (draw_left) { - EngList_Sort(list, &EngineNumberSorter); + EngList_Sort(&list, &EngineNumberSorter); } else { _engine_sort_direction = this->descending_sort_order; - EngList_Sort(list, _engine_sort_functions[this->window_number][this->sort_criteria]); + EngList_Sort(&list, _engine_sort_functions[this->window_number][this->sort_criteria]); + } + + this->engines[side].clear(); + if (side == 1) { + AddChildren(list, this->engines[side], INVALID_ENGINE, 0, side); + } else { + this->engines[side].swap(list); } } @@ -177,7 +219,7 @@ class ReplaceVehicleWindow : public Window { this->GenerateReplaceVehList(true); this->vscroll[0]->SetCount((uint)this->engines[0].size()); if (this->reset_sel_engine && this->sel_engine[0] == INVALID_ENGINE && this->engines[0].size() != 0) { - this->sel_engine[0] = this->engines[0][0]; + this->sel_engine[0] = this->engines[0][0].engine_id; } } @@ -198,8 +240,8 @@ class ReplaceVehicleWindow : public Window { this->vscroll[1]->SetCount((uint)this->engines[1].size()); if (this->reset_sel_engine && this->sel_engine[1] != INVALID_ENGINE) { int position = 0; - for (EngineID &eid : this->engines[1]) { - if (eid == this->sel_engine[1]) break; + for (const auto &item : this->engines[1]) { + if (item.engine_id == this->sel_engine[1]) break; ++position; } this->vscroll[1]->ScrollTowards(position); @@ -304,8 +346,8 @@ class ReplaceVehicleWindow : public Window { case WID_RV_INFO_TAB: { Dimension d = GetStringBoundingBox(STR_REPLACE_NOT_REPLACING); d = maxdim(d, GetStringBoundingBox(STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED)); - d.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; - d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += padding.width; + d.height += padding.height; *size = maxdim(*size, d); break; } @@ -416,13 +458,13 @@ class ReplaceVehicleWindow : public Window { bool when_old = false; EngineID e = EngineReplacementForCompany(c, this->sel_engine[0], this->sel_group, &when_old); str = when_old ? STR_REPLACE_REPLACING_WHEN_OLD : STR_ENGINE_NAME; - SetDParam(0, e); + SetDParam(0, PackEngineNameDParam(e, EngineNameContext::PurchaseList)); } } else { str = STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED; } - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_BLACK, SA_HOR_CENTER); + DrawString(r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect), str, TC_BLACK, SA_HOR_CENTER); break; } @@ -433,8 +475,7 @@ class ReplaceVehicleWindow : public Window { EngineID end = static_cast(std::min(this->vscroll[side]->GetCapacity() + start, this->engines[side].size())); /* Do the actual drawing */ - DrawEngineList((VehicleType)this->window_number, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, - &this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group); + DrawEngineList((VehicleType)this->window_number, r, this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group); break; } } @@ -482,13 +523,12 @@ class ReplaceVehicleWindow : public Window { const Engine *e = Engine::Get(this->sel_engine[side]); TestedEngineDetails ted; ted.cost = 0; - ted.cargo = e->GetDefaultCargoType(); - ted.capacity = e->GetDisplayDefaultCapacity(&ted.mail_capacity); + ted.FillDefaultCapacities(e); - NWidgetBase *nwi = this->GetWidget(side == 0 ? WID_RV_LEFT_DETAILS : WID_RV_RIGHT_DETAILS); - int text_end = DrawVehiclePurchaseInfo(nwi->pos_x + WD_FRAMETEXT_LEFT, nwi->pos_x + nwi->current_x - WD_FRAMETEXT_RIGHT, - nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine[side], ted); - needed_height = std::max(needed_height, (text_end - (int)nwi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL); + const Rect r = this->GetWidget(side == 0 ? WID_RV_LEFT_DETAILS : WID_RV_RIGHT_DETAILS)->GetCurrentRect() + .Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect); + int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine[side], ted); + needed_height = std::max(needed_height, (text_end - r.top) / FONT_HEIGHT_NORMAL); } } if (needed_height != this->details_height) { // Details window are not high enough, enlarge them. @@ -580,7 +620,22 @@ class ReplaceVehicleWindow : public Window { uint i = this->vscroll[click_side]->GetScrolledRowFromWidget(pt.y, this, widget); size_t engine_count = this->engines[click_side].size(); - EngineID e = engine_count > i ? this->engines[click_side][i] : INVALID_ENGINE; + EngineID e = INVALID_ENGINE; + if (i < engine_count) { + const auto &item = this->engines[click_side][i]; + const Rect r = this->GetWidget(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix).WithWidth(WidgetDimensions::scaled.hsep_indent * (item.indent + 1), _current_text_dir == TD_RTL); + if ((item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None && IsInsideMM(r.left, r.right, pt.x)) { + /* toggle folded flag on engine */ + assert(item.variant_id != INVALID_ENGINE); + Engine *engine = Engine::Get(item.variant_id); + engine->display_flags ^= EngineDisplayFlags::IsFolded; + + InvalidateWindowData(WC_REPLACE_VEHICLE, (VehicleType)this->window_number, 0); // Update the autoreplace window + InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well + return; + } + if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) e = item.engine_id; + } /* If Ctrl is pressed on the left side and we don't have any engines of the selected type, stop autoreplacing. * This is most common when we have finished autoreplacing the engine and want to remove it from the list. */ diff --git a/src/base_media_base.h b/src/base_media_base.h index 790bb9d38c2e8..9a9d6ff48ab9c 100644 --- a/src/base_media_base.h +++ b/src/base_media_base.h @@ -289,7 +289,7 @@ enum MusicTrackType { /** Metadata about a music track. */ struct MusicSongInfo { - char songname[32]; ///< name of song displayed in UI + std::string songname; ///< name of song displayed in UI byte tracknr; ///< track number of song displayed in UI const char *filename; ///< file on disk containing song (when used in MusicSet class, this pointer is owned by MD5File object for the file) MusicTrackType filetype; ///< decoder required for song file diff --git a/src/base_media_func.h b/src/base_media_func.h index 9a24aa94e8ca6..d2c8bcdcd9dc9 100644 --- a/src/base_media_func.h +++ b/src/base_media_func.h @@ -15,6 +15,8 @@ #include "ini_type.h" #include "string_func.h" +extern void CheckExternalFiles(); + /** * Try to read a single piece of metadata and return false if it doesn't exist. * @param name the name of the item to fetch. @@ -48,7 +50,7 @@ bool BaseSet::FillSetDetails(IniFile *ini, const this->description[std::string{}] = *item->value; /* Add the translations of the descriptions too. */ - for (const IniItem *item = metadata->item; item != nullptr; item = item->next) { + for (item = metadata->item; item != nullptr; item = item->next) { if (item->name.compare(0, 12, "description.") != 0) continue; this->description[item->name.substr(12)] = item->value.value_or(""); @@ -227,8 +229,6 @@ bool BaseMedia::AddFile(const std::string &filename, size_t basepath_ template /* static */ bool BaseMedia::SetSet(const std::string &name) { - extern void CheckExternalFiles(); - if (name.empty()) { if (!BaseMedia::DetermineBestSet()) return false; CheckExternalFiles(); diff --git a/src/base_station_base.h b/src/base_station_base.h index 40543f1b8f6df..8550d3ec49376 100644 --- a/src/base_station_base.h +++ b/src/base_station_base.h @@ -24,6 +24,17 @@ struct StationSpecList { uint8 localidx; ///< Station ID within GRF of station }; +struct RoadStopSpecList { + const RoadStopSpec *spec; + uint32 grfid; ///< GRF ID of this custom road stop + uint8 localidx; ///< Station ID within GRF of road stop +}; + +struct RoadStopTileData { + TileIndex tile; + uint8 random_bits; + uint8 animation_frame; +}; /** StationRect - used to track station spread out rectangle - cheaper than scanning whole map */ struct StationRect : public Rect { @@ -62,19 +73,23 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> { Owner owner; ///< The owner of this station StationFacility facilities; ///< The facilities that this station has - uint8 num_specs; ///< Number of specs in the speclist - StationSpecList *speclist; ///< List of station specs of this station + std::vector speclist; ///< List of rail station specs of this station. + std::vector roadstop_speclist; ///< List of road stop specs of this station Date build_date; ///< Date of construction uint16 random_bits; ///< Random bits assigned to this station byte waiting_triggers; ///< Waiting triggers (NewGRF) for this station - uint8 cached_anim_triggers; ///< NOSAVE: Combined animation trigger bitmask, used to determine if trigger processing should happen. - CargoTypes cached_cargo_triggers; ///< NOSAVE: Combined cargo trigger bitmask + uint8 cached_anim_triggers; ///< NOSAVE: Combined animation trigger bitmask, used to determine if trigger processing should happen. + uint8 cached_roadstop_anim_triggers; ///< NOSAVE: Combined animation trigger bitmask for road stops, used to determine if trigger processing should happen. + CargoTypes cached_cargo_triggers; ///< NOSAVE: Combined cargo trigger bitmask + CargoTypes cached_roadstop_cargo_triggers; ///< NOSAVE: Combined cargo trigger bitmask for road stops TileArea train_station; ///< Tile area the train 'station' part covers StationRect rect; ///< NOSAVE: Station spread out rectangle maintained by StationRect::xxx() functions + std::vector custom_roadstop_tile_data; ///< List of custom road stop tile data + /** * Initialize the base station. * @param tile The location of the station sign @@ -168,6 +183,30 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> { return (this->facilities & ~FACIL_WAYPOINT) != 0; } + inline byte GetRoadStopRandomBits(TileIndex tile) const + { + for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) { + if (tile_data.tile == tile) return tile_data.random_bits; + } + return 0; + } + + inline byte GetRoadStopAnimationFrame(TileIndex tile) const + { + for (const RoadStopTileData &tile_data : this->custom_roadstop_tile_data) { + if (tile_data.tile == tile) return tile_data.animation_frame; + } + return 0; + } + +private: + void SetRoadStopTileData(TileIndex tile, byte data, bool animation); + +public: + inline void SetRoadStopRandomBits(TileIndex tile, byte random_bits) { this->SetRoadStopTileData(tile, random_bits, false); } + inline void SetRoadStopAnimationFrame(TileIndex tile, byte frame) { this->SetRoadStopTileData(tile, frame, true); } + void RemoveRoadStopTileData(TileIndex tile); + static void PostDestructor(size_t index); private: diff --git a/src/bitmap_type.h b/src/bitmap_type.h index 99c29bf181ffe..3aff86972460c 100644 --- a/src/bitmap_type.h +++ b/src/bitmap_type.h @@ -58,8 +58,8 @@ class BitmapTileArea : public TileArea { void Initialize(const Rect &r) { this->tile = TileXY(r.left, r.top); - this->w = r.right - r.left + 1; - this->h = r.bottom - r.top + 1; + this->w = r.Width(); + this->h = r.Height(); this->data.clear(); this->data.resize(Index(w, h)); } @@ -126,9 +126,9 @@ class BitmapTileIterator : public OrthogonalTileIterator { return *this; } - virtual TileIterator *Clone() const + virtual std::unique_ptr Clone() const { - return new BitmapTileIterator(*this); + return std::make_unique(*this); } }; diff --git a/src/blitter/32bpp_anim.cpp b/src/blitter/32bpp_anim.cpp index 370994c0669ff..ab6f984d61cf3 100644 --- a/src/blitter/32bpp_anim.cpp +++ b/src/blitter/32bpp_anim.cpp @@ -383,7 +383,7 @@ void Blitter_32bppAnim::CopyFromBuffer(void *video, const void *src, int width, dst += _screen.pitch; /* Copy back the anim-buffer */ memcpy(anim_line, usrc, width * sizeof(uint16)); - usrc = (const uint32 *)((const uint16 *)usrc + width); + usrc = (const uint32 *)&((const uint16 *)usrc)[width]; anim_line += this->anim_buf_pitch; /* Okay, it is *very* likely that the image we stored is using @@ -422,7 +422,7 @@ void Blitter_32bppAnim::CopyToBuffer(const void *video, void *dst, int width, in udst += width; /* Copy the anim-buffer */ memcpy(udst, anim_line, width * sizeof(uint16)); - udst = (uint32 *)((uint16 *)udst + width); + udst = (uint32 *)&((uint16 *)udst)[width]; anim_line += this->anim_buf_pitch; } } @@ -478,9 +478,9 @@ void Blitter_32bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt Blitter_32bppBase::ScrollBuffer(video, left, top, width, height, scroll_x, scroll_y); } -int Blitter_32bppAnim::BufferSize(int width, int height) +size_t Blitter_32bppAnim::BufferSize(uint width, uint height) { - return width * height * (sizeof(uint32) + sizeof(uint16)); + return (sizeof(uint32) + sizeof(uint16)) * width * height; } void Blitter_32bppAnim::PaletteAnimate(const Palette &palette) diff --git a/src/blitter/32bpp_anim.hpp b/src/blitter/32bpp_anim.hpp index 230b7e8342152..a0516d13c4b0f 100644 --- a/src/blitter/32bpp_anim.hpp +++ b/src/blitter/32bpp_anim.hpp @@ -43,7 +43,7 @@ class Blitter_32bppAnim : public Blitter_32bppOptimized { void CopyFromBuffer(void *video, const void *src, int width, int height) override; void CopyToBuffer(const void *video, void *dst, int width, int height) override; void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override; - int BufferSize(int width, int height) override; + size_t BufferSize(uint width, uint height) override; void PaletteAnimate(const Palette &palette) override; Blitter::PaletteAnimation UsePaletteAnimation() override; diff --git a/src/blitter/32bpp_anim_sse2.cpp b/src/blitter/32bpp_anim_sse2.cpp index ee243cc21ea64..117e6ec5c2a8c 100644 --- a/src/blitter/32bpp_anim_sse2.cpp +++ b/src/blitter/32bpp_anim_sse2.cpp @@ -19,6 +19,7 @@ /** Instantiation of the partially SSSE2 32bpp with animation blitter factory. */ static FBlitter_32bppSSE2_Anim iFBlitter_32bppSSE2_Anim; +GNU_TARGET("sse2") void Blitter_32bppSSE2_Anim::PaletteAnimate(const Palette &palette) { assert(!_screen_disable_anim); diff --git a/src/blitter/32bpp_anim_sse2.hpp b/src/blitter/32bpp_anim_sse2.hpp index 8b84f703e7f69..669cef80a74c9 100644 --- a/src/blitter/32bpp_anim_sse2.hpp +++ b/src/blitter/32bpp_anim_sse2.hpp @@ -16,6 +16,10 @@ #define SSE_VERSION 2 #endif +#ifndef SSE_TARGET +#define SSE_TARGET "sse2" +#endif + #ifndef FULL_ANIMATION #define FULL_ANIMATION 1 #endif diff --git a/src/blitter/32bpp_anim_sse4.cpp b/src/blitter/32bpp_anim_sse4.cpp index adfe625287157..93c9cb20c655a 100644 --- a/src/blitter/32bpp_anim_sse4.cpp +++ b/src/blitter/32bpp_anim_sse4.cpp @@ -29,6 +29,7 @@ static FBlitter_32bppSSE4_Anim iFBlitter_32bppSSE4_Anim; */ IGNORE_UNINITIALIZED_WARNING_START template +GNU_TARGET("sse4.1") inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom) { const byte * const remap = bp->remap; @@ -52,6 +53,7 @@ inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomL const __m128i a_cm = ALPHA_CONTROL_MASK; const __m128i pack_low_cm = PACK_LOW_CONTROL_MASK; const __m128i tr_nom_base = TRANSPARENT_NOM_BASE; + const __m128i a_am = ALPHA_AND_MASK; for (int y = bp->height; y != 0; y--) { Colour *dst = dst_line; @@ -143,7 +145,7 @@ inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomL /* Blend colours. */ bmno_alpha_blend: - srcABCD = AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm); + srcABCD = AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm, a_am); bmno_full_opacity: _mm_storel_epi64((__m128i *) dst, srcABCD); bmno_full_transparency: @@ -170,7 +172,7 @@ inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomL } else { srcABCD = _mm_cvtsi32_si128(src->data); } - dst->data = _mm_cvtsi128_si32(AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm)); + dst->data = _mm_cvtsi128_si32(AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm, a_am)); } } break; @@ -254,7 +256,7 @@ inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomL /* Blend colours. */ bmcr_alpha_blend: - srcABCD = AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm); + srcABCD = AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm, a_am); bmcr_full_opacity: _mm_storel_epi64((__m128i *) dst, srcABCD); bmcr_full_transparency: @@ -287,7 +289,7 @@ inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomL if (src->a < 255) { bmcr_alpha_blend_single: __m128i dstABCD = _mm_cvtsi32_si128(dst->data); - srcABCD = AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm); + srcABCD = AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm, a_am); } dst->data = _mm_cvtsi128_si32(srcABCD); } @@ -366,6 +368,12 @@ IGNORE_UNINITIALIZED_WARNING_STOP */ void Blitter_32bppSSE4_Anim::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) { + if (_screen_disable_anim) { + /* This means our output is not to the screen, so we can't be doing any animation stuff, so use our parent Draw() */ + Blitter_32bppSSE4::Draw(bp, mode, zoom); + return; + } + const Blitter_32bppSSE_Base::SpriteFlags sprite_flags = ((const Blitter_32bppSSE_Base::SpriteData *) bp->sprite)->flags; switch (mode) { default: { diff --git a/src/blitter/32bpp_anim_sse4.hpp b/src/blitter/32bpp_anim_sse4.hpp index 7674182a8f3f8..1b32e085c547e 100644 --- a/src/blitter/32bpp_anim_sse4.hpp +++ b/src/blitter/32bpp_anim_sse4.hpp @@ -16,6 +16,10 @@ #define SSE_VERSION 4 #endif +#ifndef SSE_TARGET +#define SSE_TARGET "sse4.1" +#endif + #ifndef FULL_ANIMATION #define FULL_ANIMATION 1 #endif @@ -28,7 +32,7 @@ #define MARGIN_NORMAL_THRESHOLD 4 /** The SSE4 32 bpp blitter with palette animation. */ -class Blitter_32bppSSE4_Anim FINAL : public Blitter_32bppSSE2_Anim, public Blitter_32bppSSE_Base { +class Blitter_32bppSSE4_Anim FINAL : public Blitter_32bppSSE2_Anim, public Blitter_32bppSSE4 { private: public: @@ -39,13 +43,14 @@ class Blitter_32bppSSE4_Anim FINAL : public Blitter_32bppSSE2_Anim, public Blitt return Blitter_32bppSSE_Base::Encode(sprite, allocator); } const char *GetName() override { return "32bpp-sse4-anim"; } + using Blitter_32bppSSE2_Anim::LookupColourInPalette; }; /** Factory for the SSE4 32 bpp blitter (with palette animation). */ class FBlitter_32bppSSE4_Anim: public BlitterFactory { public: FBlitter_32bppSSE4_Anim() : BlitterFactory("32bpp-sse4-anim", "32bpp SSE4 Blitter (palette animation)", HasCPUIDFlag(1, 2, 19)) {} - Blitter *CreateInstance() override { return new Blitter_32bppSSE4_Anim(); } + Blitter *CreateInstance() override { return static_cast(new Blitter_32bppSSE4_Anim()); } }; #endif /* WITH_SSE */ diff --git a/src/blitter/32bpp_base.cpp b/src/blitter/32bpp_base.cpp index 0678fce38f48b..744337631a1a1 100644 --- a/src/blitter/32bpp_base.cpp +++ b/src/blitter/32bpp_base.cpp @@ -140,9 +140,9 @@ void Blitter_32bppBase::ScrollBuffer(void *video, int &left, int &top, int &widt } } -int Blitter_32bppBase::BufferSize(int width, int height) +size_t Blitter_32bppBase::BufferSize(uint width, uint height) { - return width * height * sizeof(uint32); + return sizeof(uint32) * width * height; } void Blitter_32bppBase::PaletteAnimate(const Palette &palette) diff --git a/src/blitter/32bpp_base.hpp b/src/blitter/32bpp_base.hpp index 9d80ec2ce02d6..2a90602326a84 100644 --- a/src/blitter/32bpp_base.hpp +++ b/src/blitter/32bpp_base.hpp @@ -27,7 +27,7 @@ class Blitter_32bppBase : public Blitter { void CopyToBuffer(const void *video, void *dst, int width, int height) override; void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override; void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override; - int BufferSize(int width, int height) override; + size_t BufferSize(uint width, uint height) override; void PaletteAnimate(const Palette &palette) override; Blitter::PaletteAnimation UsePaletteAnimation() override; int GetBytesPerPixel() override { return 4; } diff --git a/src/blitter/32bpp_optimized.cpp b/src/blitter/32bpp_optimized.cpp index beafcff37f611..3eae7c4e48e49 100644 --- a/src/blitter/32bpp_optimized.cpp +++ b/src/blitter/32bpp_optimized.cpp @@ -316,8 +316,9 @@ template Sprite *Blitter_32bppOptimized::EncodeInternal(const const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *)src_orig->data; for (uint y = src_orig->height; y > 0; y--) { - Colour *dst_px = (Colour *)(dst_px_ln + 1); - uint16 *dst_n = (uint16 *)(dst_n_ln + 1); + /* Index 0 of dst_px and dst_n is left as space to save the length of the row to be filled later. */ + Colour *dst_px = (Colour *)&dst_px_ln[1]; + uint16 *dst_n = (uint16 *)&dst_n_ln[1]; uint16 *dst_len = dst_n++; diff --git a/src/blitter/32bpp_sse2.hpp b/src/blitter/32bpp_sse2.hpp index 12105516f813f..445fa97eb504a 100644 --- a/src/blitter/32bpp_sse2.hpp +++ b/src/blitter/32bpp_sse2.hpp @@ -16,6 +16,10 @@ #define SSE_VERSION 2 #endif +#ifndef SSE_TARGET +#define SSE_TARGET "sse2" +#endif + #ifndef FULL_ANIMATION #define FULL_ANIMATION 0 #endif diff --git a/src/blitter/32bpp_sse4.hpp b/src/blitter/32bpp_sse4.hpp index 7d44926b8867c..deb4fbed928cb 100644 --- a/src/blitter/32bpp_sse4.hpp +++ b/src/blitter/32bpp_sse4.hpp @@ -16,6 +16,10 @@ #define SSE_VERSION 4 #endif +#ifndef SSE_TARGET +#define SSE_TARGET "sse4.1" +#endif + #ifndef FULL_ANIMATION #define FULL_ANIMATION 0 #endif diff --git a/src/blitter/32bpp_sse_func.hpp b/src/blitter/32bpp_sse_func.hpp index d6e12af6193a0..e8d9c05061d12 100644 --- a/src/blitter/32bpp_sse_func.hpp +++ b/src/blitter/32bpp_sse_func.hpp @@ -12,6 +12,7 @@ #ifdef WITH_SSE +GNU_TARGET(SSE_TARGET) static inline void InsertFirstUint32(const uint32 value, __m128i &into) { #if (SSE_VERSION >= 4) @@ -22,6 +23,7 @@ static inline void InsertFirstUint32(const uint32 value, __m128i &into) #endif } +GNU_TARGET(SSE_TARGET) static inline void InsertSecondUint32(const uint32 value, __m128i &into) { #if (SSE_VERSION >= 4) @@ -32,6 +34,7 @@ static inline void InsertSecondUint32(const uint32 value, __m128i &into) #endif } +GNU_TARGET(SSE_TARGET) static inline void LoadUint64(const uint64 value, __m128i &into) { #ifdef POINTER_IS_64BIT @@ -46,6 +49,7 @@ static inline void LoadUint64(const uint64 value, __m128i &into) #endif } +GNU_TARGET(SSE_TARGET) static inline __m128i PackUnsaturated(__m128i from, const __m128i &mask) { #if (SSE_VERSION == 2) @@ -56,36 +60,43 @@ static inline __m128i PackUnsaturated(__m128i from, const __m128i &mask) #endif } +GNU_TARGET(SSE_TARGET) static inline __m128i DistributeAlpha(const __m128i from, const __m128i &mask) { #if (SSE_VERSION == 2) __m128i alphaAB = _mm_shufflelo_epi16(from, 0x3F); // PSHUFLW, put alpha1 in front of each rgb1 - return _mm_shufflehi_epi16(alphaAB, 0x3F); // PSHUFHW, put alpha2 in front of each rgb2 + alphaAB = _mm_shufflehi_epi16(alphaAB, 0x3F); // PSHUFHW, put alpha2 in front of each rgb2 + return _mm_andnot_si128(mask, alphaAB); // PANDN, set alpha fields to 0 #else return _mm_shuffle_epi8(from, mask); #endif } -static inline __m128i AlphaBlendTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &pack_mask) +GNU_TARGET(SSE_TARGET) +static inline __m128i AlphaBlendTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &pack_mask, const __m128i &alpha_mask) { __m128i srcAB = _mm_unpacklo_epi8(src, _mm_setzero_si128()); // PUNPCKLBW, expand each uint8 into uint16 __m128i dstAB = _mm_unpacklo_epi8(dst, _mm_setzero_si128()); - __m128i alphaAB = _mm_cmpgt_epi16(srcAB, _mm_setzero_si128()); // PCMPGTW, if (alpha > 0) a++; - alphaAB = _mm_srli_epi16(alphaAB, 15); - alphaAB = _mm_add_epi16(alphaAB, srcAB); + __m128i alphaMaskAB = _mm_cmpgt_epi16(srcAB, _mm_setzero_si128()); // PCMPGTW (alpha > 0) ? 0xFFFF : 0 + __m128i alphaAB = _mm_sub_epi16(srcAB, alphaMaskAB); // if (alpha > 0) a++; alphaAB = DistributeAlpha(alphaAB, distribution_mask); srcAB = _mm_sub_epi16(srcAB, dstAB); // PSUBW, (r - Cr) srcAB = _mm_mullo_epi16(srcAB, alphaAB); // PMULLW, a*(r - Cr) srcAB = _mm_srli_epi16(srcAB, 8); // PSRLW, a*(r - Cr)/256 srcAB = _mm_add_epi16(srcAB, dstAB); // PADDW, a*(r - Cr)/256 + Cr + + alphaMaskAB = _mm_and_si128(alphaMaskAB, alpha_mask); // PAND, set non alpha fields to 0 + srcAB = _mm_or_si128(srcAB, alphaMaskAB); // POR, set alpha fields to 0xFFFF is src alpha was > 0 + return PackUnsaturated(srcAB, pack_mask); } /* Darken 2 pixels. * rgb = rgb * ((256/4) * 4 - (alpha/4)) / ((256/4) * 4) */ +GNU_TARGET(SSE_TARGET) static inline __m128i DarkenTwoPixels(__m128i src, __m128i dst, const __m128i &distribution_mask, const __m128i &tr_nom_base) { __m128i srcAB = _mm_unpacklo_epi8(src, _mm_setzero_si128()); @@ -99,6 +110,7 @@ static inline __m128i DarkenTwoPixels(__m128i src, __m128i dst, const __m128i &d } IGNORE_UNINITIALIZED_WARNING_START +GNU_TARGET(SSE_TARGET) static Colour ReallyAdjustBrightness(Colour colour, uint8 brightness) { uint64 c16 = colour.b | (uint64) colour.g << 16 | (uint64) colour.r << 32; @@ -141,6 +153,7 @@ static inline Colour AdjustBrightneSSE(Colour colour, uint8 brightness) return ReallyAdjustBrightness(colour, brightness); } +GNU_TARGET(SSE_TARGET) static inline __m128i AdjustBrightnessOfTwoPixels(__m128i from, uint32 brightness) { #if (SSE_VERSION < 3) @@ -192,6 +205,7 @@ static inline __m128i AdjustBrightnessOfTwoPixels(__m128i from, uint32 brightnes */ IGNORE_UNINITIALIZED_WARNING_START template +GNU_TARGET(SSE_TARGET) #if (SSE_VERSION == 2) inline void Blitter_32bppSSE2::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom) #elif (SSE_VERSION == 3) @@ -217,9 +231,11 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel const MapValue *src_mv = src_mv_line; /* Load these variables into register before loop. */ + const __m128i alpha_and = ALPHA_AND_MASK; + #define ALPHA_BLEND_PARAM_3 alpha_and #if (SSE_VERSION == 2) const __m128i clear_hi = CLEAR_HIGH_BYTE_MASK; - #define ALPHA_BLEND_PARAM_1 clear_hi + #define ALPHA_BLEND_PARAM_1 alpha_and #define ALPHA_BLEND_PARAM_2 clear_hi #define DARKEN_PARAM_1 tr_nom_base #define DARKEN_PARAM_2 tr_nom_base @@ -265,7 +281,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel for (uint x = (uint) effective_width / 2; x > 0; x--) { __m128i srcABCD = _mm_loadl_epi64((const __m128i*) src); __m128i dstABCD = _mm_loadl_epi64((__m128i*) dst); - _mm_storel_epi64((__m128i*) dst, AlphaBlendTwoPixels(srcABCD, dstABCD, ALPHA_BLEND_PARAM_1, ALPHA_BLEND_PARAM_2)); + _mm_storel_epi64((__m128i*) dst, AlphaBlendTwoPixels(srcABCD, dstABCD, ALPHA_BLEND_PARAM_1, ALPHA_BLEND_PARAM_2, ALPHA_BLEND_PARAM_3)); src += 2; dst += 2; } @@ -273,7 +289,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) { __m128i srcABCD = _mm_cvtsi32_si128(src->data); __m128i dstABCD = _mm_cvtsi32_si128(dst->data); - dst->data = _mm_cvtsi128_si32(AlphaBlendTwoPixels(srcABCD, dstABCD, ALPHA_BLEND_PARAM_1, ALPHA_BLEND_PARAM_2)); + dst->data = _mm_cvtsi128_si32(AlphaBlendTwoPixels(srcABCD, dstABCD, ALPHA_BLEND_PARAM_1, ALPHA_BLEND_PARAM_2, ALPHA_BLEND_PARAM_3)); } break; @@ -318,7 +334,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel } /* Blend colours. */ - _mm_storel_epi64((__m128i *) dst, AlphaBlendTwoPixels(srcABCD, dstABCD, ALPHA_BLEND_PARAM_1, ALPHA_BLEND_PARAM_2)); + _mm_storel_epi64((__m128i *) dst, AlphaBlendTwoPixels(srcABCD, dstABCD, ALPHA_BLEND_PARAM_1, ALPHA_BLEND_PARAM_2, ALPHA_BLEND_PARAM_3)); dst += 2; src += 2; src_mv += 2; @@ -347,7 +363,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel if (src->a < 255) { bmcr_alpha_blend_single: __m128i dstABCD = _mm_cvtsi32_si128(dst->data); - srcABCD = AlphaBlendTwoPixels(srcABCD, dstABCD, ALPHA_BLEND_PARAM_1, ALPHA_BLEND_PARAM_2); + srcABCD = AlphaBlendTwoPixels(srcABCD, dstABCD, ALPHA_BLEND_PARAM_1, ALPHA_BLEND_PARAM_2, ALPHA_BLEND_PARAM_3); } dst->data = _mm_cvtsi128_si32(srcABCD); } diff --git a/src/blitter/32bpp_sse_type.h b/src/blitter/32bpp_sse_type.h index 33c76d9b4d394..fe91b294bede3 100644 --- a/src/blitter/32bpp_sse_type.h +++ b/src/blitter/32bpp_sse_type.h @@ -51,6 +51,7 @@ typedef union ALIGN(16) um128i { #define OVERBRIGHT_VALUE_MASK _mm_setr_epi8(-1, 0, -1, 0, -1, 0, 0, 0, -1, 0, -1, 0, -1, 0, 0, 0) #define OVERBRIGHT_CONTROL_MASK _mm_setr_epi8( 0, 1, 0, 1, 0, 1, 7, 7, 2, 3, 2, 3, 2, 3, 7, 7) #define TRANSPARENT_NOM_BASE _mm_setr_epi16(256, 256, 256, 256, 256, 256, 256, 256) +#define ALPHA_AND_MASK _mm_setr_epi16( 0, 0, 0, -1, 0, 0, 0, -1) #endif /* WITH_SSE */ #endif /* BLITTER_32BPP_SSE_TYPE_H */ diff --git a/src/blitter/32bpp_ssse3.hpp b/src/blitter/32bpp_ssse3.hpp index cc710ed05bfa9..c95095d4df49f 100644 --- a/src/blitter/32bpp_ssse3.hpp +++ b/src/blitter/32bpp_ssse3.hpp @@ -16,6 +16,10 @@ #define SSE_VERSION 3 #endif +#ifndef SSE_TARGET +#define SSE_TARGET "ssse3" +#endif + #ifndef FULL_ANIMATION #define FULL_ANIMATION 0 #endif diff --git a/src/blitter/40bpp_anim.cpp b/src/blitter/40bpp_anim.cpp index d29b34a17962f..c0b9568ebd32b 100644 --- a/src/blitter/40bpp_anim.cpp +++ b/src/blitter/40bpp_anim.cpp @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * 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. @@ -33,9 +31,10 @@ void Blitter_40bppAnim::SetPixel(void *video, int x, int y, uint8 colour) if (_screen_disable_anim) { Blitter_32bppOptimized::SetPixel(video, x, y, colour); } else { - *((Colour *)video + x + y * _screen.pitch) = _black_colour; + size_t y_offset = static_cast(y) * _screen.pitch; + *((Colour *)video + x + y_offset) = _black_colour; - VideoDriver::GetInstance()->GetAnimBuffer()[((uint32 *)video - (uint32 *)_screen.dst_ptr) + x + y * _screen.pitch] = colour; + VideoDriver::GetInstance()->GetAnimBuffer()[((uint32 *)video - (uint32 *)_screen.dst_ptr) + x + y_offset] = colour; } } @@ -502,9 +501,9 @@ void Blitter_40bppAnim::ScrollBuffer(void *video, int &left, int &top, int &widt Blitter_32bppBase::ScrollBuffer(video, left, top, width, height, scroll_x, scroll_y); } -int Blitter_40bppAnim::BufferSize(int width, int height) +size_t Blitter_40bppAnim::BufferSize(uint width, uint height) { - return width * height * (sizeof(uint32) + sizeof(uint8)); + return (sizeof(uint32) + sizeof(uint8)) * width * height; } Blitter::PaletteAnimation Blitter_40bppAnim::UsePaletteAnimation() diff --git a/src/blitter/40bpp_anim.hpp b/src/blitter/40bpp_anim.hpp index c0bea15ae03e4..c530889f493e1 100644 --- a/src/blitter/40bpp_anim.hpp +++ b/src/blitter/40bpp_anim.hpp @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * 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. @@ -20,7 +18,6 @@ class Blitter_40bppAnim : public Blitter_32bppOptimized { public: - // void *MoveTo(void *video, int x, int y) override; void SetPixel(void *video, int x, int y, uint8 colour) override; void DrawRect(void *video, int width, int height, uint8 colour) override; void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) override; @@ -31,7 +28,7 @@ class Blitter_40bppAnim : public Blitter_32bppOptimized { void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override; Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override; - int BufferSize(int width, int height) override; + size_t BufferSize(uint width, uint height) override; Blitter::PaletteAnimation UsePaletteAnimation() override; bool NeedsAnimationBuffer() override; diff --git a/src/blitter/8bpp_base.cpp b/src/blitter/8bpp_base.cpp index 501ffc64e5c46..2b608c246cf28 100644 --- a/src/blitter/8bpp_base.cpp +++ b/src/blitter/8bpp_base.cpp @@ -144,9 +144,9 @@ void Blitter_8bppBase::ScrollBuffer(void *video, int &left, int &top, int &width } } -int Blitter_8bppBase::BufferSize(int width, int height) +size_t Blitter_8bppBase::BufferSize(uint width, uint height) { - return width * height; + return static_cast(width) * height; } void Blitter_8bppBase::PaletteAnimate(const Palette &palette) diff --git a/src/blitter/8bpp_base.hpp b/src/blitter/8bpp_base.hpp index f6f67ad1a65cf..8bbbc3a9eeb3c 100644 --- a/src/blitter/8bpp_base.hpp +++ b/src/blitter/8bpp_base.hpp @@ -25,7 +25,7 @@ class Blitter_8bppBase : public Blitter { void CopyToBuffer(const void *video, void *dst, int width, int height) override; void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override; void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override; - int BufferSize(int width, int height) override; + size_t BufferSize(uint width, uint height) override; void PaletteAnimate(const Palette &palette) override; Blitter::PaletteAnimation UsePaletteAnimation() override; int GetBytesPerPixel() override { return 1; } diff --git a/src/blitter/CMakeLists.txt b/src/blitter/CMakeLists.txt index ddcc9a0082a80..50faefbc1c079 100644 --- a/src/blitter/CMakeLists.txt +++ b/src/blitter/CMakeLists.txt @@ -38,21 +38,6 @@ add_files( CONDITION NOT OPTION_DEDICATED AND OPENGL_FOUND ) - -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") - set_compile_flags( - 32bpp_anim_sse2.cpp - 32bpp_sse2.cpp - COMPILE_FLAGS -msse2) - set_compile_flags( - 32bpp_ssse3.cpp - COMPILE_FLAGS -mssse3) - set_compile_flags( - 32bpp_anim_sse4.cpp - 32bpp_sse4.cpp - COMPILE_FLAGS -msse4.1) -endif() - add_files( base.hpp common.hpp diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp index 4ec25c38dd9c4..f33b99ba2e681 100644 --- a/src/blitter/base.hpp +++ b/src/blitter/base.hpp @@ -170,7 +170,7 @@ class Blitter : public SpriteEncoder { * @param height The height of the buffer-to-be. * @return The size needed for the buffer. */ - virtual int BufferSize(int width, int height) = 0; + virtual size_t BufferSize(uint width, uint height) = 0; /** * Called when the 8bpp palette is changed; you should redraw all pixels on the screen that diff --git a/src/blitter/null.hpp b/src/blitter/null.hpp index 7d5a672c56c6c..9810a7b51aa89 100644 --- a/src/blitter/null.hpp +++ b/src/blitter/null.hpp @@ -27,7 +27,7 @@ class Blitter_Null : public Blitter { void CopyToBuffer(const void *video, void *dst, int width, int height) override {}; void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) override {}; void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) override {}; - int BufferSize(int width, int height) override { return 0; }; + size_t BufferSize(uint width, uint height) override { return 0; }; void PaletteAnimate(const Palette &palette) override { }; Blitter::PaletteAnimation UsePaletteAnimation() override { return Blitter::PALETTE_ANIMATION_NONE; }; diff --git a/src/bmp.cpp b/src/bmp.cpp index 2877d01470250..70e86ee014f30 100644 --- a/src/bmp.cpp +++ b/src/bmp.cpp @@ -367,7 +367,12 @@ bool BmpReadHeader(BmpBuffer *buffer, BmpInfo *info, BmpData *data) info->palette_size = ReadDword(buffer); // number of colours in palette SkipBytes(buffer, header_size - 16); // skip the end of info header } - if (info->palette_size == 0) info->palette_size = 1 << info->bpp; + + uint maximum_palette_size = 1U << info->bpp; + if (info->palette_size == 0) info->palette_size = maximum_palette_size; + + /* More palette colours than palette indices is not supported. */ + if (info->palette_size > maximum_palette_size) return false; data->palette = CallocT(info->palette_size); @@ -390,7 +395,7 @@ bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data) { assert(info != nullptr && data != nullptr); - data->bitmap = CallocT(info->width * info->height * ((info->bpp == 24) ? 3 : 1)); + data->bitmap = CallocT(static_cast(info->width) * info->height * ((info->bpp == 24) ? 3 : 1)); /* Load image */ SetStreamOffset(buffer, info->offset); diff --git a/src/bootstrap_gui.cpp b/src/bootstrap_gui.cpp index d8e4aedec9827..a1ae02acf6de1 100644 --- a/src/bootstrap_gui.cpp +++ b/src/bootstrap_gui.cpp @@ -101,14 +101,14 @@ class BootstrapErrorWindow : public Window { { if (widget == WID_BEM_MESSAGE) { *size = GetStringBoundingBox(STR_MISSING_GRAPHICS_ERROR); - size->height = GetStringHeight(STR_MISSING_GRAPHICS_ERROR, size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT) + WD_FRAMETEXT_BOTTOM + WD_FRAMETEXT_TOP; + size->height = GetStringHeight(STR_MISSING_GRAPHICS_ERROR, size->width - WidgetDimensions::scaled.frametext.Horizontal()) + WidgetDimensions::scaled.frametext.Vertical(); } } void DrawWidget(const Rect &r, int widget) const override { if (widget == WID_BEM_MESSAGE) { - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMETEXT_BOTTOM, STR_MISSING_GRAPHICS_ERROR, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.frametext), STR_MISSING_GRAPHICS_ERROR, TC_FROMSTRING, SA_CENTER); } } @@ -123,8 +123,11 @@ class BootstrapErrorWindow : public Window { /** Nested widgets for the download window. */ static const NWidgetPart _nested_bootstrap_download_status_window_widgets[] = { NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_CONTENT_DOWNLOAD_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_PANEL, COLOUR_GREY, WID_NCDS_BACKGROUND), - NWidget(NWID_SPACER), SetMinimalSize(350, 0), SetMinimalTextLines(3, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 30), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NCDS_PROGRESS_BAR), SetFill(1, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NCDS_PROGRESS_TEXT), SetFill(1, 0), SetMinimalSize(350, 0), + EndContainer(), EndContainer(), }; @@ -214,15 +217,15 @@ class BootstrapAskForDownloadWindow : public Window, ContentCallback { /* We cache the button size. This is safe as no reinit can happen here. */ if (this->button_size.width == 0) { this->button_size = maxdim(GetStringBoundingBox(STR_MISSING_GRAPHICS_YES_DOWNLOAD), GetStringBoundingBox(STR_MISSING_GRAPHICS_NO_QUIT)); - this->button_size.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; - this->button_size.height += WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM; + this->button_size.width += WidgetDimensions::scaled.frametext.Horizontal(); + this->button_size.height += WidgetDimensions::scaled.frametext.Vertical(); } switch (widget) { case WID_BAFD_QUESTION: /* The question is twice as wide as the buttons, and determine the height based on the width. */ size->width = this->button_size.width * 2; - size->height = GetStringHeight(STR_MISSING_GRAPHICS_SET_MESSAGE, size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT) + WD_FRAMETEXT_BOTTOM + WD_FRAMETEXT_TOP; + size->height = GetStringHeight(STR_MISSING_GRAPHICS_SET_MESSAGE, size->width - WidgetDimensions::scaled.frametext.Horizontal()) + WidgetDimensions::scaled.frametext.Vertical(); break; case WID_BAFD_YES: @@ -236,7 +239,7 @@ class BootstrapAskForDownloadWindow : public Window, ContentCallback { { if (widget != 0) return; - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMETEXT_BOTTOM, STR_MISSING_GRAPHICS_SET_MESSAGE, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.frametext), STR_MISSING_GRAPHICS_SET_MESSAGE, TC_FROMSTRING, SA_CENTER); } void OnClick(Point pt, int widget, int click_count) override @@ -286,16 +289,16 @@ bool HandleBootstrap() /* No user interface, bail out with an error. */ if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) goto failure; - /* If there is no network or no freetype, then there is nothing we can do. Go straight to failure. */ + /* If there is no network or no non-sprite font, then there is nothing we can do. Go straight to failure. */ #if (defined(_WIN32) && defined(WITH_UNISCRIBE)) || (defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(__APPLE__))) || defined(WITH_COCOA) if (!_network_available) goto failure; /* First tell the game we're bootstrapping. */ _game_mode = GM_BOOTSTRAP; - /* Initialise the freetype font code. */ + /* Initialise the font cache. */ InitializeUnicodeGlyphMap(); - /* Next "force" finding a suitable freetype font as the local font is missing. */ + /* Next "force" finding a suitable non-sprite font as the local font is missing. */ CheckForMissingGlyphs(false); /* Initialise the palette. The biggest step is 'faking' some recolour sprites. diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp index 515a9318c376b..62f4c96b9bc6f 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -130,6 +130,23 @@ class BuildBridgeWindow : public Window { this->SetWidgetDirty(WID_BBS_BRIDGE_LIST); } + /** + * Get the StringID to draw in the selection list and set the appropriate DParams. + * @param bridge_data the bridge to get the StringID of. + * @return the StringID. + */ + StringID GetBridgeSelectString(const BuildBridgeData &bridge_data) const + { + SetDParam(0, bridge_data.spec->material); + SetDParam(1, bridge_data.spec->speed); + SetDParam(2, bridge_data.cost); + /* If the bridge has no meaningful speed limit, don't display it. */ + if (bridge_data.spec->speed == UINT16_MAX) { + return _game_mode == GM_EDITOR ? STR_SELECT_BRIDGE_INFO_NAME : STR_SELECT_BRIDGE_INFO_NAME_COST; + } + return _game_mode == GM_EDITOR ? STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED : STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST; + } + public: BuildBridgeWindow(WindowDesc *desc, TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type, GUIBridgeList *bl) : Window(desc), start_tile(start), @@ -183,21 +200,16 @@ class BuildBridgeWindow : public Window { case WID_BBS_BRIDGE_LIST: { Dimension sprite_dim = {0, 0}; // Biggest bridge sprite dimension Dimension text_dim = {0, 0}; // Biggest text dimension - for (int i = 0; i < (int)this->bridges->size(); i++) { - const BridgeSpec *b = this->bridges->at(i).spec; - sprite_dim = maxdim(sprite_dim, GetSpriteSize(b->sprite)); - - SetDParam(2, this->bridges->at(i).cost); - SetDParam(1, b->speed); - SetDParam(0, b->material); - text_dim = maxdim(text_dim, GetStringBoundingBox(_game_mode == GM_EDITOR ? STR_SELECT_BRIDGE_SCENEDIT_INFO : STR_SELECT_BRIDGE_INFO)); + for (const BuildBridgeData &bridge_data : *this->bridges) { + sprite_dim = maxdim(sprite_dim, GetSpriteSize(bridge_data.spec->sprite)); + text_dim = maxdim(text_dim, GetStringBoundingBox(GetBridgeSelectString(bridge_data))); } sprite_dim.height++; // Sprite is rendered one pixel down in the matrix field. text_dim.height++; // Allowing the bottom row pixels to be rendered on the edge of the matrix field. - resize->height = std::max(sprite_dim.height, text_dim.height) + 2; // Max of both sizes + account for matrix edges. + resize->height = std::max(sprite_dim.height, text_dim.height) + padding.height; // Max of both sizes + account for matrix edges. - this->bridgetext_offset = WD_MATRIX_LEFT + sprite_dim.width + 1; // Left edge of text, 1 pixel distance from the sprite. - size->width = this->bridgetext_offset + text_dim.width + WD_MATRIX_RIGHT; + this->bridgetext_offset = sprite_dim.width + WidgetDimensions::scaled.hsep_normal; // Left edge of text, 1 pixel distance from the sprite. + size->width = this->bridgetext_offset + text_dim.width + padding.width; size->height = 4 * resize->height; // Smallest bridge gui is 4 entries high in the matrix. break; } @@ -222,18 +234,13 @@ class BuildBridgeWindow : public Window { break; case WID_BBS_BRIDGE_LIST: { - uint y = r.top; + Rect tr = r.WithHeight(this->resize.step_height).Shrink(WidgetDimensions::scaled.matrix); for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < (int)this->bridges->size(); i++) { - const BridgeSpec *b = this->bridges->at(i).spec; - - SetDParam(2, this->bridges->at(i).cost); - SetDParam(1, b->speed); - SetDParam(0, b->material); - - DrawSprite(b->sprite, b->pal, r.left + WD_MATRIX_LEFT, y + this->resize.step_height - 1 - GetSpriteSize(b->sprite).height); - DrawStringMultiLine(r.left + this->bridgetext_offset, r.right, y + 2, y + this->resize.step_height, - _game_mode == GM_EDITOR ? STR_SELECT_BRIDGE_SCENEDIT_INFO : STR_SELECT_BRIDGE_INFO); - y += this->resize.step_height; + const BuildBridgeData &bridge_data = this->bridges->at(i); + const BridgeSpec *b = bridge_data.spec; + DrawSprite(b->sprite, b->pal, tr.left, tr.bottom - GetSpriteSize(b->sprite).height); + DrawStringMultiLine(tr.Indent(this->bridgetext_offset, false), GetBridgeSelectString(bridge_data)); + tr = tr.Translate(0, this->resize.step_height); } break; } diff --git a/src/bridge_map.h b/src/bridge_map.h index 575af60470a3a..317ebdd6f02f2 100644 --- a/src/bridge_map.h +++ b/src/bridge_map.h @@ -21,10 +21,10 @@ * @pre IsTileType(t, MP_TUNNELBRIDGE) * @return true if the structure is a bridge one */ -static inline bool IsBridge(TileIndex t) +static inline bool IsBridge(Tile t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); - return HasBit(_m[t].m5, 7); + return HasBit(t.m5(), 7); } /** @@ -32,7 +32,7 @@ static inline bool IsBridge(TileIndex t) * @param t The tile to analyze * @return true if a bridge is present */ -static inline bool IsBridgeTile(TileIndex t) +static inline bool IsBridgeTile(Tile t) { return IsTileType(t, MP_TUNNELBRIDGE) && IsBridge(t); } @@ -42,9 +42,9 @@ static inline bool IsBridgeTile(TileIndex t) * @param t The tile to analyze * @return true if a bridge is detected above */ -static inline bool IsBridgeAbove(TileIndex t) +static inline bool IsBridgeAbove(Tile t) { - return GB(_m[t].type, 2, 2) != 0; + return GB(t.type(), 2, 2) != 0; } /** @@ -53,10 +53,10 @@ static inline bool IsBridgeAbove(TileIndex t) * @pre IsBridgeTile(t) * @return The bridge type */ -static inline BridgeType GetBridgeType(TileIndex t) +static inline BridgeType GetBridgeType(Tile t) { assert(IsBridgeTile(t)); - return GB(_me[t].m6, 2, 4); + return GB(t.m6(), 2, 4); } /** @@ -65,10 +65,10 @@ static inline BridgeType GetBridgeType(TileIndex t) * @pre IsBridgeAbove(t) * @return the above mentioned axis */ -static inline Axis GetBridgeAxis(TileIndex t) +static inline Axis GetBridgeAxis(Tile t) { assert(IsBridgeAbove(t)); - return (Axis)(GB(_m[t].type, 2, 2) - 1); + return (Axis)(GB(t.type(), 2, 2) - 1); } TileIndex GetNorthernBridgeEnd(TileIndex t); @@ -91,16 +91,16 @@ static inline int GetBridgePixelHeight(TileIndex tile) * @param t the tile to remove the bridge from * @param a the axis of the bridge to remove */ -static inline void ClearSingleBridgeMiddle(TileIndex t, Axis a) +static inline void ClearSingleBridgeMiddle(Tile t, Axis a) { - ClrBit(_m[t].type, 2 + a); + ClrBit(t.type(), 2 + a); } /** * Removes bridges from the given, that is bridges along the X and Y axis. * @param t the tile to remove the bridge from */ -static inline void ClearBridgeMiddle(TileIndex t) +static inline void ClearBridgeMiddle(Tile t) { ClearSingleBridgeMiddle(t, AXIS_X); ClearSingleBridgeMiddle(t, AXIS_Y); @@ -111,9 +111,9 @@ static inline void ClearBridgeMiddle(TileIndex t) * @param t the tile to add the bridge to * @param a the axis of the bridge to add */ -static inline void SetBridgeMiddle(TileIndex t, Axis a) +static inline void SetBridgeMiddle(Tile t, Axis a) { - SetBit(_m[t].type, 2 + a); + SetBit(t.type(), 2 + a); } /** @@ -125,18 +125,18 @@ static inline void SetBridgeMiddle(TileIndex t, Axis a) * @param tt the transport type of the bridge * @note this function should not be called directly. */ -static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, DiagDirection d, TransportType tt) +static inline void MakeBridgeRamp(Tile t, Owner o, BridgeType bridgetype, DiagDirection d, TransportType tt) { SetTileType(t, MP_TUNNELBRIDGE); SetTileOwner(t, o); SetDockingTile(t, false); - _m[t].m2 = 0; - _m[t].m3 = 0; - _m[t].m4 = INVALID_ROADTYPE; - _m[t].m5 = 1 << 7 | tt << 2 | d; - SB(_me[t].m6, 2, 4, bridgetype); - _me[t].m7 = 0; - _me[t].m8 = INVALID_ROADTYPE << 6; + t.m2() = 0; + t.m3() = 0; + t.m4() = INVALID_ROADTYPE; + t.m5() = 1 << 7 | tt << 2 | d; + SB(t.m6(), 2, 4, bridgetype); + t.m7() = 0; + t.m8() = INVALID_ROADTYPE << 6; } /** @@ -150,7 +150,7 @@ static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, D * @param road_rt the road type of the bridge * @param tram_rt the tram type of the bridge */ -static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, Owner owner_road, Owner owner_tram, BridgeType bridgetype, DiagDirection d, RoadType road_rt, RoadType tram_rt) +static inline void MakeRoadBridgeRamp(Tile t, Owner o, Owner owner_road, Owner owner_tram, BridgeType bridgetype, DiagDirection d, RoadType road_rt, RoadType tram_rt) { MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD); SetRoadOwner(t, RTT_ROAD, owner_road); @@ -166,7 +166,7 @@ static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, Owner owner_road, Ow * @param d the direction this ramp must be facing * @param rt the rail type of the bridge */ -static inline void MakeRailBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, DiagDirection d, RailType rt) +static inline void MakeRailBridgeRamp(Tile t, Owner o, BridgeType bridgetype, DiagDirection d, RailType rt) { MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL); SetRailType(t, rt); @@ -178,7 +178,7 @@ static inline void MakeRailBridgeRamp(TileIndex t, Owner o, BridgeType bridgetyp * @param o the new owner of the bridge ramp * @param d the direction this ramp must be facing */ -static inline void MakeAqueductBridgeRamp(TileIndex t, Owner o, DiagDirection d) +static inline void MakeAqueductBridgeRamp(Tile t, Owner o, DiagDirection d) { MakeBridgeRamp(t, o, 0, d, TRANSPORT_WATER); } diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 04392c9b03963..b0d5d62e55ddd 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.cpp @@ -33,6 +33,7 @@ #include "engine_cmd.h" #include "train_cmd.h" #include "vehicle_cmd.h" +#include "zoom_func.h" #include "widgets/build_vehicle_widget.h" @@ -47,7 +48,7 @@ */ uint GetEngineListHeight(VehicleType type) { - return std::max(FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM, GetVehicleImageCellSize(type, EIT_PURCHASE).height); + return std::max(FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.matrix.Vertical(), GetVehicleImageCellSize(type, EIT_PURCHASE).height); } static const NWidgetPart _nested_build_vehicle_widgets[] = { @@ -105,9 +106,9 @@ static CargoID _engine_sort_last_cargo_criteria[] = {CF_ANY, CF_ANY, CF_ANY, CF_ * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool EngineNumberSorter(const EngineID &a, const EngineID &b) +static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - int r = Engine::Get(a)->list_position - Engine::Get(b)->list_position; + int r = Engine::Get(a.engine_id)->list_position - Engine::Get(b.engine_id)->list_position; return _engine_sort_direction ? r > 0 : r < 0; } @@ -118,10 +119,10 @@ static bool EngineNumberSorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool EngineIntroDateSorter(const EngineID &a, const EngineID &b) +static bool EngineIntroDateSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - const int va = Engine::Get(a)->intro_date; - const int vb = Engine::Get(b)->intro_date; + const int va = Engine::Get(a.engine_id)->intro_date; + const int vb = Engine::Get(b.engine_id)->intro_date; const int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ @@ -138,19 +139,20 @@ static EngineID _last_engine[2] = { INVALID_ENGINE, INVALID_ENGINE }; * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool EngineNameSorter(const EngineID &a, const EngineID &b) +static bool EngineNameSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { static char last_name[2][64] = { "", "" }; - if (a != _last_engine[0]) { - _last_engine[0] = a; - SetDParam(0, a); + if (a.engine_id != _last_engine[0]) { + _last_engine[0] = a.engine_id; + SetDParam(0, PackEngineNameDParam(a.engine_id, EngineNameContext::PurchaseList)); + GetString(last_name[0], STR_ENGINE_NAME, lastof(last_name[0])); } - if (b != _last_engine[1]) { - _last_engine[1] = b; - SetDParam(0, b); + if (b.engine_id != _last_engine[1]) { + _last_engine[1] = b.engine_id; + SetDParam(0, PackEngineNameDParam(b.engine_id, EngineNameContext::PurchaseList)); GetString(last_name[1], STR_ENGINE_NAME, lastof(last_name[1])); } @@ -167,10 +169,10 @@ static bool EngineNameSorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool EngineReliabilitySorter(const EngineID &a, const EngineID &b) +static bool EngineReliabilitySorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - const int va = Engine::Get(a)->reliability; - const int vb = Engine::Get(b)->reliability; + const int va = Engine::Get(a.engine_id)->reliability; + const int vb = Engine::Get(b.engine_id)->reliability; const int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ @@ -184,10 +186,10 @@ static bool EngineReliabilitySorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool EngineCostSorter(const EngineID &a, const EngineID &b) +static bool EngineCostSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - Money va = Engine::Get(a)->GetCost(); - Money vb = Engine::Get(b)->GetCost(); + Money va = Engine::Get(a.engine_id)->GetCost(); + Money vb = Engine::Get(b.engine_id)->GetCost(); int r = ClampToI32(va - vb); /* Use EngineID to sort instead since we want consistent sorting */ @@ -201,10 +203,10 @@ static bool EngineCostSorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool EngineSpeedSorter(const EngineID &a, const EngineID &b) +static bool EngineSpeedSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - int va = Engine::Get(a)->GetDisplayMaxSpeed(); - int vb = Engine::Get(b)->GetDisplayMaxSpeed(); + int va = Engine::Get(a.engine_id)->GetDisplayMaxSpeed(); + int vb = Engine::Get(b.engine_id)->GetDisplayMaxSpeed(); int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ @@ -218,10 +220,10 @@ static bool EngineSpeedSorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool EnginePowerSorter(const EngineID &a, const EngineID &b) +static bool EnginePowerSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - int va = Engine::Get(a)->GetPower(); - int vb = Engine::Get(b)->GetPower(); + int va = Engine::Get(a.engine_id)->GetPower(); + int vb = Engine::Get(b.engine_id)->GetPower(); int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ @@ -235,10 +237,10 @@ static bool EnginePowerSorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool EngineTractiveEffortSorter(const EngineID &a, const EngineID &b) +static bool EngineTractiveEffortSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - int va = Engine::Get(a)->GetDisplayMaxTractiveEffort(); - int vb = Engine::Get(b)->GetDisplayMaxTractiveEffort(); + int va = Engine::Get(a.engine_id)->GetDisplayMaxTractiveEffort(); + int vb = Engine::Get(b.engine_id)->GetDisplayMaxTractiveEffort(); int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ @@ -252,10 +254,10 @@ static bool EngineTractiveEffortSorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool EngineRunningCostSorter(const EngineID &a, const EngineID &b) +static bool EngineRunningCostSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - Money va = Engine::Get(a)->GetRunningCost(); - Money vb = Engine::Get(b)->GetRunningCost(); + Money va = Engine::Get(a.engine_id)->GetRunningCost(); + Money vb = Engine::Get(b.engine_id)->GetRunningCost(); int r = ClampToI32(va - vb); /* Use EngineID to sort instead since we want consistent sorting */ @@ -269,10 +271,10 @@ static bool EngineRunningCostSorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool EnginePowerVsRunningCostSorter(const EngineID &a, const EngineID &b) +static bool EnginePowerVsRunningCostSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - const Engine *e_a = Engine::Get(a); - const Engine *e_b = Engine::Get(b); + const Engine *e_a = Engine::Get(a.engine_id); + const Engine *e_b = Engine::Get(b.engine_id); uint p_a = e_a->GetPower(); uint p_b = e_b->GetPower(); Money r_a = e_a->GetRunningCost(); @@ -311,13 +313,13 @@ static bool EnginePowerVsRunningCostSorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool TrainEngineCapacitySorter(const EngineID &a, const EngineID &b) +static bool TrainEngineCapacitySorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - const RailVehicleInfo *rvi_a = RailVehInfo(a); - const RailVehicleInfo *rvi_b = RailVehInfo(b); + const RailVehicleInfo *rvi_a = RailVehInfo(a.engine_id); + const RailVehicleInfo *rvi_b = RailVehInfo(b.engine_id); - int va = GetTotalCapacityOfArticulatedParts(a) * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1); - int vb = GetTotalCapacityOfArticulatedParts(b) * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1); + int va = GetTotalCapacityOfArticulatedParts(a.engine_id) * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1); + int vb = GetTotalCapacityOfArticulatedParts(b.engine_id) * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1); int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ @@ -331,10 +333,10 @@ static bool TrainEngineCapacitySorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool TrainEnginesThenWagonsSorter(const EngineID &a, const EngineID &b) +static bool TrainEnginesThenWagonsSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - int val_a = (RailVehInfo(a)->railveh_type == RAILVEH_WAGON ? 1 : 0); - int val_b = (RailVehInfo(b)->railveh_type == RAILVEH_WAGON ? 1 : 0); + int val_a = (RailVehInfo(a.engine_id)->railveh_type == RAILVEH_WAGON ? 1 : 0); + int val_b = (RailVehInfo(b.engine_id)->railveh_type == RAILVEH_WAGON ? 1 : 0); int r = val_a - val_b; /* Use EngineID to sort instead since we want consistent sorting */ @@ -350,10 +352,10 @@ static bool TrainEnginesThenWagonsSorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool RoadVehEngineCapacitySorter(const EngineID &a, const EngineID &b) +static bool RoadVehEngineCapacitySorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - int va = GetTotalCapacityOfArticulatedParts(a); - int vb = GetTotalCapacityOfArticulatedParts(b); + int va = GetTotalCapacityOfArticulatedParts(a.engine_id); + int vb = GetTotalCapacityOfArticulatedParts(b.engine_id); int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ @@ -369,10 +371,10 @@ static bool RoadVehEngineCapacitySorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool ShipEngineCapacitySorter(const EngineID &a, const EngineID &b) +static bool ShipEngineCapacitySorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - const Engine *e_a = Engine::Get(a); - const Engine *e_b = Engine::Get(b); + const Engine *e_a = Engine::Get(a.engine_id); + const Engine *e_b = Engine::Get(b.engine_id); int va = e_a->GetDisplayDefaultCapacity(); int vb = e_b->GetDisplayDefaultCapacity(); @@ -391,10 +393,10 @@ static bool ShipEngineCapacitySorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool AircraftEngineCargoSorter(const EngineID &a, const EngineID &b) +static bool AircraftEngineCargoSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - const Engine *e_a = Engine::Get(a); - const Engine *e_b = Engine::Get(b); + const Engine *e_a = Engine::Get(a.engine_id); + const Engine *e_b = Engine::Get(b.engine_id); uint16 mail_a, mail_b; int va = e_a->GetDisplayDefaultCapacity(&mail_a); @@ -419,10 +421,10 @@ static bool AircraftEngineCargoSorter(const EngineID &a, const EngineID &b) * @param b second engine to compare * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static bool AircraftRangeSorter(const EngineID &a, const EngineID &b) +static bool AircraftRangeSorter(const GUIEngineListItem &a, const GUIEngineListItem &b) { - uint16 r_a = Engine::Get(a)->GetRange(); - uint16 r_b = Engine::Get(b)->GetRange(); + uint16 r_a = Engine::Get(a.engine_id)->GetRange(); + uint16 r_b = Engine::Get(b.engine_id)->GetRange(); int r = r_a - r_b; @@ -536,14 +538,14 @@ const StringID _engine_sort_listing[][12] = {{ }}; /** Filters vehicles by cargo and engine (in case of rail vehicle). */ -static bool CDECL CargoAndEngineFilter(const EngineID *eid, const CargoID cid) +static bool CDECL CargoAndEngineFilter(const GUIEngineListItem *item, const CargoID cid) { if (cid == CF_ANY) { return true; } else if (cid == CF_ENGINES) { - return Engine::Get(*eid)->GetPower() != 0; + return Engine::Get(item->engine_id)->GetPower() != 0; } else { - CargoTypes refit_mask = GetUnionOfArticulatedRefitMasks(*eid, true) & _standard_cargo_mask; + CargoTypes refit_mask = GetUnionOfArticulatedRefitMasks(item->engine_id, true) & _standard_cargo_mask; return (cid == CF_NONE ? refit_mask == 0 : HasBit(refit_mask, cid)); } } @@ -552,18 +554,29 @@ static GUIEngineList::FilterFunction * const _filter_funcs[] = { &CargoAndEngineFilter, }; -static int DrawCargoCapacityInfo(int left, int right, int y, EngineID engine, TestedEngineDetails &te) +static uint GetCargoWeight(const CargoArray &cap, VehicleType vtype) { - CargoArray cap; - CargoTypes refits; - GetArticulatedVehicleCargoesAndRefits(engine, &cap, &refits, te.cargo, te.capacity); + uint weight = 0; + for (CargoID c = 0; c < NUM_CARGO; c++) { + if (cap[c] != 0) { + if (vtype == VEH_TRAIN) { + weight += CargoSpec::Get(c)->WeightOfNUnitsInTrain(cap[c]); + } else { + weight += CargoSpec::Get(c)->WeightOfNUnits(cap[c]); + } + } + } + return weight; +} +static int DrawCargoCapacityInfo(int left, int right, int y, TestedEngineDetails &te, bool refittable) +{ for (CargoID c = 0; c < NUM_CARGO; c++) { - if (cap[c] == 0) continue; + if (te.all_capacities[c] == 0) continue; SetDParam(0, c); - SetDParam(1, cap[c]); - SetDParam(2, HasBit(refits, c) ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY); + SetDParam(1, te.all_capacities[c]); + SetDParam(2, refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY); DrawString(left, right, y, STR_PURCHASE_INFO_CAPACITY); y += FONT_HEIGHT_NORMAL; } @@ -590,8 +603,7 @@ static int DrawRailWagonPurchaseInfo(int left, int right, int y, EngineID engine /* Wagon weight - (including cargo) */ uint weight = e->GetDisplayWeight(); SetDParam(0, weight); - uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(te.cargo)->weight * te.capacity / 16 : 0); - SetDParam(1, cargo_weight + weight); + SetDParam(1, GetCargoWeight(te.all_capacities, VEH_TRAIN) + weight); DrawString(left, right, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT); y += FONT_HEIGHT_NORMAL; @@ -684,8 +696,7 @@ static int DrawRoadVehPurchaseInfo(int left, int right, int y, EngineID engine_n /* Road vehicle weight - (including cargo) */ int16 weight = e->GetDisplayWeight(); SetDParam(0, weight); - uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(te.cargo)->weight * te.capacity / 16 : 0); - SetDParam(1, cargo_weight + weight); + SetDParam(1, GetCargoWeight(te.all_capacities, VEH_ROAD) + weight); DrawString(left, right, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT); y += FONT_HEIGHT_NORMAL; @@ -856,6 +867,7 @@ static uint ShowAdditionalText(int left, int right, int y, EngineID engine) uint16 callback = GetVehicleCallback(CBID_VEHICLE_ADDITIONAL_TEXT, 0, 0, engine, nullptr); if (callback == CALLBACK_FAILED || callback == 0x400) return y; const GRFFile *grffile = Engine::Get(engine)->GetGRF(); + assert(grffile != nullptr); if (callback > 0x400) { ErrorUnknownCallbackResult(grffile->grfid, CBID_VEHICLE_ADDITIONAL_TEXT, callback); return y; @@ -867,6 +879,21 @@ static uint ShowAdditionalText(int left, int right, int y, EngineID engine) return result; } +void TestedEngineDetails::FillDefaultCapacities(const Engine *e) +{ + this->cargo = e->GetDefaultCargoType(); + if (e->type == VEH_TRAIN || e->type == VEH_ROAD) { + this->all_capacities = GetCapacityOfArticulatedParts(e->index); + this->capacity = this->all_capacities[this->cargo]; + this->mail_capacity = 0; + } else { + this->capacity = e->GetDisplayDefaultCapacity(&this->mail_capacity); + this->all_capacities[this->cargo] = this->capacity; + this->all_capacities[CT_MAIL] = this->mail_capacity; + } + if (this->all_capacities.GetCount() == 0) this->cargo = CT_INVALID; +} + /** * Draw the purchase info details of a vehicle at a given location. * @param left,right,y location where to draw the info @@ -908,7 +935,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, if (articulated_cargo) { /* Cargo type + capacity, or N/A */ - int new_y = DrawCargoCapacityInfo(left, right, y, engine_number, te); + int new_y = DrawCargoCapacityInfo(left, right, y, te, refittable); if (new_y == y) { SetDParam(0, CT_INVALID); @@ -953,9 +980,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, /** * Engine drawing loop * @param type Type of vehicle (VEH_*) - * @param l The left most location of the list - * @param r The right most location of the list - * @param y The top most location of the list + * @param r The Rect of the list * @param eng_list What engines to draw * @param min where to start in the list * @param max where in the list to end @@ -963,21 +988,23 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, * @param show_count Whether to show the amount of engines or not * @param selected_group the group to list the engines of */ -void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group) +void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group) { static const int sprite_y_offsets[] = { -1, -1, -2, -2 }; /* Obligatory sanity checks! */ - assert(max <= eng_list->size()); + assert(max <= eng_list.size()); bool rtl = _current_text_dir == TD_RTL; int step_size = GetEngineListHeight(type); int sprite_left = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_left; int sprite_right = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_right; int sprite_width = sprite_left + sprite_right; + int circle_width = std::max(GetScaledSpriteSize(SPR_CIRCLE_FOLDED).width, GetScaledSpriteSize(SPR_CIRCLE_UNFOLDED).width); + int linecolour = _colour_gradient[COLOUR_ORANGE][4]; - int sprite_x = rtl ? r - sprite_right - 1 : l + sprite_left + 1; - int sprite_y_offset = sprite_y_offsets[type] + step_size / 2; + Rect ir = r.WithHeight(step_size).Shrink(WidgetDimensions::scaled.matrix); + int sprite_y_offset = ScaleSpriteTrad(sprite_y_offsets[type]) + ir.Height() / 2; Dimension replace_icon = {0, 0}; int count_width = 0; @@ -987,33 +1014,51 @@ void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList * count_width = GetStringBoundingBox(STR_TINY_BLACK_COMA).width; } - int text_left = l + (rtl ? WD_FRAMERECT_LEFT + replace_icon.width + 8 + count_width : sprite_width + WD_FRAMETEXT_LEFT); - int text_right = r - (rtl ? sprite_width + WD_FRAMETEXT_RIGHT : WD_FRAMERECT_RIGHT + replace_icon.width + 8 + count_width); - int replace_icon_left = rtl ? l + WD_FRAMERECT_LEFT : r - WD_FRAMERECT_RIGHT - replace_icon.width; - int count_left = l; - int count_right = rtl ? text_left : r - WD_FRAMERECT_RIGHT - replace_icon.width - 8; + Rect tr = ir.Indent(circle_width + WidgetDimensions::scaled.hsep_normal + sprite_width + WidgetDimensions::scaled.hsep_wide, rtl); // Name position + Rect cr = tr.Indent(replace_icon.width + WidgetDimensions::scaled.hsep_wide, !rtl).WithWidth(count_width, !rtl); // Count position + Rect rr = tr.WithWidth(replace_icon.width, !rtl); // Replace icon position + if (show_count) tr = tr.Indent(count_width + WidgetDimensions::scaled.hsep_normal + replace_icon.width + WidgetDimensions::scaled.hsep_wide, !rtl); - int normal_text_y_offset = (step_size - FONT_HEIGHT_NORMAL) / 2; - int small_text_y_offset = step_size - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1; - int replace_icon_y_offset = (step_size - replace_icon.height) / 2 - 1; + int normal_text_y_offset = (ir.Height() - FONT_HEIGHT_NORMAL) / 2; + int small_text_y_offset = ir.Height() - FONT_HEIGHT_SMALL; + int replace_icon_y_offset = (ir.Height() - replace_icon.height) / 2; + int y = ir.top; for (; min < max; min++, y += step_size) { - const EngineID engine = (*eng_list)[min]; + const auto &item = eng_list[min]; + uint indent = item.indent * WidgetDimensions::scaled.hsep_indent; + bool has_variants = (item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None; + bool is_folded = (item.flags & EngineDisplayFlags::IsFolded) != EngineDisplayFlags::None; + bool shaded = (item.flags & EngineDisplayFlags::Shaded) != EngineDisplayFlags::None; /* Note: num_engines is only used in the autoreplace GUI, so it is correct to use _local_company here. */ - const uint num_engines = GetGroupNumEngines(_local_company, selected_group, engine); + const uint num_engines = GetGroupNumEngines(_local_company, selected_group, item.engine_id); - const Engine *e = Engine::Get(engine); + const Engine *e = Engine::Get(item.engine_id); bool hidden = HasBit(e->company_hidden, _local_company); StringID str = hidden ? STR_HIDDEN_ENGINE_NAME : STR_ENGINE_NAME; - TextColour tc = (engine == selected_id) ? TC_WHITE : (TC_NO_SHADE | (hidden ? TC_GREY : TC_BLACK)); + TextColour tc = (item.engine_id == selected_id) ? TC_WHITE : (TC_NO_SHADE | ((hidden | shaded) ? TC_GREY : TC_BLACK)); - SetDParam(0, engine); - DrawString(text_left, text_right, y + normal_text_y_offset, str, tc); - DrawVehicleEngine(l, r, sprite_x, y + sprite_y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_company), EIT_PURCHASE); + SetDParam(0, PackEngineNameDParam(item.engine_id, EngineNameContext::PurchaseList, item.indent)); + Rect itr = tr.Indent(indent, rtl); + DrawString(itr.left, itr.right, y + normal_text_y_offset, str, tc); + int sprite_x = ir.Indent(indent + circle_width + WidgetDimensions::scaled.hsep_normal, rtl).WithWidth(sprite_width, rtl).left + sprite_left; + DrawVehicleEngine(r.left, r.right, sprite_x, y + sprite_y_offset, item.engine_id, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(item.engine_id, _local_company), EIT_PURCHASE); if (show_count) { SetDParam(0, num_engines); - DrawString(count_left, count_right, y + small_text_y_offset, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); - if (EngineHasReplacementForCompany(Company::Get(_local_company), engine, selected_group)) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, num_engines == 0 ? PALETTE_CRASH : PAL_NONE, replace_icon_left, y + replace_icon_y_offset); + DrawString(cr.left, cr.right, y + small_text_y_offset, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); + if (EngineHasReplacementForCompany(Company::Get(_local_company), item.engine_id, selected_group)) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, num_engines == 0 ? PALETTE_CRASH : PAL_NONE, rr.left, y + replace_icon_y_offset); + } + if (has_variants) { + Rect fr = ir.Indent(indent, rtl).WithWidth(circle_width, rtl); + DrawSpriteIgnorePadding(is_folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED, PAL_NONE, {fr.left, y, fr.right, y + ir.Height() - 1}, false, SA_CENTER); + } + if (indent > 0) { + /* Draw tree lines */ + Rect fr = ir.Indent(indent - WidgetDimensions::scaled.hsep_indent, rtl).WithWidth(circle_width, rtl); + int ycenter = y + normal_text_y_offset + FONT_HEIGHT_NORMAL / 2; + bool continues = (min + 1U) < eng_list.size() && eng_list[min + 1].indent == item.indent; + GfxDrawLine(fr.left + circle_width / 2, y - WidgetDimensions::scaled.matrix.top, fr.left + circle_width / 2, continues ? y - WidgetDimensions::scaled.matrix.top + step_size - 1 : ycenter, linecolour, WidgetDimensions::scaled.fullbevel.top); + GfxDrawLine(fr.left + circle_width / 2, ycenter, fr.right, ycenter, linecolour, WidgetDimensions::scaled.fullbevel.top); } } } @@ -1078,6 +1123,27 @@ struct BuildVehicleWindow : Window { } } + void AddChildren(const GUIEngineList &source, EngineID parent, int indent) + { + for (const auto &item : source) { + if (item.variant_id != parent || item.engine_id == parent) continue; + + const Engine *e = Engine::Get(item.engine_id); + EngineDisplayFlags flags = item.flags; + if (e->display_last_variant != INVALID_ENGINE) flags &= ~EngineDisplayFlags::Shaded; + this->eng_list.emplace_back(e->display_last_variant == INVALID_ENGINE ? item.engine_id : e->display_last_variant, item.engine_id, flags, indent); + + /* Add variants if not folded */ + if ((item.flags & (EngineDisplayFlags::HasVariants | EngineDisplayFlags::IsFolded)) == EngineDisplayFlags::HasVariants) { + /* Add this engine again as a child */ + if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) { + this->eng_list.emplace_back(item.engine_id, item.engine_id, EngineDisplayFlags::None, indent + 1); + } + AddChildren(source, item.engine_id, indent + 1); + } + } + } + BuildVehicleWindow(WindowDesc *desc, TileIndex tile, VehicleType type) : Window(desc) { this->vehicle_type = type; @@ -1123,12 +1189,12 @@ struct BuildVehicleWindow : Window { this->eng_list.ForceRebuild(); this->GenerateBuildList(); // generate the list, since we need it in the next line - /* Select the first engine in the list as default when opening the window */ - if (this->eng_list.size() > 0) { - this->SelectEngine(this->eng_list[0]); - } else { - this->SelectEngine(INVALID_ENGINE); - } + + /* Select the first unshaded engine in the list as default when opening the window */ + EngineID engine = INVALID_ENGINE; + auto it = std::find_if(this->eng_list.begin(), this->eng_list.end(), [&](GUIEngineListItem &item){ return (item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None; }); + if (it != this->eng_list.end()) engine = it->engine_id; + this->SelectEngine(engine); } /** Set the filter type according to the depot type */ @@ -1221,28 +1287,23 @@ struct BuildVehicleWindow : Window { if (this->sel_engine == INVALID_ENGINE) return; const Engine *e = Engine::Get(this->sel_engine); - if (!e->CanCarryCargo()) { - this->te.cost = 0; - this->te.cargo = CT_INVALID; - return; - } if (!this->listview_mode) { /* Query for cost and refitted capacity */ - auto [ret, veh_id, refit_capacity, refit_mail] = Command::Do(DC_QUERY_COST, this->window_number, this->sel_engine, true, cargo, INVALID_CLIENT_ID); + auto [ret, veh_id, refit_capacity, refit_mail, cargo_capacities] = Command::Do(DC_QUERY_COST, this->window_number, this->sel_engine, true, cargo, INVALID_CLIENT_ID); if (ret.Succeeded()) { this->te.cost = ret.GetCost() - e->GetCost(); this->te.capacity = refit_capacity; this->te.mail_capacity = refit_mail; this->te.cargo = (cargo == CT_INVALID) ? e->GetDefaultCargoType() : cargo; + this->te.all_capacities = cargo_capacities; return; } } /* Purchase test was not possible or failed, fill in the defaults instead. */ this->te.cost = 0; - this->te.capacity = e->GetDisplayDefaultCapacity(&this->te.mail_capacity); - this->te.cargo = e->GetDefaultCargoType(); + this->te.FillDefaultCapacities(e); } void OnInit() override @@ -1257,7 +1318,7 @@ struct BuildVehicleWindow : Window { if (0 == this->eng_list.size()) { // no engine passed through the filter, invalidate the previously selected engine this->SelectEngine(INVALID_ENGINE); } else if (std::find(this->eng_list.begin(), this->eng_list.end(), this->sel_engine) == this->eng_list.end()) { // previously selected engine didn't pass the filter, select the first engine of the list - this->SelectEngine(this->eng_list[0]); + this->SelectEngine(this->eng_list[0].engine_id); } } @@ -1265,17 +1326,18 @@ struct BuildVehicleWindow : Window { bool FilterSingleEngine(EngineID eid) { CargoID filter_type = this->cargo_filter[this->cargo_filter_criteria]; - return CargoAndEngineFilter(&eid, filter_type); + GUIEngineListItem item = {eid, eid, EngineDisplayFlags::None, 0}; + return CargoAndEngineFilter(&item, filter_type); } /* Figure out what train EngineIDs to put in the list */ - void GenerateBuildTrainList() + void GenerateBuildTrainList(GUIEngineList &list) { + std::vector variants; EngineID sel_id = INVALID_ENGINE; - int num_engines = 0; - int num_wagons = 0; + size_t num_engines = 0; - this->eng_list.clear(); + list.clear(); /* Make list of all available train engines and wagons. * Also check to see if the previously selected engine is still available, @@ -1292,17 +1354,22 @@ struct BuildVehicleWindow : Window { /* Filter now! So num_engines and num_wagons is valid */ if (!FilterSingleEngine(eid)) continue; - this->eng_list.push_back(eid); - - if (rvi->railveh_type != RAILVEH_WAGON) { - num_engines++; - } else { - num_wagons++; - } + list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); + if (rvi->railveh_type != RAILVEH_WAGON) num_engines++; + if (e->info.variant_id != eid && e->info.variant_id != INVALID_ENGINE) variants.push_back(e->info.variant_id); if (eid == this->sel_engine) sel_id = eid; } + /* ensure primary engine of variant group is in list */ + for (const auto &variant : variants) { + if (std::find(list.begin(), list.end(), variant) == list.end()) { + const Engine *e = Engine::Get(variant); + list.emplace_back(variant, e->info.variant_id, e->display_flags | EngineDisplayFlags::Shaded, 0); + if (e->u.rail.railveh_type != RAILVEH_WAGON) num_engines++; + } + } + this->SelectEngine(sel_id); /* invalidate cached values for name sorter - engine names could change */ @@ -1310,14 +1377,14 @@ struct BuildVehicleWindow : Window { /* make engines first, and then wagons, sorted by selected sort_criteria */ _engine_sort_direction = false; - EngList_Sort(&this->eng_list, TrainEnginesThenWagonsSorter); + EngList_Sort(&list, TrainEnginesThenWagonsSorter); /* and then sort engines */ _engine_sort_direction = this->descending_sort_order; - EngList_SortPartial(&this->eng_list, _engine_sort_functions[0][this->sort_criteria], 0, num_engines); + EngList_SortPartial(&list, _engine_sort_functions[0][this->sort_criteria], 0, num_engines); /* and finally sort wagons */ - EngList_SortPartial(&this->eng_list, _engine_sort_functions[0][this->sort_criteria], num_engines, num_wagons); + EngList_SortPartial(&list, _engine_sort_functions[0][this->sort_criteria], num_engines, list.size() - num_engines); } /* Figure out what road vehicle EngineIDs to put in the list */ @@ -1333,7 +1400,7 @@ struct BuildVehicleWindow : Window { if (!IsEngineBuildable(eid, VEH_ROAD, _local_company)) continue; if (this->filter.roadtype != INVALID_ROADTYPE && !HasPowerOnRoad(e->u.road.roadtype, this->filter.roadtype)) continue; - this->eng_list.push_back(eid); + this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); if (eid == this->sel_engine) sel_id = eid; } @@ -1350,7 +1417,7 @@ struct BuildVehicleWindow : Window { if (!this->show_hidden_engines && e->IsHidden(_local_company)) continue; EngineID eid = e->index; if (!IsEngineBuildable(eid, VEH_SHIP, _local_company)) continue; - this->eng_list.push_back(eid); + this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); if (eid == this->sel_engine) sel_id = eid; } @@ -1377,7 +1444,7 @@ struct BuildVehicleWindow : Window { /* First VEH_END window_numbers are fake to allow a window open for all different types at once */ if (!this->listview_mode && !CanVehicleUseStation(eid, st)) continue; - this->eng_list.push_back(eid); + this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0); if (eid == this->sel_engine) sel_id = eid; } @@ -1392,13 +1459,18 @@ struct BuildVehicleWindow : Window { /* Update filter type in case the road/railtype of the depot got converted */ this->UpdateFilterByTile(); + this->eng_list.clear(); + + GUIEngineList list; + switch (this->vehicle_type) { default: NOT_REACHED(); case VEH_TRAIN: - this->GenerateBuildTrainList(); + this->GenerateBuildTrainList(list); + AddChildren(list, INVALID_ENGINE, 0); this->eng_list.shrink_to_fit(); this->eng_list.RebuildDone(); - return; // trains should not reach the last sorting + return; case VEH_ROAD: this->GenerateBuildRoadVehList(); break; @@ -1412,9 +1484,23 @@ struct BuildVehicleWindow : Window { this->FilterEngineList(); + /* ensure primary engine of variant group is in list after filtering */ + std::vector variants; + for (const auto &item : this->eng_list) { + if (item.engine_id != item.variant_id && item.variant_id != INVALID_ENGINE) variants.push_back(item.variant_id); + } + for (const auto &variant : variants) { + if (std::find(this->eng_list.begin(), this->eng_list.end(), variant) == this->eng_list.end()) { + const Engine *e = Engine::Get(variant); + this->eng_list.emplace_back(variant, e->info.variant_id, e->display_flags | EngineDisplayFlags::Shaded, 0); + } + } + _engine_sort_direction = this->descending_sort_order; EngList_Sort(&this->eng_list, _engine_sort_functions[this->vehicle_type][this->sort_criteria]); + this->eng_list.swap(list); + AddChildren(list, INVALID_ENGINE, 0); this->eng_list.shrink_to_fit(); this->eng_list.RebuildDone(); } @@ -1440,7 +1526,23 @@ struct BuildVehicleWindow : Window { case WID_BV_LIST: { uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_BV_LIST); size_t num_items = this->eng_list.size(); - this->SelectEngine((i < num_items) ? this->eng_list[i] : INVALID_ENGINE); + EngineID e = INVALID_ENGINE; + if (i < num_items) { + const auto &item = this->eng_list[i]; + const Rect r = this->GetWidget(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix).WithWidth(WidgetDimensions::scaled.hsep_indent * (item.indent + 1), _current_text_dir == TD_RTL); + if ((item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None && IsInsideMM(r.left, r.right, pt.x)) { + /* toggle folded flag on engine */ + assert(item.variant_id != INVALID_ENGINE); + Engine *engine = Engine::Get(item.variant_id); + engine->display_flags ^= EngineDisplayFlags::IsFolded; + + InvalidateWindowData(WC_REPLACE_VEHICLE, this->vehicle_type, 0); // Update the autoreplace window + InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well + return; + } + if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) e = item.engine_id; + } + this->SelectEngine(e); this->SetDirty(); if (_ctrl_pressed) { this->OnClick(pt, WID_BV_SHOW_HIDE, 1); @@ -1476,6 +1578,20 @@ struct BuildVehicleWindow : Window { } else { Command::Post(GetCmdBuildVehMsg(this->vehicle_type), CcBuildPrimaryVehicle, this->window_number, sel_eng, true, cargo, INVALID_CLIENT_ID); } + + /* Update last used variant and refresh if necessary. */ + bool refresh = false; + int recursion = 10; /* In case of infinite loop */ + for (Engine *e = Engine::Get(sel_eng); recursion > 0; e = Engine::Get(e->info.variant_id), --recursion) { + refresh |= (e->display_last_variant != sel_eng); + e->display_last_variant = sel_eng; + if (e->info.variant_id == INVALID_ENGINE) break; + } + if (refresh) { + InvalidateWindowData(WC_REPLACE_VEHICLE, this->vehicle_type, 0); // Update the autoreplace window + InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well + return; + } } break; } @@ -1484,7 +1600,7 @@ struct BuildVehicleWindow : Window { EngineID sel_eng = this->sel_engine; if (sel_eng != INVALID_ENGINE) { this->rename_engine = sel_eng; - SetDParam(0, sel_eng); + SetDParam(0, PackEngineNameDParam(sel_eng, EngineNameContext::Generic)); ShowQueryString(STR_ENGINE_NAME, STR_QUERY_RENAME_TRAIN_TYPE_CAPTION + this->vehicle_type, MAX_LENGTH_ENGINE_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS); } break; @@ -1551,7 +1667,7 @@ struct BuildVehicleWindow : Window { case WID_BV_LIST: resize->height = GetEngineListHeight(this->vehicle_type); size->height = 3 * resize->height; - size->width = std::max(size->width, GetVehicleImageCellSize(this->vehicle_type, EIT_PURCHASE).extend_left + GetVehicleImageCellSize(this->vehicle_type, EIT_PURCHASE).extend_right + 165); + size->width = std::max(size->width, GetVehicleImageCellSize(this->vehicle_type, EIT_PURCHASE).extend_left + GetVehicleImageCellSize(this->vehicle_type, EIT_PURCHASE).extend_right + 165) + padding.width; break; case WID_BV_PANEL: @@ -1588,10 +1704,8 @@ struct BuildVehicleWindow : Window { case WID_BV_LIST: DrawEngineList( this->vehicle_type, - r.left + WD_FRAMERECT_LEFT, - r.right - WD_FRAMERECT_RIGHT, - r.top + WD_FRAMERECT_TOP, - &this->eng_list, + r, + this->eng_list, this->vscroll->GetPosition(), static_cast(std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->eng_list.size())), this->sel_engine, @@ -1622,10 +1736,9 @@ struct BuildVehicleWindow : Window { int needed_height = this->details_height; /* Draw details panels. */ if (this->sel_engine != INVALID_ENGINE) { - NWidgetBase *nwi = this->GetWidget(WID_BV_PANEL); - int text_end = DrawVehiclePurchaseInfo(nwi->pos_x + WD_FRAMETEXT_LEFT, nwi->pos_x + nwi->current_x - WD_FRAMETEXT_RIGHT, - nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine, this->te); - needed_height = std::max(needed_height, (text_end - (int)nwi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL); + const Rect r = this->GetWidget(WID_BV_PANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect); + int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine, this->te); + needed_height = std::max(needed_height, (text_end - r.top) / FONT_HEIGHT_NORMAL); } if (needed_height != this->details_height) { // Details window are not high enough, enlarge them. int resize = needed_height - this->details_height; diff --git a/src/cargotype.cpp b/src/cargotype.cpp index e35c94d2fefb4..1bb490a2cf7db 100644 --- a/src/cargotype.cpp +++ b/src/cargotype.cpp @@ -12,6 +12,7 @@ #include "newgrf_cargo.h" #include "string_func.h" #include "strings_func.h" +#include "settings_type.h" #include "table/sprites.h" #include "table/strings.h" @@ -209,3 +210,8 @@ void InitializeSortedCargoSpecs() _sorted_standard_cargo_specs = { _sorted_cargo_specs.data(), nb_standard_cargo }; } +uint64 CargoSpec::WeightOfNUnitsInTrain(uint32 n) const +{ + if (this->is_freight) n *= _settings_game.vehicle.freight_trains; + return this->WeightOfNUnits(n); +} diff --git a/src/cargotype.h b/src/cargotype.h index 54d24f1d7af7d..6e73f36958719 100644 --- a/src/cargotype.h +++ b/src/cargotype.h @@ -123,6 +123,13 @@ struct CargoSpec { SpriteID GetCargoIcon() const; + inline uint64 WeightOfNUnits(uint32 n) const + { + return n * this->weight / 16u; + } + + uint64 WeightOfNUnitsInTrain(uint32 n) const; + /** * Iterator to iterate all valid CargoSpec */ diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index eb62dc031755d..34418c9840c5c 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -29,6 +29,7 @@ #include "newgrf.h" #include "error.h" #include "misc_cmd.h" +#include "core/geometry_func.hpp" #include "widgets/cheat_widget.h" @@ -55,7 +56,7 @@ static int32 _money_cheat_amount = 10000000; */ static int32 ClickMoneyCheat(int32 p1, int32 p2) { - Command::Post(p2 * _money_cheat_amount); + Command::Post(Money(_money_cheat_amount) * p2); return _money_cheat_amount; } @@ -114,6 +115,8 @@ static int32 ClickChangeDateCheat(int32 p1, int32 p2) EnginesMonthlyLoop(); SetWindowDirty(WC_STATUS_BAR, 0); InvalidateWindowClassesData(WC_BUILD_STATION, 0); + InvalidateWindowClassesData(WC_BUS_STATION, 0); + InvalidateWindowClassesData(WC_TRUCK_STATION, 0); InvalidateWindowClassesData(WC_BUILD_OBJECT, 0); ResetSignalVariant(); return _cur_year; @@ -132,7 +135,7 @@ static int32 ClickChangeMaxHlCheat(int32 p1, int32 p2) /* Check if at least one mountain on the map is higher than the new value. * If yes, disallow the change. */ - for (TileIndex t = 0; t < MapSize(); t++) { + for (TileIndex t = 0; t < Map::Size(); t++) { if ((int32)TileHeight(t) > p1) { ShowErrorMessage(STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN, INVALID_STRING_ID, WL_ERROR); /* Return old, unchanged value */ @@ -207,7 +210,7 @@ static const NWidgetPart _nested_cheat_widgets[] = { EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY, WID_C_PANEL), SetDataTip(0x0, STR_CHEATS_TOOLTIP), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(WWT_LABEL, COLOUR_GREY, WID_C_NOTE), SetFill(1, 1), SetDataTip(STR_CHEATS_NOTE, STR_NULL), SetPadding(WD_PAR_VSEP_NORMAL, 4, WD_PAR_VSEP_NORMAL, 4), + NWidget(WWT_LABEL, COLOUR_GREY, WID_C_NOTE), SetFill(1, 1), SetDataTip(STR_CHEATS_NOTE, STR_NULL), SetPadding(WidgetDimensions::unscaled.frametext), EndContainer(), }; @@ -216,39 +219,48 @@ struct CheatWindow : Window { int clicked; int clicked_widget; uint line_height; - int box_width; + Dimension box; ///< Dimension of box sprite + Dimension icon; ///< Dimension of company icon sprite CheatWindow(WindowDesc *desc) : Window(desc) { - this->box_width = GetSpriteSize(SPR_BOX_EMPTY).width; this->InitNested(); } + void OnInit() override + { + this->box = maxdim(GetSpriteSize(SPR_BOX_EMPTY), GetSpriteSize(SPR_BOX_CHECKED)); + this->icon = GetSpriteSize(SPR_COMPANY_ICON); + } + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_C_PANEL) return; - int y = r.top + WD_FRAMERECT_TOP + WD_PAR_VSEP_NORMAL; + const Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); + int y = ir.top; bool rtl = _current_text_dir == TD_RTL; - uint box_left = rtl ? r.right - this->box_width - 5 : r.left + 5; - uint button_left = rtl ? r.right - this->box_width - 10 - SETTING_BUTTON_WIDTH : r.left + this->box_width + 10; - uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : 20 + this->box_width + SETTING_BUTTON_WIDTH); - uint text_right = r.right - (rtl ? 20 + this->box_width + SETTING_BUTTON_WIDTH : WD_FRAMERECT_RIGHT); + uint box_left = rtl ? ir.right - this->box.width - WidgetDimensions::scaled.hsep_wide : ir.left + WidgetDimensions::scaled.hsep_wide; + uint button_left = rtl ? ir.right - this->box.width - WidgetDimensions::scaled.hsep_wide * 2 - SETTING_BUTTON_WIDTH : ir.left + this->box.width + WidgetDimensions::scaled.hsep_wide * 2; + uint text_left = ir.left + (rtl ? 0 : WidgetDimensions::scaled.hsep_wide * 4 + this->box.width + SETTING_BUTTON_WIDTH); + uint text_right = ir.right - (rtl ? WidgetDimensions::scaled.hsep_wide * 4 + this->box.width + SETTING_BUTTON_WIDTH : 0); int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; - int icon_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; + int box_y_offset = (this->line_height - this->box.height) / 2; + int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; + int icon_y_offset = (this->line_height - this->icon.height) / 2; for (int i = 0; i != lengthof(_cheats_ui); i++) { const CheatEntry *ce = &_cheats_ui[i]; - DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + icon_y_offset + 2); + DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + box_y_offset); switch (ce->type) { case SLE_BOOL: { bool on = (*(bool*)ce->variable); - DrawBoolButton(button_left, y + icon_y_offset, on, true); + DrawBoolButton(button_left, y + button_y_offset, on, true); SetDParam(0, on ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF); break; } @@ -258,7 +270,7 @@ struct CheatWindow : Window { char buf[512]; /* Draw [<][>] boxes for settings of an integer-type */ - DrawArrowButtons(button_left, y + icon_y_offset, COLOUR_YELLOW, clicked - (i * 2), true, true); + DrawArrowButtons(button_left, y + button_y_offset, COLOUR_YELLOW, clicked - (i * 2), true, true); switch (ce->str) { /* Display date for change date cheat */ @@ -268,8 +280,8 @@ struct CheatWindow : Window { case STR_CHEAT_CHANGE_COMPANY: { SetDParam(0, val + 1); GetString(buf, STR_CHEAT_CHANGE_COMPANY, lastof(buf)); - uint offset = 10 + GetStringBoundingBox(buf).width; - DrawCompanyIcon(_local_company, rtl ? text_right - offset - 10 : text_left + offset, y + icon_y_offset + 2); + uint offset = WidgetDimensions::scaled.hsep_indent + GetStringBoundingBox(buf).width; + DrawCompanyIcon(_local_company, rtl ? text_right - offset - WidgetDimensions::scaled.hsep_indent : text_left + offset, y + icon_y_offset); break; } @@ -311,7 +323,7 @@ struct CheatWindow : Window { /* Draw coloured flag for change company cheat */ case STR_CHEAT_CHANGE_COMPANY: SetDParamMaxValue(0, MAX_COMPANIES); - width = std::max(width, GetStringBoundingBox(ce->str).width + 10 + 10); + width = std::max(width, GetStringBoundingBox(ce->str).width + WidgetDimensions::scaled.hsep_wide * 4); break; default: @@ -323,21 +335,21 @@ struct CheatWindow : Window { } } - this->line_height = std::max(GetSpriteSize(SPR_BOX_CHECKED).height, GetSpriteSize(SPR_BOX_EMPTY).height); + this->line_height = std::max(this->box.height, this->icon.height); this->line_height = std::max(this->line_height, SETTING_BUTTON_HEIGHT); - this->line_height = std::max(this->line_height, FONT_HEIGHT_NORMAL) + WD_PAR_VSEP_NORMAL; + this->line_height = std::max(this->line_height, FONT_HEIGHT_NORMAL) + WidgetDimensions::scaled.framerect.Vertical(); - size->width = width + 20 + this->box_width + SETTING_BUTTON_WIDTH /* stuff on the left */ + 10 /* extra spacing on right */; - size->height = WD_FRAMERECT_TOP + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_BOTTOM + this->line_height * lengthof(_cheats_ui); + size->width = width + WidgetDimensions::scaled.hsep_wide * 4 + this->box.width + SETTING_BUTTON_WIDTH /* stuff on the left */ + WidgetDimensions::scaled.hsep_wide * 2 /* extra spacing on right */; + size->height = WidgetDimensions::scaled.framerect.Vertical() + this->line_height * lengthof(_cheats_ui); } void OnClick(Point pt, int widget, int click_count) override { - const NWidgetBase *wid = this->GetWidget(WID_C_PANEL); - uint btn = (pt.y - wid->pos_y - WD_FRAMERECT_TOP - WD_PAR_VSEP_NORMAL) / this->line_height; - int x = pt.x - wid->pos_x; + Rect r = this->GetWidget(WID_C_PANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); + uint btn = (pt.y - r.top) / this->line_height; + uint x = pt.x - r.left; bool rtl = _current_text_dir == TD_RTL; - if (rtl) x = wid->current_x - x; + if (rtl) x = r.Width() - 1 - x; if (btn >= lengthof(_cheats_ui)) return; @@ -345,13 +357,13 @@ struct CheatWindow : Window { int value = (int32)ReadValue(ce->variable, ce->type); int oldvalue = value; - if (btn == CHT_CHANGE_DATE && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) { + if (btn == CHT_CHANGE_DATE && x >= WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH) { /* Click at the date text directly. */ clicked_widget = CHT_CHANGE_DATE; SetDParam(0, value); ShowQueryString(STR_JUST_INT, STR_CHEAT_CHANGE_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED); return; - } else if (btn == CHT_EDIT_MAX_HL && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) { + } else if (btn == CHT_EDIT_MAX_HL && x >= WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH) { clicked_widget = CHT_EDIT_MAX_HL; SetDParam(0, value); ShowQueryString(STR_JUST_INT, STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED); @@ -359,7 +371,7 @@ struct CheatWindow : Window { } /* Not clicking a button? */ - if (!IsInsideMM(x, 10 + this->box_width, 10 + this->box_width + SETTING_BUTTON_WIDTH)) return; + if (!IsInsideMM(x, WidgetDimensions::scaled.hsep_wide * 2 + this->box.width, WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH)) return; *ce->been_used = true; @@ -371,10 +383,10 @@ struct CheatWindow : Window { default: /* Take whatever the function returns */ - value = ce->proc(value + ((x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1), (x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1); + value = ce->proc(value + ((x >= WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1), (x >= WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1); /* The first cheat (money), doesn't return a different value. */ - if (value != oldvalue || btn == CHT_MONEY) this->clicked = btn * 2 + 1 + ((x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) != rtl ? 1 : 0); + if (value != oldvalue || btn == CHT_MONEY) this->clicked = btn * 2 + 1 + ((x >= WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH / 2) != rtl ? 1 : 0); break; } diff --git a/src/clear_cmd.cpp b/src/clear_cmd.cpp index 3e89fb5543770..abd5fc0c31c2c 100644 --- a/src/clear_cmd.cpp +++ b/src/clear_cmd.cpp @@ -13,7 +13,6 @@ #include "landscape.h" #include "genworld.h" #include "viewport_func.h" -#include "water.h" #include "core/random_func.hpp" #include "newgrf_generic.h" #include "landscape_cmd.h" @@ -249,15 +248,6 @@ static void TileLoopClearDesert(TileIndex tile) static void TileLoop_Clear(TileIndex tile) { - /* If the tile is at any edge flood it to prevent maps without water. */ - if (_settings_game.construction.freeform_edges && DistanceFromEdge(tile) == 1) { - int z; - if (IsTileFlat(tile, &z) && z == 0) { - DoFloodTile(tile); - MarkTileDirtyByTile(tile); - return; - } - } AmbientSoundEffect(tile); switch (_settings_game.game_creation.landscape) { @@ -320,8 +310,8 @@ void GenerateClearTile() TileIndex tile; /* add rough tiles */ - i = ScaleByMapSize(GB(Random(), 0, 10) + 0x400); - gi = ScaleByMapSize(GB(Random(), 0, 7) + 0x80); + i = Map::ScaleBySize(GB(Random(), 0, 10) + 0x400); + gi = Map::ScaleBySize(GB(Random(), 0, 7) + 0x80); SetGeneratingWorldProgress(GWP_ROUGH_ROCKY, gi + i); do { diff --git a/src/clear_map.h b/src/clear_map.h index 163d0023534f7..c2603a6cc3d86 100644 --- a/src/clear_map.h +++ b/src/clear_map.h @@ -32,10 +32,10 @@ enum ClearGround { * @pre IsTileType(t, MP_CLEAR) * @return whether the tile is covered with snow. */ -static inline bool IsSnowTile(TileIndex t) +static inline bool IsSnowTile(Tile t) { assert(IsTileType(t, MP_CLEAR)); - return HasBit(_m[t].m3, 4); + return HasBit(t.m3(), 4); } /** @@ -44,10 +44,10 @@ static inline bool IsSnowTile(TileIndex t) * @pre IsTileType(t, MP_CLEAR) * @return the ground type */ -static inline ClearGround GetRawClearGround(TileIndex t) +static inline ClearGround GetRawClearGround(Tile t) { assert(IsTileType(t, MP_CLEAR)); - return (ClearGround)GB(_m[t].m5, 2, 3); + return (ClearGround)GB(t.m5(), 2, 3); } /** @@ -56,7 +56,7 @@ static inline ClearGround GetRawClearGround(TileIndex t) * @pre IsTileType(t, MP_CLEAR) * @return the ground type */ -static inline ClearGround GetClearGround(TileIndex t) +static inline ClearGround GetClearGround(Tile t) { if (IsSnowTile(t)) return CLEAR_SNOW; return GetRawClearGround(t); @@ -68,7 +68,7 @@ static inline ClearGround GetClearGround(TileIndex t) * @param ct the ground type * @pre IsTileType(t, MP_CLEAR) */ -static inline bool IsClearGround(TileIndex t, ClearGround ct) +static inline bool IsClearGround(Tile t, ClearGround ct) { return GetClearGround(t) == ct; } @@ -80,10 +80,10 @@ static inline bool IsClearGround(TileIndex t, ClearGround ct) * @pre IsTileType(t, MP_CLEAR) * @return the density */ -static inline uint GetClearDensity(TileIndex t) +static inline uint GetClearDensity(Tile t) { assert(IsTileType(t, MP_CLEAR)); - return GB(_m[t].m5, 0, 2); + return GB(t.m5(), 0, 2); } /** @@ -92,10 +92,10 @@ static inline uint GetClearDensity(TileIndex t) * @param d the amount to increment the density with * @pre IsTileType(t, MP_CLEAR) */ -static inline void AddClearDensity(TileIndex t, int d) +static inline void AddClearDensity(Tile t, int d) { assert(IsTileType(t, MP_CLEAR)); // XXX incomplete - _m[t].m5 += d; + t.m5() += d; } /** @@ -104,10 +104,10 @@ static inline void AddClearDensity(TileIndex t, int d) * @param d the new density * @pre IsTileType(t, MP_CLEAR) */ -static inline void SetClearDensity(TileIndex t, uint d) +static inline void SetClearDensity(Tile t, uint d) { assert(IsTileType(t, MP_CLEAR)); - SB(_m[t].m5, 0, 2, d); + SB(t.m5(), 0, 2, d); } @@ -117,10 +117,10 @@ static inline void SetClearDensity(TileIndex t, uint d) * @pre IsTileType(t, MP_CLEAR) * @return the value of the counter */ -static inline uint GetClearCounter(TileIndex t) +static inline uint GetClearCounter(Tile t) { assert(IsTileType(t, MP_CLEAR)); - return GB(_m[t].m5, 5, 3); + return GB(t.m5(), 5, 3); } /** @@ -129,10 +129,10 @@ static inline uint GetClearCounter(TileIndex t) * @param c the amount to increment the counter with * @pre IsTileType(t, MP_CLEAR) */ -static inline void AddClearCounter(TileIndex t, int c) +static inline void AddClearCounter(Tile t, int c) { assert(IsTileType(t, MP_CLEAR)); // XXX incomplete - _m[t].m5 += c << 5; + t.m5() += c << 5; } /** @@ -141,10 +141,10 @@ static inline void AddClearCounter(TileIndex t, int c) * @param c the amount to set the counter to * @pre IsTileType(t, MP_CLEAR) */ -static inline void SetClearCounter(TileIndex t, uint c) +static inline void SetClearCounter(Tile t, uint c) { assert(IsTileType(t, MP_CLEAR)); // XXX incomplete - SB(_m[t].m5, 5, 3, c); + SB(t.m5(), 5, 3, c); } @@ -155,10 +155,10 @@ static inline void SetClearCounter(TileIndex t, uint c) * @param density the density of the ground tile * @pre IsTileType(t, MP_CLEAR) */ -static inline void SetClearGroundDensity(TileIndex t, ClearGround type, uint density) +static inline void SetClearGroundDensity(Tile t, ClearGround type, uint density) { assert(IsTileType(t, MP_CLEAR)); // XXX incomplete - _m[t].m5 = 0 << 5 | type << 2 | density; + t.m5() = 0 << 5 | type << 2 | density; } @@ -168,10 +168,10 @@ static inline void SetClearGroundDensity(TileIndex t, ClearGround type, uint den * @pre GetClearGround(t) == CLEAR_FIELDS * @return the field type */ -static inline uint GetFieldType(TileIndex t) +static inline uint GetFieldType(Tile t) { assert(GetClearGround(t) == CLEAR_FIELDS); - return GB(_m[t].m3, 0, 4); + return GB(t.m3(), 0, 4); } /** @@ -180,10 +180,10 @@ static inline uint GetFieldType(TileIndex t) * @param f the field type * @pre GetClearGround(t) == CLEAR_FIELDS */ -static inline void SetFieldType(TileIndex t, uint f) +static inline void SetFieldType(Tile t, uint f) { assert(GetClearGround(t) == CLEAR_FIELDS); // XXX incomplete - SB(_m[t].m3, 0, 4, f); + SB(t.m3(), 0, 4, f); } /** @@ -191,9 +191,9 @@ static inline void SetFieldType(TileIndex t, uint f) * @param t tile index field belongs to. * @return frame value. */ -static inline int GetIncFieldAnimationFract(TileIndex t) { +static inline int GetIncFieldAnimationFract(Tile t) { assert(GetClearGround(t) == CLEAR_FIELDS); - return _me[t].m8++; + return t.m8()++; } /** @@ -202,10 +202,10 @@ static inline int GetIncFieldAnimationFract(TileIndex t) { * @pre GetClearGround(t) == CLEAR_FIELDS * @return the industry that made the field */ -static inline IndustryID GetIndustryIndexOfField(TileIndex t) +static inline IndustryID GetIndustryIndexOfField(Tile t) { assert(GetClearGround(t) == CLEAR_FIELDS); - return(IndustryID) _m[t].m2; + return(IndustryID) t.m2(); } /** @@ -214,10 +214,10 @@ static inline IndustryID GetIndustryIndexOfField(TileIndex t) * @param i the industry that made the field * @pre GetClearGround(t) == CLEAR_FIELDS */ -static inline void SetIndustryIndexOfField(TileIndex t, IndustryID i) +static inline void SetIndustryIndexOfField(Tile t, IndustryID i) { assert(GetClearGround(t) == CLEAR_FIELDS); - _m[t].m2 = i; + t.m2() = i; } @@ -228,15 +228,15 @@ static inline void SetIndustryIndexOfField(TileIndex t, IndustryID i) * @pre IsClearGround(t, CLEAR_FIELDS) * @return 0 if there is no fence, otherwise the fence type */ -static inline uint GetFence(TileIndex t, DiagDirection side) +static inline uint GetFence(Tile t, DiagDirection side) { assert(IsClearGround(t, CLEAR_FIELDS)); switch (side) { default: NOT_REACHED(); - case DIAGDIR_SE: return GB(_m[t].m4, 2, 3); - case DIAGDIR_SW: return GB(_m[t].m4, 5, 3); - case DIAGDIR_NE: return GB(_m[t].m3, 5, 3); - case DIAGDIR_NW: return GB(_me[t].m6, 2, 3); + case DIAGDIR_SE: return GB(t.m4(), 2, 3); + case DIAGDIR_SW: return GB(t.m4(), 5, 3); + case DIAGDIR_NE: return GB(t.m3(), 5, 3); + case DIAGDIR_NW: return GB(t.m6(), 2, 3); } } @@ -247,15 +247,15 @@ static inline uint GetFence(TileIndex t, DiagDirection side) * @param h 0 if there is no fence, otherwise the fence type * @pre IsClearGround(t, CLEAR_FIELDS) */ -static inline void SetFence(TileIndex t, DiagDirection side, uint h) +static inline void SetFence(Tile t, DiagDirection side, uint h) { assert(IsClearGround(t, CLEAR_FIELDS)); switch (side) { default: NOT_REACHED(); - case DIAGDIR_SE: SB(_m[t].m4, 2, 3, h); break; - case DIAGDIR_SW: SB(_m[t].m4, 5, 3, h); break; - case DIAGDIR_NE: SB(_m[t].m3, 5, 3, h); break; - case DIAGDIR_NW: SB(_me[t].m6, 2, 3, h); break; + case DIAGDIR_SE: SB(t.m4(), 2, 3, h); break; + case DIAGDIR_SW: SB(t.m4(), 5, 3, h); break; + case DIAGDIR_NE: SB(t.m3(), 5, 3, h); break; + case DIAGDIR_NW: SB(t.m6(), 2, 3, h); break; } } @@ -266,18 +266,18 @@ static inline void SetFence(TileIndex t, DiagDirection side, uint h) * @param g the type of ground * @param density the density of the grass/snow/desert etc */ -static inline void MakeClear(TileIndex t, ClearGround g, uint density) +static inline void MakeClear(Tile t, ClearGround g, uint density) { SetTileType(t, MP_CLEAR); - _m[t].m1 = 0; + t.m1() = 0; SetTileOwner(t, OWNER_NONE); - _m[t].m2 = 0; - _m[t].m3 = 0; - _m[t].m4 = 0 << 5 | 0 << 2; + t.m2() = 0; + t.m3() = 0; + t.m4() = 0 << 5 | 0 << 2; SetClearGroundDensity(t, g, density); // Sets m5 - _me[t].m6 = 0; - _me[t].m7 = 0; - _me[t].m8 = 0; + t.m6() = 0; + t.m7() = 0; + t.m8() = 0; } @@ -287,18 +287,18 @@ static inline void MakeClear(TileIndex t, ClearGround g, uint density) * @param field_type the 'growth' level of the field * @param industry the industry this tile belongs to */ -static inline void MakeField(TileIndex t, uint field_type, IndustryID industry) +static inline void MakeField(Tile t, uint field_type, IndustryID industry) { SetTileType(t, MP_CLEAR); - _m[t].m1 = 0; + t.m1() = 0; SetTileOwner(t, OWNER_NONE); - _m[t].m2 = industry; - _m[t].m3 = field_type; - _m[t].m4 = 0 << 5 | 0 << 2; + t.m2() = industry; + t.m3() = field_type; + t.m4() = 0 << 5 | 0 << 2; SetClearGroundDensity(t, CLEAR_FIELDS, 3); - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; - _me[t].m8 = 0; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; + t.m8() = 0; } /** @@ -307,10 +307,10 @@ static inline void MakeField(TileIndex t, uint field_type, IndustryID industry) * @param density The density of snowiness. * @pre GetClearGround(t) != CLEAR_SNOW */ -static inline void MakeSnow(TileIndex t, uint density = 0) +static inline void MakeSnow(Tile t, uint density = 0) { assert(GetClearGround(t) != CLEAR_SNOW); - SetBit(_m[t].m3, 4); + SetBit(t.m3(), 4); if (GetRawClearGround(t) == CLEAR_FIELDS) { SetClearGroundDensity(t, CLEAR_GRASS, density); } else { @@ -323,10 +323,10 @@ static inline void MakeSnow(TileIndex t, uint density = 0) * @param t the tile to clear of snow * @pre GetClearGround(t) == CLEAR_SNOW */ -static inline void ClearSnow(TileIndex t) +static inline void ClearSnow(Tile t) { assert(GetClearGround(t) == CLEAR_SNOW); - ClrBit(_m[t].m3, 4); + ClrBit(t.m3(), 4); SetClearDensity(t, 3); } diff --git a/src/command.cpp b/src/command.cpp index 65e5acf10c91f..410e4fd4a80ea 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -32,6 +32,7 @@ #include "goal_cmd.h" #include "group_cmd.h" #include "industry_cmd.h" +#include "league_cmd.h" #include "landscape_cmd.h" #include "misc_cmd.h" #include "news_cmd.h" @@ -258,7 +259,7 @@ void CommandHelperBase::InternalPostResult(const CommandCost &res, TileIndex til if (res.Failed()) { /* Only show the error when it's for us. */ if (estimate_only || (IsLocalCompany() && err_message != 0 && my_cmd)) { - ShowErrorMessage(err_message, res.GetErrorMessage(), WL_INFO, x, y, res.GetTextRefStackGRF(), res.GetTextRefStackSize(), res.GetTextRefStack()); + ShowErrorMessage(err_message, x, y, res); } } else if (estimate_only) { ShowEstimatedCostOrIncome(res.GetCost(), x, y); diff --git a/src/command_func.h b/src/command_func.h index d78c8229a4a38..d10340146d3e8 100644 --- a/src/command_func.h +++ b/src/command_func.h @@ -37,7 +37,7 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); */ #define return_cmd_error(errcode) return CommandCost(errcode); -void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex location, const CommandDataBuffer &cmd_data); +void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, const CommandDataBuffer &cmd_data); bool IsValidCommand(Commands cmd); CommandFlags GetCommandFlags(Commands cmd); @@ -152,7 +152,7 @@ struct CommandHelper : protected C if constexpr (std::is_same_v>>) { /* Do not even think about executing out-of-bounds tile-commands. */ TileIndex tile = std::get<0>(std::make_tuple(args...)); - if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (flags & DC_ALL_TILES) == 0))) return MakeResult(CMD_ERROR); + if (tile != 0 && (tile >= Map::Size() || (!IsValidTile(tile) && (flags & DC_ALL_TILES) == 0))) return MakeResult(CMD_ERROR); } RecursiveCommandCounter counter{}; @@ -215,20 +215,13 @@ struct CommandHelper : protected C * @param err_message Message prefix to show on error * @param callback A callback function to call after the command is finished * @param my_cmd indicator if the command is from a company or server (to display error messages for a user) - * @param location Tile location for user feedback. * @param args Parameters for the command * @return \c true if the command succeeded, else \c false. */ template - static bool PostFromNet(StringID err_message, Tcallback *callback, bool my_cmd, TileIndex location, std::tuple args) + static bool PostFromNet(StringID err_message, Tcallback *callback, bool my_cmd, std::tuple args) { - if constexpr (std::is_same_v>) { - /* Do not even think about executing out-of-bounds tile-commands. */ - TileIndex tile = std::get<0>(args); - if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (GetCommandFlags() & CMD_ALL_TILES) == 0))) return false; - } - - return InternalPost(err_message, callback, my_cmd, true, location, std::move(args)); + return InternalPost(err_message, callback, my_cmd, true, std::move(args)); } /** @@ -242,12 +235,7 @@ struct CommandHelper : protected C { auto args_tuple = std::forward_as_tuple(args...); - TileIndex tile{}; - if constexpr (std::is_same_v>) { - tile = std::get<0>(args_tuple); - } - - ::NetworkSendCommand(Tcmd, err_message, nullptr, _current_company, tile, EndianBufferWriter::FromValue(args_tuple)); + ::NetworkSendCommand(Tcmd, err_message, nullptr, company, EndianBufferWriter::FromValue(args_tuple)); } /** @@ -306,7 +294,7 @@ struct CommandHelper : protected C static bool InternalPost(StringID err_message, Tcallback *callback, bool my_cmd, bool network_command, TileIndex tile, std::tuple args) { /* Do not even think about executing out-of-bounds tile-commands. */ - if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (GetCommandFlags() & CMD_ALL_TILES) == 0))) return false; + if (tile != 0 && (tile >= Map::Size() || (!IsValidTile(tile) && (GetCommandFlags() & CMD_ALL_TILES) == 0))) return false; auto [err, estimate_only, only_sending] = InternalPostBefore(Tcmd, GetCommandFlags(), tile, err_message, network_command); if (err) return false; @@ -324,9 +312,9 @@ struct CommandHelper : protected C } else if constexpr (std::is_same_v) { /* Generic callback that takes packed arguments as a buffer. */ if constexpr (std::is_same_v) { - callback(Tcmd, ExtractCommandCost(res), tile, EndianBufferWriter::FromValue(args), {}); + callback(Tcmd, ExtractCommandCost(res), EndianBufferWriter::FromValue(args), {}); } else { - callback(Tcmd, ExtractCommandCost(res), tile, EndianBufferWriter::FromValue(args), EndianBufferWriter::FromValue(RemoveFirstTupleElement(res))); + callback(Tcmd, ExtractCommandCost(res), EndianBufferWriter::FromValue(args), EndianBufferWriter::FromValue(RemoveFirstTupleElement(res))); } } else if constexpr (!std::is_same_v && std::is_same_v::RetCallbackProc>) { std::apply(callback, std::tuple_cat(std::make_tuple(Tcmd), res)); @@ -405,7 +393,7 @@ struct CommandHelper : protected C /* If we are in network, and the command is not from the network * send it to the command-queue and abort execution. */ if (send_net) { - ::NetworkSendCommand(Tcmd, err_message, callback, _current_company, tile, EndianBufferWriter::FromValue(args)); + ::NetworkSendCommand(Tcmd, err_message, callback, _current_company, EndianBufferWriter::FromValue(args)); cur_company.Restore(); /* Don't return anything special here; no error, no costs. @@ -446,18 +434,23 @@ struct CommandHelper : protected C template struct CommandHelper : CommandHelper { - /* Import Post overloads from our base class. */ - using CommandHelper::Post; + /* Do not allow Post without explicit location. */ + static inline bool Post(StringID err_message, Targs... args) = delete; + template + static inline bool Post(Tcallback *callback, Targs... args) = delete; + static inline bool Post(Targs... args) = delete; + template + static bool Post(StringID err_message, Tcallback *callback, Targs... args) = delete; /** - * Shortcut for Post when not using an error message. + * Shortcut for Post when not using a callback. * @param err_message Message prefix to show on error * @param location Tile location for user feedback. * @param args Parameters for the command */ static inline bool Post(StringID err_message, TileIndex location, Targs... args) { return Post(err_message, nullptr, location, std::forward(args)...); } /** - * Shortcut for Post when not using a callback. + * Shortcut for Post when not using an error message. * @param callback A callback function to call after the command is finished * @param location Tile location for user feedback. * @param args Parameters for the command @@ -476,7 +469,6 @@ struct CommandHelper : CommandHel * commands that don't take a TileIndex by themselves. * @param err_message Message prefix to show on error * @param callback A callback function to call after the command is finished - * @param location Tile location for user feedback. * @param args Parameters for the command * @return \c true if the command succeeded, else \c false. */ @@ -492,6 +484,6 @@ struct CommandHelper : CommandHel #endif template -using Command = CommandHelper::ProcType, std::is_same_v::Args>>>; +using Command = CommandHelper::ProcType, (GetCommandFlags() & CMD_LOCATION) == 0>; #endif /* COMMAND_FUNC_H */ diff --git a/src/command_type.h b/src/command_type.h index 9a122dede0354..3ade17ed7b955 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -22,12 +22,13 @@ struct GRFFile; * a possible error message/state together. */ class CommandCost { - ExpensesType expense_type; ///< the type of expence as shown on the finances view - Money cost; ///< The cost of this action - StringID message; ///< Warning message for when success is unset - bool success; ///< Whether the comment went fine up to this moment - const GRFFile *textref_stack_grffile; ///< NewGRF providing the #TextRefStack content. - uint textref_stack_size; ///< Number of uint32 values to put on the #TextRefStack for the error message. + ExpensesType expense_type; ///< the type of expence as shown on the finances view + Money cost; ///< The cost of this action + StringID message; ///< Warning message for when success is unset + bool success; ///< Whether the command went fine up to this moment + const GRFFile *textref_stack_grffile; ///< NewGRF providing the #TextRefStack content. + uint textref_stack_size; ///< Number of uint32 values to put on the #TextRefStack for the error message. + StringID extra_message = INVALID_STRING_ID; ///< Additional warning message for when success is unset static uint32 textref_stack[16]; @@ -38,9 +39,9 @@ class CommandCost { CommandCost() : expense_type(INVALID_EXPENSES), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_grffile(nullptr), textref_stack_size(0) {} /** - * Creates a command return value the is failed with the given message + * Creates a command return value with one, or optionally two, error message strings. */ - explicit CommandCost(StringID msg) : expense_type(INVALID_EXPENSES), cost(0), message(msg), success(false), textref_stack_grffile(nullptr), textref_stack_size(0) {} + explicit CommandCost(StringID msg, StringID extra_msg = INVALID_STRING_ID) : expense_type(INVALID_EXPENSES), cost(0), message(msg), success(false), textref_stack_grffile(nullptr), textref_stack_size(0), extra_message(extra_msg) {} /** * Creates a command cost with given expense type and start cost of 0 @@ -98,11 +99,12 @@ class CommandCost { * Makes this #CommandCost behave like an error command. * @param message The error message. */ - void MakeError(StringID message) + void MakeError(StringID message, StringID extra_message = INVALID_STRING_ID) { assert(message != INVALID_STRING_ID); this->success = false; this->message = message; + this->extra_message = extra_message; } void UseTextRefStack(const GRFFile *grffile, uint num_registers); @@ -144,6 +146,16 @@ class CommandCost { return this->message; } + /** + * Returns the extra error message of a command + * @return the extra error message, if succeeded #INVALID_STRING_ID + */ + StringID GetExtraErrorMessage() const + { + if (this->success) return INVALID_STRING_ID; + return this->extra_message; + } + /** * Did this command succeed? * @return true if and only if it succeeded @@ -186,6 +198,7 @@ enum Commands : uint16 { CMD_REMOVE_SIGNALS, ///< remove a signal CMD_TERRAFORM_LAND, ///< terraform a tile CMD_BUILD_OBJECT, ///< build an object + CMD_BUILD_OBJECT_AREA, ///< build an area of objects CMD_BUILD_TUNNEL, ///< build a tunnel CMD_REMOVE_FROM_RAIL_STATION, ///< remove a (rectangle of) tiles from a rail station @@ -231,7 +244,9 @@ enum Commands : uint16 { CMD_CHANGE_SERVICE_INT, ///< change the server interval of a vehicle CMD_BUILD_INDUSTRY, ///< build a new industry - CMD_INDUSTRY_CTRL, ///< change industry properties + CMD_INDUSTRY_SET_FLAGS, ///< change industry control flags + CMD_INDUSTRY_SET_EXCLUSIVITY, ///< change industry exclusive consumer/supplier + CMD_INDUSTRY_SET_TEXT, ///< change additional text for the industry CMD_SET_COMPANY_MANAGER_FACE, ///< set the manager's face of the company CMD_SET_COMPANY_COLOUR, ///< set the colour of the company @@ -330,12 +345,19 @@ enum Commands : uint16 { CMD_MOVE_ORDER, ///< move an order CMD_CHANGE_TIMETABLE, ///< change the timetable for a vehicle + CMD_BULK_CHANGE_TIMETABLE, ///< change the timetable for all orders of a vehicle CMD_SET_VEHICLE_ON_TIME, ///< set the vehicle on time feature (timetable) CMD_AUTOFILL_TIMETABLE, ///< autofill the timetable CMD_SET_TIMETABLE_START, ///< set the date that a timetable should start CMD_OPEN_CLOSE_AIRPORT, ///< open/close an airport to incoming aircraft + CMD_CREATE_LEAGUE_TABLE, ///< create a new league table + CMD_CREATE_LEAGUE_TABLE_ELEMENT, ///< create a new element in a league table + CMD_UPDATE_LEAGUE_TABLE_ELEMENT_DATA, ///< update the data fields of a league table element + CMD_UPDATE_LEAGUE_TABLE_ELEMENT_SCORE, ///< update the score of a league table element + CMD_REMOVE_LEAGUE_TABLE_ELEMENT, ///< remove a league table element + CMD_END, ///< Must ALWAYS be on the end of this list!! (period) }; @@ -378,6 +400,7 @@ enum CommandFlags { CMD_DEITY = 0x100, ///< the command may be executed by COMPANY_DEITY CMD_STR_CTRL = 0x200, ///< the command's string may contain control strings CMD_NO_EST = 0x400, ///< the command is never estimated. + CMD_LOCATION = 0x800, ///< the command has implicit location argument. }; DECLARE_ENUM_AS_BIT_SET(CommandFlags) @@ -469,6 +492,6 @@ typedef void CommandCallback(Commands cmd, const CommandCost &result, TileIndex * @param result_data Additional returned data from the command * @see CommandProc */ -typedef void CommandCallbackData(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, CommandDataBuffer result_data); +typedef void CommandCallbackData(Commands cmd, const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data); #endif /* COMMAND_TYPE_H */ diff --git a/src/company_base.h b/src/company_base.h index 123865a90258f..16e22b2fea023 100644 --- a/src/company_base.h +++ b/src/company_base.h @@ -87,6 +87,7 @@ struct CompanyProperties { uint32 terraform_limit; ///< Amount of tileheights we can (still) terraform (times 65536). uint32 clear_limit; ///< Amount of tiles we can (still) clear (times 65536). uint32 tree_limit; ///< Amount of trees we can (still) plant (times 65536). + uint32 build_object_limit; ///< Amount of tiles we can (still) build objects on (times 65536). Also applies to buying land. /** * If \c true, the company is (also) controlled by the computer (a NoAI program). @@ -110,7 +111,7 @@ struct CompanyProperties { face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0), location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0), months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0), - terraform_limit(0), clear_limit(0), tree_limit(0), is_ai(false), engine_renew_list(nullptr) {} + terraform_limit(0), clear_limit(0), tree_limit(0), build_object_limit(0), is_ai(false), engine_renew_list(nullptr) {} }; struct Company : CompanyProperties, CompanyPool::PoolItem<&_company_pool> { diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index ccec23eae79c8..acd66858ecf99 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -42,6 +42,7 @@ #include "safeguards.h" void ClearEnginesHiddenFlagOfCompany(CompanyID cid); +void UpdateObjectColours(const Company *c); CompanyID _local_company; ///< Company controlled by the human player at this client. Can also be #COMPANY_SPECTATOR. CompanyID _current_company; ///< Company currently doing an action. @@ -63,9 +64,10 @@ Company::Company(uint16 name_1, bool is_ai) this->name_1 = name_1; this->location_of_HQ = INVALID_TILE; this->is_ai = is_ai; - this->terraform_limit = (uint32)_settings_game.construction.terraform_frame_burst << 16; - this->clear_limit = (uint32)_settings_game.construction.clear_frame_burst << 16; - this->tree_limit = (uint32)_settings_game.construction.tree_frame_burst << 16; + this->terraform_limit = (uint32)_settings_game.construction.terraform_frame_burst << 16; + this->clear_limit = (uint32)_settings_game.construction.clear_frame_burst << 16; + this->tree_limit = (uint32)_settings_game.construction.tree_frame_burst << 16; + this->build_object_limit = (uint32)_settings_game.construction.build_object_frame_burst << 16; std::fill(this->share_owners.begin(), this->share_owners.end(), INVALID_OWNER); InvalidateWindowData(WC_PERFORMANCE_DETAIL, 0, INVALID_COMPANY); @@ -114,8 +116,11 @@ void SetLocalCompany(CompanyID new_company) _current_company = _local_company = new_company; - /* Delete any construction windows... */ - if (switching_company) CloseConstructionWindows(); + if (switching_company) { + InvalidateWindowClassesData(WC_COMPANY); + /* Delete any construction windows... */ + CloseConstructionWindows(); + } /* ... and redraw the whole screen. */ MarkWholeScreenDirty(); @@ -267,9 +272,10 @@ void SubtractMoneyFromCompanyFract(CompanyID company, const CommandCost &cst) void UpdateLandscapingLimits() { for (Company *c : Company::Iterate()) { - c->terraform_limit = std::min((uint64)c->terraform_limit + _settings_game.construction.terraform_per_64k_frames, (uint64)_settings_game.construction.terraform_frame_burst << 16); - c->clear_limit = std::min((uint64)c->clear_limit + _settings_game.construction.clear_per_64k_frames, (uint64)_settings_game.construction.clear_frame_burst << 16); - c->tree_limit = std::min((uint64)c->tree_limit + _settings_game.construction.tree_per_64k_frames, (uint64)_settings_game.construction.tree_frame_burst << 16); + c->terraform_limit = std::min((uint64)c->terraform_limit + _settings_game.construction.terraform_per_64k_frames, (uint64)_settings_game.construction.terraform_frame_burst << 16); + c->clear_limit = std::min((uint64)c->clear_limit + _settings_game.construction.clear_per_64k_frames, (uint64)_settings_game.construction.clear_frame_burst << 16); + c->tree_limit = std::min((uint64)c->tree_limit + _settings_game.construction.tree_per_64k_frames, (uint64)_settings_game.construction.tree_frame_burst << 16); + c->build_object_limit = std::min((uint64)c->build_object_limit + _settings_game.construction.build_object_per_64k_frames, (uint64)_settings_game.construction.build_object_frame_burst << 16); } } @@ -555,15 +561,23 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY) ResetCompanyLivery(c); _company_colours[c->index] = (Colours)c->colour; + /* Scale the initial loan based on the inflation rounded down to the loan interval. The maximum loan has already been inflation adjusted. */ auto initial_loan = INITIAL_LOAN * GetPaceFactor(); - c->money = c->current_loan = (std::min(initial_loan, _economy.max_loan) * _economy.inflation_prices >> 16) / 50000 * 50000; + c->money = c->current_loan = std::min((initial_loan * _economy.inflation_prices >> 16) / LOAN_INTERVAL * LOAN_INTERVAL, _economy.max_loan * GetPaceFactor()); std::fill(c->share_owners.begin(), c->share_owners.end(), INVALID_OWNER); c->avail_railtypes = GetCompanyRailtypes(c->index); c->avail_roadtypes = GetCompanyRoadTypes(c->index); c->inaugurated_year = _cur_year; - RandomCompanyManagerFaceBits(c->face, (GenderEthnicity)Random(), false, false); // create a random company manager face + + /* If starting a player company in singleplayer and a favorite company manager face is selected, choose it. Otherwise, use a random face. + * In a network game, we'll choose the favorite face later in CmdCompanyCtrl to sync it to all clients. */ + if (_company_manager_face != 0 && !is_ai && !_networking) { + c->face = _company_manager_face; + } else { + RandomCompanyManagerFaceBits(c->face, (GenderEthnicity)Random(), false, _random); + } SetDefaultCompanySettings(c->index); ClearEnginesHiddenFlagOfCompany(c->index); @@ -689,9 +703,9 @@ static void HandleBankruptcyTakeover(Company *c) SetBit(c->bankrupt_asked, best->index); c->bankrupt_timeout = TAKE_OVER_TIMEOUT; - if (best->is_ai) { - AI::NewEvent(best->index, new ScriptEventCompanyAskMerger(c->index, ClampToI32(c->bankrupt_value))); - } else if (IsInteractiveCompany(best->index)) { + + AI::NewEvent(best->index, new ScriptEventCompanyAskMerger(c->index, c->bankrupt_value)); + if (IsInteractiveCompany(best->index)) { ShowBuyCompanyDialog(c->index); } } @@ -839,6 +853,10 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass); } + /* In network games, we need to try setting the company manager face here to sync it to all clients. + * If a favorite company manager face is selected, choose it. Otherwise, use a random face. */ + if (_company_manager_face != 0) Command::SendNet(STR_NULL, c->index, _company_manager_face); + /* Now that we have a new company, broadcast our company settings to * all clients so everything is in sync */ SyncCompanySettings(); @@ -877,8 +895,6 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID if (!(flags & DC_EXEC)) return CommandCost(); - /* Delete any open window of the company */ - CloseCompanyWindows(c->index); CompanyNewsInformation *cni = new CompanyNewsInformation(c); /* Show the bankrupt news */ @@ -907,8 +923,8 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID } InvalidateWindowClassesData(WC_GAME_OPTIONS); - InvalidateWindowClassesData(WC_AI_SETTINGS); - InvalidateWindowClassesData(WC_AI_LIST); + InvalidateWindowClassesData(WC_SCRIPT_SETTINGS); + InvalidateWindowClassesData(WC_SCRIPT_LIST); return CommandCost(); } @@ -1016,7 +1032,6 @@ CommandCost CmdSetCompanyColour(DoCommandFlag flags, LiveryScheme scheme, bool p if (v->owner == _current_company) v->InvalidateNewGRFCache(); } - extern void UpdateObjectColours(const Company *c); UpdateObjectColours(c); } return CommandCost(); diff --git a/src/company_gui.cpp b/src/company_gui.cpp index 8e0f1e877423a..ea0c9df3942a0 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.cpp @@ -49,10 +49,6 @@ /** Company GUI constants. */ -static const uint EXP_LINESPACE = 2; ///< Amount of vertical space for a horizontal (sub-)total line. -static const uint EXP_BLOCKSPACE = 10; ///< Amount of vertical space between two blocks of numbers. -static const int EXP_INDENT = 10; ///< Amount of horizontal space for an indented line. - static void DoSelectCompanyManagerFace(Window *parent); static void ShowCompanyInfrastructure(CompanyID company); @@ -122,15 +118,15 @@ static const ExpensesList _expenses_list_types[] = { static uint GetTotalCategoriesHeight() { /* There's an empty line and blockspace on the year row */ - uint total_height = FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE; + uint total_height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide; for (uint i = 0; i < lengthof(_expenses_list_types); i++) { /* Title + expense list + total line + total + blockspace after category */ - total_height += FONT_HEIGHT_NORMAL + _expenses_list_types[i].GetHeight() + EXP_LINESPACE + FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE; + total_height += FONT_HEIGHT_NORMAL + _expenses_list_types[i].GetHeight() + WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide; } /* Total income */ - total_height += EXP_LINESPACE + FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE; + total_height += WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide; return total_height; } @@ -148,7 +144,7 @@ static uint GetMaxCategoriesWidth() /* Title of category */ max_width = std::max(max_width, GetStringBoundingBox(STR_FINANCES_REVENUE_TITLE + i).width); /* Entries in category */ - max_width = std::max(max_width, _expenses_list_types[i].GetListWidth()); + max_width = std::max(max_width, _expenses_list_types[i].GetListWidth() + WidgetDimensions::scaled.hsep_indent); } return max_width; @@ -159,16 +155,15 @@ static uint GetMaxCategoriesWidth() */ static void DrawCategory(const Rect &r, int start_y, ExpensesList list) { - int offs_left = _current_text_dir == TD_LTR ? EXP_INDENT : 0; - int offs_right = _current_text_dir == TD_LTR ? 0 : EXP_INDENT; + Rect tr = r.Indent(WidgetDimensions::scaled.hsep_indent, _current_text_dir == TD_RTL); - int y = start_y; + tr.top = start_y; ExpensesType et; for (uint i = 0; i < list.length; i++) { et = list.et[i]; - DrawString(r.left + offs_left, r.right - offs_right, y, STR_FINANCES_SECTION_CONSTRUCTION + et); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_FINANCES_SECTION_CONSTRUCTION + et); + tr.top += FONT_HEIGHT_NORMAL; } } @@ -180,7 +175,7 @@ static void DrawCategory(const Rect &r, int start_y, ExpensesList list) static void DrawCategories(const Rect &r) { /* Start with an empty space in the year row, plus the blockspace under the year. */ - int y = r.top + FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE; + int y = r.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide; for (uint i = 0; i < lengthof(_expenses_list_types); i++) { /* Draw category title and advance y */ @@ -191,16 +186,20 @@ static void DrawCategories(const Rect &r) DrawCategory(r, y, _expenses_list_types[i]); y += _expenses_list_types[i].GetHeight(); - /* Advance y by the height of the total and associated total line */ - y += EXP_LINESPACE + FONT_HEIGHT_NORMAL; + /* Advance y by the height of the horizontal line between amounts and subtotal */ + y += WidgetDimensions::scaled.vsep_normal; + + /* Draw category total and advance y */ + DrawString(r.left, r.right, y, STR_FINANCES_TOTAL_CAPTION, TC_FROMSTRING, SA_RIGHT); + y += FONT_HEIGHT_NORMAL; /* Advance y by a blockspace after this category block */ - y += EXP_BLOCKSPACE; + y += WidgetDimensions::scaled.vsep_wide; } /* Draw total profit/loss */ - y += EXP_LINESPACE; - DrawString(r.left, r.right, y, STR_FINANCES_NET_PROFIT, TC_FROMSTRING, SA_LEFT); + y += WidgetDimensions::scaled.vsep_normal; + DrawString(r.left, r.right, y, STR_FINANCES_PROFIT, TC_FROMSTRING, SA_LEFT); } /** @@ -214,9 +213,11 @@ static void DrawCategories(const Rect &r) static void DrawPrice(Money amount, int left, int right, int top, TextColour colour) { StringID str = STR_FINANCES_NEGATIVE_INCOME; - if (amount < 0) { + if (amount == 0) { + str = STR_FINANCES_ZERO_INCOME; + } else if (amount < 0) { amount = -amount; - str++; + str = STR_FINANCES_POSITIVE_INCOME; } SetDParam(0, amount); DrawString(left, right, top, str, colour, SA_RIGHT); @@ -226,7 +227,7 @@ static void DrawPrice(Money amount, int left, int right, int top, TextColour col * Draw a category of expenses/revenues in the year column. * @return The income sum of the category. */ -static Money DrawYearCategory (const Rect &r, int start_y, ExpensesList list, const Money(*tbl)[EXPENSES_END]) +static Money DrawYearCategory (const Rect &r, int start_y, ExpensesList list, const Money(&tbl)[EXPENSES_END]) { int y = start_y; ExpensesType et; @@ -234,7 +235,7 @@ static Money DrawYearCategory (const Rect &r, int start_y, ExpensesList list, co for (uint i = 0; i < list.length; i++) { et = list.et[i]; - Money cost = (*tbl)[et]; + Money cost = tbl[et]; sum += cost; if (cost != 0) DrawPrice(cost, r.left, r.right, y, TC_BLACK); y += FONT_HEIGHT_NORMAL; @@ -242,7 +243,7 @@ static Money DrawYearCategory (const Rect &r, int start_y, ExpensesList list, co /* Draw the total at the bottom of the category. */ GfxFillRect(r.left, y, r.right, y, PC_BLACK); - y += EXP_LINESPACE; + y += WidgetDimensions::scaled.vsep_normal; if (sum != 0) DrawPrice(sum, r.left, r.right, y, TC_WHITE); /* Return the sum for the yearly total. */ @@ -254,10 +255,10 @@ static Money DrawYearCategory (const Rect &r, int start_y, ExpensesList list, co * Draw a column with prices. * @param r Available space for drawing. * @param year Year being drawn. - * @param tbl Pointer to table of amounts for \a year. + * @param tbl Reference to table of amounts for \a year. * @note The environment must provide padding at the left and right of \a r. */ -static void DrawYearColumn(const Rect &r, int year, const Money (*tbl)[EXPENSES_END]) +static void DrawYearColumn(const Rect &r, int year, const Money (&tbl)[EXPENSES_END]) { int y = r.top; Money sum; @@ -265,19 +266,19 @@ static void DrawYearColumn(const Rect &r, int year, const Money (*tbl)[EXPENSES_ /* Year header */ SetDParam(0, year); DrawString(r.left, r.right, y, STR_FINANCES_YEAR, TC_FROMSTRING, SA_RIGHT, true); - y += FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE; + y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide; /* Categories */ for (uint i = 0; i < lengthof(_expenses_list_types); i++) { y += FONT_HEIGHT_NORMAL; sum += DrawYearCategory(r, y, _expenses_list_types[i], tbl); /* Expense list + expense category title + expense category total + blockspace after category */ - y += _expenses_list_types[i].GetHeight() + EXP_LINESPACE + FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE; + y += _expenses_list_types[i].GetHeight() + WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide; } /* Total income. */ GfxFillRect(r.left, y, r.right, y, PC_BLACK); - y += EXP_LINESPACE; + y += WidgetDimensions::scaled.vsep_normal; DrawPrice(sum, r.left, r.right, y, TC_WHITE); } @@ -291,7 +292,7 @@ static const NWidgetPart _nested_company_finances_widgets[] = { EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_CF_SEL_PANEL), NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM, WD_FRAMERECT_LEFT), SetPIP(0, 9, 0), + NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CF_EXPS_CATEGORY), SetMinimalSize(120, 0), SetFill(0, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CF_EXPS_PRICE1), SetMinimalSize(86, 0), SetFill(0, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CF_EXPS_PRICE2), SetMinimalSize(86, 0), SetFill(0, 0), @@ -300,7 +301,7 @@ static const NWidgetPart _nested_company_finances_widgets[] = { EndContainer(), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM, WD_FRAMERECT_LEFT), + NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect), NWidget(NWID_VERTICAL), // Vertical column with 'bank balance', 'loan' NWidget(WWT_TEXT, COLOUR_GREY), SetDataTip(STR_FINANCES_OWN_FUNDS_TITLE, STR_NULL), SetFill(1, 0), NWidget(WWT_TEXT, COLOUR_GREY), SetDataTip(STR_FINANCES_LOAN_TITLE, STR_NULL), SetFill(1, 0), @@ -313,7 +314,7 @@ static const NWidgetPart _nested_company_finances_widgets[] = { NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_OWN_VALUE), SetDataTip(STR_FINANCES_TOTAL_CURRENCY, STR_NULL), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_LOAN_VALUE), SetDataTip(STR_FINANCES_TOTAL_CURRENCY, STR_NULL), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CF_BALANCE_LINE), SetMinimalSize(0, 2), SetFill(1, 0), - NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_BALANCE_VALUE), SetDataTip(STR_FINANCES_TOTAL_CURRENCY, STR_NULL), SetAlignment(SA_VERT_CENTER | SA_RIGHT), + NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_BALANCE_VALUE), SetDataTip(STR_FINANCES_BANK_BALANCE, STR_NULL), SetAlignment(SA_VERT_CENTER | SA_RIGHT), EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_CF_SEL_MAXLOAN), NWidget(NWID_HORIZONTAL), @@ -434,7 +435,7 @@ struct CompanyFinancesWindow : Window { int age = std::min(_cur_year - c->inaugurated_year, 2); int wid_offset = widget - WID_CF_EXPS_PRICE1; if (wid_offset <= age) { - DrawYearColumn(r, _cur_year - (age - wid_offset), c->yearly_expenses + (age - wid_offset)); + DrawYearColumn(r, _cur_year - (age - wid_offset), c->yearly_expenses[age - wid_offset]); } break; } @@ -601,23 +602,20 @@ class DropDownListColourItem : public DropDownListItem { return true; } - void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const override + void Draw(const Rect &r, bool sel, Colours bg_colour) const override { bool rtl = _current_text_dir == TD_RTL; - int height = bottom - top; - int icon_y_offset = height / 2; - int text_y_offset = (height - FONT_HEIGHT_NORMAL) / 2 + 1; + int icon_y = CenterBounds(r.top, r.bottom, 0); + int text_y = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL); + Rect tr = r.Shrink(WidgetDimensions::scaled.dropdowntext); DrawSprite(SPR_VEH_BUS_SIDE_VIEW, PALETTE_RECOLOUR_START + (this->result % COLOUR_END), - rtl ? right - 2 - ScaleGUITrad(14) : left + ScaleGUITrad(14) + 2, - top + icon_y_offset); - DrawString(rtl ? left + 2 : left + ScaleGUITrad(28) + 4, - rtl ? right - ScaleGUITrad(28) - 4 : right - 2, - top + text_y_offset, this->String(), sel ? TC_WHITE : TC_BLACK); + rtl ? tr.right - ScaleGUITrad(14) : tr.left + ScaleGUITrad(14), + icon_y); + tr = tr.Indent(ScaleGUITrad(28) + WidgetDimensions::scaled.hsep_normal, rtl); + DrawString(tr.left, tr.right, text_y, this->String(), sel ? TC_WHITE : TC_BLACK); } }; -static const int LEVEL_WIDTH = 10; ///< Indenting width of a sub-group in pixels - typedef GUIList GUIGroupList; /** Company livery colour scheme window. */ @@ -635,10 +633,9 @@ struct SelectCompanyLiveryWindow : public Window { void ShowColourDropDownMenu(uint32 widget) { uint32 used_colours = 0; - const Company *c; const Livery *livery, *default_livery = nullptr; bool primary = widget == WID_SCL_PRI_COL_DROPDOWN; - byte default_col; + byte default_col = 0; /* Disallow other company colours for the primary colour */ if (this->livery_class < LC_GROUP_RAIL && HasBit(this->sel, LS_DEFAULT) && primary) { @@ -647,7 +644,7 @@ struct SelectCompanyLiveryWindow : public Window { } } - c = Company::Get((CompanyID)this->window_number); + const Company *c = Company::Get((CompanyID)this->window_number); if (this->livery_class < LC_GROUP_RAIL) { /* Get the first selected livery to use as the default dropdown item */ @@ -798,7 +795,7 @@ struct SelectCompanyLiveryWindow : public Window { /* Position scrollbar to selected group */ for (uint i = 0; i < this->rows; i++) { if (this->groups[i]->index == sel) { - this->vscroll->SetPosition(Clamp(i - this->vscroll->GetCapacity() / 2, 0, std::max(this->vscroll->GetCount() - this->vscroll->GetCapacity(), 0))); + this->vscroll->SetPosition(i - this->vscroll->GetCapacity() / 2); break; } } @@ -822,14 +819,14 @@ struct SelectCompanyLiveryWindow : public Window { } } - size->width = std::max(size->width, 5 + d.width + WD_FRAMERECT_RIGHT); + size->width = std::max(size->width, 5 + d.width + padding.width); break; } case WID_SCL_MATRIX: { /* 11 items in the default rail class */ this->square = GetSpriteSize(SPR_SQUARE); - this->line_height = std::max(this->square.height, (uint)FONT_HEIGHT_NORMAL) + 4; + this->line_height = std::max(this->square.height, (uint)FONT_HEIGHT_NORMAL) + padding.height; size->height = 11 * this->line_height; resize->width = 1; @@ -846,7 +843,7 @@ struct SelectCompanyLiveryWindow : public Window { case WID_SCL_PRI_COL_DROPDOWN: { this->square = GetSpriteSize(SPR_SQUARE); - int string_padding = this->square.width + NWidgetScrollbar::GetVerticalDimension().width + 10; + int string_padding = this->square.width + WidgetDimensions::scaled.hsep_normal + padding.width; for (const StringID *id = _colour_dropdown; id != endof(_colour_dropdown); id++) { size->width = std::max(size->width, GetStringBoundingBox(*id).width + string_padding); } @@ -916,40 +913,41 @@ struct SelectCompanyLiveryWindow : public Window { bool rtl = _current_text_dir == TD_RTL; - /* Horizontal coordinates of scheme name column. */ + /* Coordinates of scheme name column. */ const NWidgetBase *nwi = this->GetWidget(WID_SCL_SPACER_DROPDOWN); - int sch_left = nwi->pos_x; - int sch_right = sch_left + nwi->current_x - 1; - /* Horizontal coordinates of first dropdown. */ + Rect sch = nwi->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); + /* Coordinates of first dropdown. */ nwi = this->GetWidget(WID_SCL_PRI_COL_DROPDOWN); - int pri_left = nwi->pos_x; - int pri_right = pri_left + nwi->current_x - 1; - /* Horizontal coordinates of second dropdown. */ + Rect pri = nwi->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); + /* Coordinates of second dropdown. */ nwi = this->GetWidget(WID_SCL_SEC_COL_DROPDOWN); - int sec_left = nwi->pos_x; - int sec_right = sec_left + nwi->current_x - 1; + Rect sec = nwi->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); - int text_left = (rtl ? (uint)WD_FRAMERECT_LEFT : (this->square.width + 5)); - int text_right = (rtl ? (this->square.width + 5) : (uint)WD_FRAMERECT_RIGHT); + Rect pri_squ = pri.WithWidth(this->square.width, rtl); + Rect sec_squ = sec.WithWidth(this->square.width, rtl); - int square_offs = (this->line_height - this->square.height) / 2 + 1; - int text_offs = (this->line_height - FONT_HEIGHT_NORMAL) / 2 + 1; + pri = pri.Indent(this->square.width + WidgetDimensions::scaled.hsep_normal, rtl); + sec = sec.Indent(this->square.width + WidgetDimensions::scaled.hsep_normal, rtl); - int y = r.top; + Rect ir = r.WithHeight(this->resize.step_height).Shrink(WidgetDimensions::scaled.matrix); + int square_offs = (ir.Height() - this->square.height) / 2; + int text_offs = (ir.Height() - FONT_HEIGHT_NORMAL) / 2; + + int y = ir.top; /* Helper function to draw livery info. */ auto draw_livery = [&](StringID str, const Livery &liv, bool sel, bool def, int indent) { /* Livery Label. */ - DrawString(sch_left + WD_FRAMERECT_LEFT + (rtl ? 0 : indent), sch_right - WD_FRAMERECT_RIGHT - (rtl ? indent : 0), y + text_offs, str, sel ? TC_WHITE : TC_BLACK); + DrawString(sch.left + (rtl ? 0 : indent), sch.right - (rtl ? indent : 0), y + text_offs, str, sel ? TC_WHITE : TC_BLACK); /* Text below the first dropdown. */ - DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour1), (rtl ? pri_right - (this->square.width + 5) + WD_FRAMERECT_RIGHT : pri_left) + WD_FRAMERECT_LEFT, y + square_offs); - DrawString(pri_left + text_left, pri_right - text_right, y + text_offs, (def || HasBit(liv.in_use, 0)) ? STR_COLOUR_DARK_BLUE + liv.colour1 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD); + DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour1), pri_squ.left, y + square_offs); + DrawString(pri.left, pri.right, y + text_offs, (def || HasBit(liv.in_use, 0)) ? STR_COLOUR_DARK_BLUE + liv.colour1 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD); /* Text below the second dropdown. */ - if (sec_right > sec_left) { // Second dropdown has non-zero size. - DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour2), (rtl ? sec_right - (this->square.width + 5) + WD_FRAMERECT_RIGHT : sec_left) + WD_FRAMERECT_LEFT, y + square_offs); - DrawString(sec_left + text_left, sec_right - text_right, y + text_offs, (def || HasBit(liv.in_use, 1)) ? STR_COLOUR_DARK_BLUE + liv.colour2 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD); + if (sec.right > sec.left) { // Second dropdown has non-zero size. + DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour2), sec_squ.left, y + square_offs); + DrawString(sec.left, sec.right, y + text_offs, (def || HasBit(liv.in_use, 1)) ? STR_COLOUR_DARK_BLUE + liv.colour2 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD); } y += this->line_height; @@ -969,7 +967,7 @@ struct SelectCompanyLiveryWindow : public Window { for (uint i = this->vscroll->GetPosition(); i < max; ++i) { const Group *g = this->groups[i]; SetDParam(0, g->index); - draw_livery(STR_GROUP_NAME, g->livery, this->sel == g->index, false, this->indents[i] * LEVEL_WIDTH); + draw_livery(STR_GROUP_NAME, g->livery, this->sel == g->index, false, this->indents[i] * WidgetDimensions::scaled.hsep_indent); } } } @@ -1267,84 +1265,84 @@ static const NWidgetPart _nested_select_company_manager_face_widgets[] = { EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 4), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_EYECOLOUR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_MOUSTACHE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_MOUSTACHE_EARRING_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_MOUSTACHE_EARRING), SetDataTip(STR_WHITE_STRING, STR_FACE_MOUSTACHE_EARRING_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_GLASSES_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_GLASSES_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_GLASSES, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_GLASSES), SetDataTip(STR_WHITE_STRING, STR_FACE_GLASSES_TOOLTIP), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAIR_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAIR_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_HAIR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_L), SetDataTip(AWV_DECREASE, STR_FACE_HAIR_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAIR), SetDataTip(STR_EMPTY, STR_FACE_HAIR_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAIR), SetDataTip(STR_WHITE_STRING, STR_FACE_HAIR_TOOLTIP), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_R), SetDataTip(AWV_INCREASE, STR_FACE_HAIR_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYEBROWS_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYEBROWS_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_EYEBROWS, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_L), SetDataTip(AWV_DECREASE, STR_FACE_EYEBROWS_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYEBROWS), SetDataTip(STR_EMPTY, STR_FACE_EYEBROWS_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYEBROWS), SetDataTip(STR_WHITE_STRING, STR_FACE_EYEBROWS_TOOLTIP), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_R), SetDataTip(AWV_INCREASE, STR_FACE_EYEBROWS_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYECOLOUR_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYECOLOUR_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_EYECOLOUR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_L), SetDataTip(AWV_DECREASE, STR_FACE_EYECOLOUR_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR), SetDataTip(STR_EMPTY, STR_FACE_EYECOLOUR_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR), SetDataTip(STR_WHITE_STRING, STR_FACE_EYECOLOUR_TOOLTIP), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_R), SetDataTip(AWV_INCREASE, STR_FACE_EYECOLOUR_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_GLASSES_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_GLASSES_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_GLASSES, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_L), SetDataTip(AWV_DECREASE, STR_FACE_GLASSES_TOOLTIP_2), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP_2), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_GLASSES), SetDataTip(STR_WHITE_STRING, STR_FACE_GLASSES_TOOLTIP_2), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_R), SetDataTip(AWV_INCREASE, STR_FACE_GLASSES_TOOLTIP_2), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_NOSE_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_NOSE_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_NOSE, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_L), SetDataTip(AWV_DECREASE, STR_FACE_NOSE_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_NOSE), SetDataTip(STR_EMPTY, STR_FACE_NOSE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_NOSE), SetDataTip(STR_WHITE_STRING, STR_FACE_NOSE_TOOLTIP), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_R), SetDataTip(AWV_INCREASE, STR_FACE_NOSE_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_LIPS_MOUSTACHE_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_LIPS_MOUSTACHE_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_MOUSTACHE, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_L), SetDataTip(AWV_DECREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE), SetDataTip(STR_EMPTY, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE), SetDataTip(STR_WHITE_STRING, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_R), SetDataTip(AWV_INCREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_CHIN_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_CHIN_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_CHIN, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_L), SetDataTip(AWV_DECREASE, STR_FACE_CHIN_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_CHIN), SetDataTip(STR_EMPTY, STR_FACE_CHIN_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_CHIN), SetDataTip(STR_WHITE_STRING, STR_FACE_CHIN_TOOLTIP), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_R), SetDataTip(AWV_INCREASE, STR_FACE_CHIN_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_JACKET_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_JACKET_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_JACKET, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_L), SetDataTip(AWV_DECREASE, STR_FACE_JACKET_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_JACKET), SetDataTip(STR_EMPTY, STR_FACE_JACKET_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_JACKET), SetDataTip(STR_WHITE_STRING, STR_FACE_JACKET_TOOLTIP), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_R), SetDataTip(AWV_INCREASE, STR_FACE_JACKET_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_COLLAR_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_COLLAR_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_COLLAR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_L), SetDataTip(AWV_DECREASE, STR_FACE_COLLAR_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_COLLAR), SetDataTip(STR_EMPTY, STR_FACE_COLLAR_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_COLLAR), SetDataTip(STR_WHITE_STRING, STR_FACE_COLLAR_TOOLTIP), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_R), SetDataTip(AWV_INCREASE, STR_FACE_COLLAR_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_TIE_EARRING_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), + NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_TIE_EARRING_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_FACE_EARRING, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_L), SetDataTip(AWV_DECREASE, STR_FACE_TIE_EARRING_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_TIE_EARRING_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING), SetDataTip(STR_WHITE_STRING, STR_FACE_TIE_EARRING_TOOLTIP), NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_R), SetDataTip(AWV_INCREASE, STR_FACE_TIE_EARRING_TOOLTIP), EndContainer(), NWidget(NWID_SPACER), SetFill(0, 1), @@ -1374,29 +1372,26 @@ class SelectCompanyManagerFaceWindow : public Window Dimension number_dim; ///< Dimension of a number widget of a part in the advanced face window. /** - * Draw dynamic a label to the left of the button and a value in the button + * Set parameters for value of face control buttons. * * @param widget_index index of this widget in the window - * @param val the value which will be draw + * @param val the value which will be displayed * @param is_bool_widget is it a bool button */ - void DrawFaceStringLabel(byte widget_index, uint8 val, bool is_bool_widget) const + void SetFaceStringParameters(byte widget_index, uint8 val, bool is_bool_widget) const { - StringID str; const NWidgetCore *nwi_widget = this->GetWidget(widget_index); - if (!nwi_widget->IsDisabled()) { + if (nwi_widget->IsDisabled()) { + SetDParam(0, STR_EMPTY); + } else { if (is_bool_widget) { /* if it a bool button write yes or no */ - str = (val != 0) ? STR_FACE_YES : STR_FACE_NO; + SetDParam(0, (val != 0) ? STR_FACE_YES : STR_FACE_NO); } else { /* else write the value + 1 */ - SetDParam(0, val + 1); - str = STR_JUST_INT; + SetDParam(0, STR_JUST_INT); + SetDParam(1, val + 1); } - - /* Draw the value/bool in white (0xC). If the button clicked adds 1px to x and y text coordinates (IsWindowWidgetLowered()). */ - DrawString(nwi_widget->pos_x + nwi_widget->IsLowered(), nwi_widget->pos_x + nwi_widget->current_x - 1 - nwi_widget->IsLowered(), - nwi_widget->pos_y + 1 + nwi_widget->IsLowered(), str, TC_WHITE, SA_HOR_CENTER); } } @@ -1448,17 +1443,17 @@ class SelectCompanyManagerFaceWindow : public Window { /* Size of the boolean yes/no button. */ Dimension yesno_dim = maxdim(GetStringBoundingBox(STR_FACE_YES), GetStringBoundingBox(STR_FACE_NO)); - yesno_dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - yesno_dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + yesno_dim.width += WidgetDimensions::scaled.framerect.Horizontal(); + yesno_dim.height += WidgetDimensions::scaled.framerect.Vertical(); /* Size of the number button + arrows. */ Dimension number_dim = {0, 0}; for (int val = 1; val <= 12; val++) { SetDParam(0, val); number_dim = maxdim(number_dim, GetStringBoundingBox(STR_JUST_INT)); } - uint arrows_width = GetSpriteSize(SPR_ARROW_LEFT).width + GetSpriteSize(SPR_ARROW_RIGHT).width + 2 * (WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT); - number_dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT + arrows_width; - number_dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + uint arrows_width = GetSpriteSize(SPR_ARROW_LEFT).width + GetSpriteSize(SPR_ARROW_RIGHT).width + 2 * (WidgetDimensions::scaled.imgbtn.Horizontal()); + number_dim.width += WidgetDimensions::scaled.framerect.Horizontal() + arrows_width; + number_dim.height += WidgetDimensions::scaled.framerect.Vertical(); /* Compute width of both buttons. */ yesno_dim.width = std::max(yesno_dim.width, number_dim.width); number_dim.width = yesno_dim.width - arrows_width; @@ -1573,65 +1568,70 @@ class SelectCompanyManagerFaceWindow : public Window this->DrawWidgets(); } - void DrawWidget(const Rect &r, int widget) const override + void SetStringParameters(int widget) const override { switch (widget) { case WID_SCMF_HAS_MOUSTACHE_EARRING: if (this->is_female) { // Only for female faces - this->DrawFaceStringLabel(WID_SCMF_HAS_MOUSTACHE_EARRING, GetCompanyManagerFaceBits(this->face, CMFV_HAS_TIE_EARRING, this->ge), true); + this->SetFaceStringParameters(WID_SCMF_HAS_MOUSTACHE_EARRING, GetCompanyManagerFaceBits(this->face, CMFV_HAS_TIE_EARRING, this->ge), true); } else { // Only for male faces - this->DrawFaceStringLabel(WID_SCMF_HAS_MOUSTACHE_EARRING, GetCompanyManagerFaceBits(this->face, CMFV_HAS_MOUSTACHE, this->ge), true); + this->SetFaceStringParameters(WID_SCMF_HAS_MOUSTACHE_EARRING, GetCompanyManagerFaceBits(this->face, CMFV_HAS_MOUSTACHE, this->ge), true); } break; case WID_SCMF_TIE_EARRING: - this->DrawFaceStringLabel(WID_SCMF_TIE_EARRING, GetCompanyManagerFaceBits(this->face, CMFV_TIE_EARRING, this->ge), false); + this->SetFaceStringParameters(WID_SCMF_TIE_EARRING, GetCompanyManagerFaceBits(this->face, CMFV_TIE_EARRING, this->ge), false); break; case WID_SCMF_LIPS_MOUSTACHE: if (this->is_moust_male) { // Only for male faces with moustache - this->DrawFaceStringLabel(WID_SCMF_LIPS_MOUSTACHE, GetCompanyManagerFaceBits(this->face, CMFV_MOUSTACHE, this->ge), false); + this->SetFaceStringParameters(WID_SCMF_LIPS_MOUSTACHE, GetCompanyManagerFaceBits(this->face, CMFV_MOUSTACHE, this->ge), false); } else { // Only for female faces or male faces without moustache - this->DrawFaceStringLabel(WID_SCMF_LIPS_MOUSTACHE, GetCompanyManagerFaceBits(this->face, CMFV_LIPS, this->ge), false); + this->SetFaceStringParameters(WID_SCMF_LIPS_MOUSTACHE, GetCompanyManagerFaceBits(this->face, CMFV_LIPS, this->ge), false); } break; case WID_SCMF_HAS_GLASSES: - this->DrawFaceStringLabel(WID_SCMF_HAS_GLASSES, GetCompanyManagerFaceBits(this->face, CMFV_HAS_GLASSES, this->ge), true ); + this->SetFaceStringParameters(WID_SCMF_HAS_GLASSES, GetCompanyManagerFaceBits(this->face, CMFV_HAS_GLASSES, this->ge), true ); break; case WID_SCMF_HAIR: - this->DrawFaceStringLabel(WID_SCMF_HAIR, GetCompanyManagerFaceBits(this->face, CMFV_HAIR, this->ge), false); + this->SetFaceStringParameters(WID_SCMF_HAIR, GetCompanyManagerFaceBits(this->face, CMFV_HAIR, this->ge), false); break; case WID_SCMF_EYEBROWS: - this->DrawFaceStringLabel(WID_SCMF_EYEBROWS, GetCompanyManagerFaceBits(this->face, CMFV_EYEBROWS, this->ge), false); + this->SetFaceStringParameters(WID_SCMF_EYEBROWS, GetCompanyManagerFaceBits(this->face, CMFV_EYEBROWS, this->ge), false); break; case WID_SCMF_EYECOLOUR: - this->DrawFaceStringLabel(WID_SCMF_EYECOLOUR, GetCompanyManagerFaceBits(this->face, CMFV_EYE_COLOUR, this->ge), false); + this->SetFaceStringParameters(WID_SCMF_EYECOLOUR, GetCompanyManagerFaceBits(this->face, CMFV_EYE_COLOUR, this->ge), false); break; case WID_SCMF_GLASSES: - this->DrawFaceStringLabel(WID_SCMF_GLASSES, GetCompanyManagerFaceBits(this->face, CMFV_GLASSES, this->ge), false); + this->SetFaceStringParameters(WID_SCMF_GLASSES, GetCompanyManagerFaceBits(this->face, CMFV_GLASSES, this->ge), false); break; case WID_SCMF_NOSE: - this->DrawFaceStringLabel(WID_SCMF_NOSE, GetCompanyManagerFaceBits(this->face, CMFV_NOSE, this->ge), false); + this->SetFaceStringParameters(WID_SCMF_NOSE, GetCompanyManagerFaceBits(this->face, CMFV_NOSE, this->ge), false); break; case WID_SCMF_CHIN: - this->DrawFaceStringLabel(WID_SCMF_CHIN, GetCompanyManagerFaceBits(this->face, CMFV_CHIN, this->ge), false); + this->SetFaceStringParameters(WID_SCMF_CHIN, GetCompanyManagerFaceBits(this->face, CMFV_CHIN, this->ge), false); break; case WID_SCMF_JACKET: - this->DrawFaceStringLabel(WID_SCMF_JACKET, GetCompanyManagerFaceBits(this->face, CMFV_JACKET, this->ge), false); + this->SetFaceStringParameters(WID_SCMF_JACKET, GetCompanyManagerFaceBits(this->face, CMFV_JACKET, this->ge), false); break; case WID_SCMF_COLLAR: - this->DrawFaceStringLabel(WID_SCMF_COLLAR, GetCompanyManagerFaceBits(this->face, CMFV_COLLAR, this->ge), false); + this->SetFaceStringParameters(WID_SCMF_COLLAR, GetCompanyManagerFaceBits(this->face, CMFV_COLLAR, this->ge), false); break; + } + } + void DrawWidget(const Rect &r, int widget) const override + { + switch (widget) { case WID_SCMF_FACE: DrawCompanyManagerFace(this->face, Company::Get((CompanyID)this->window_number)->colour, r.left, r.top); break; @@ -1693,7 +1693,7 @@ class SelectCompanyManagerFaceWindow : public Window /* Randomize face button */ case WID_SCMF_RANDOM_NEW_FACE: - RandomCompanyManagerFaceBits(this->face, this->ge, this->advanced); + RandomCompanyManagerFaceBits(this->face, this->ge, this->advanced, _interactive_random); this->UpdateData(); this->SetDirty(); break; @@ -1792,28 +1792,28 @@ static const NWidgetPart _nested_company_infrastructure_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_GREY), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_VERTICAL), SetPIP(WD_FRAMERECT_TOP, 4, WD_FRAMETEXT_BOTTOM), - NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2), + NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.framerect), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_RAIL_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_RAIL_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1), EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_ROAD_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_ROAD_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1), EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TRAM_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TRAM_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1), EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_WATER_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_WATER_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1), EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_STATION_DESC), SetMinimalTextLines(3, 0), SetFill(1, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_STATION_COUNT), SetMinimalTextLines(3, 0), SetFill(0, 1), EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TOTAL_DESC), SetFill(1, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TOTAL), SetFill(0, 1), EndContainer(), @@ -1914,12 +1914,12 @@ struct CompanyInfrastructureWindow : Window if (HasBit(this->railtypes, rt)) { lines++; SetDParam(0, GetRailTypeInfo(rt)->strings.name); - size->width = std::max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WD_FRAMERECT_LEFT); + size->width = std::max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WidgetDimensions::scaled.hsep_indent); } } if (this->railtypes != RAILTYPES_NONE) { lines++; - size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS).width + WD_FRAMERECT_LEFT); + size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS).width + WidgetDimensions::scaled.hsep_indent); } size->height = std::max(size->height, lines * FONT_HEIGHT_NORMAL); @@ -1936,7 +1936,7 @@ struct CompanyInfrastructureWindow : Window if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) { lines++; SetDParam(0, GetRoadTypeInfo(rt)->strings.name); - size->width = std::max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WD_FRAMERECT_LEFT); + size->width = std::max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WidgetDimensions::scaled.hsep_indent); } } @@ -1946,13 +1946,13 @@ struct CompanyInfrastructureWindow : Window case WID_CI_WATER_DESC: size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT).width); - size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS).width + WD_FRAMERECT_LEFT); + size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS).width + WidgetDimensions::scaled.hsep_indent); break; case WID_CI_STATION_DESC: size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT).width); - size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS).width + WD_FRAMERECT_LEFT); - size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS).width + WD_FRAMERECT_LEFT); + size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS).width + WidgetDimensions::scaled.hsep_indent); + size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS).width + WidgetDimensions::scaled.hsep_indent); break; case WID_CI_RAIL_COUNT: @@ -1986,11 +1986,11 @@ struct CompanyInfrastructureWindow : Window max_cost = std::max(max_cost, AirportMaintenanceCost(c->index)); SetDParamMaxValue(0, max_val); - uint count_width = GetStringBoundingBox(STR_WHITE_COMMA).width + 20; // Reserve some wiggle room + uint count_width = GetStringBoundingBox(STR_WHITE_COMMA).width + WidgetDimensions::scaled.hsep_indent; // Reserve some wiggle room if (_settings_game.economy.infrastructure_maintenance) { SetDParamMaxValue(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year - this->total_width = GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL).width + 20; + this->total_width = GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL).width + WidgetDimensions::scaled.hsep_indent * 2; size->width = std::max(size->width, this->total_width); SetDParamMaxValue(0, max_cost * 12); // Convert to per year @@ -2001,7 +2001,7 @@ struct CompanyInfrastructureWindow : Window /* Set height of the total line. */ if (widget == WID_CI_TOTAL) { - size->height = _settings_game.economy.infrastructure_maintenance ? std::max(size->height, EXP_LINESPACE + FONT_HEIGHT_NORMAL) : 0; + size->height = _settings_game.economy.infrastructure_maintenance ? std::max(size->height, WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL) : 0; } break; } @@ -2022,19 +2022,18 @@ struct CompanyInfrastructureWindow : Window if (_settings_game.economy.infrastructure_maintenance) { SetDParam(0, monthly_cost * 12); // Convert to per year - int left = _current_text_dir == TD_RTL ? r.right - this->total_width : r.left; - DrawString(left, left + this->total_width, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT); + Rect tr = r.WithWidth(this->total_width, _current_text_dir == TD_RTL); + DrawString(tr.left, tr.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT); } } void DrawWidget(const Rect &r, int widget) const override { const Company *c = Company::Get((CompanyID)this->window_number); - int y = r.top; - int offs_left = _current_text_dir == TD_LTR ? WD_FRAMERECT_LEFT : 0; - int offs_right = _current_text_dir == TD_LTR ? 0 : WD_FRAMERECT_LEFT; + int y = r.top; + Rect ir = r.Indent(WidgetDimensions::scaled.hsep_indent, _current_text_dir == TD_RTL); switch (widget) { case WID_CI_RAIL_DESC: DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT); @@ -2044,13 +2043,13 @@ struct CompanyInfrastructureWindow : Window for (const auto &rt : _sorted_railtypes) { if (HasBit(this->railtypes, rt)) { SetDParam(0, GetRailTypeInfo(rt)->strings.name); - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING); } } - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS); } else { /* No valid railtype. */ - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE); } break; @@ -2077,7 +2076,7 @@ struct CompanyInfrastructureWindow : Window for (const auto &rt : _sorted_roadtypes) { if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) { SetDParam(0, GetRoadTypeInfo(rt)->strings.name); - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING); } } @@ -2097,7 +2096,7 @@ struct CompanyInfrastructureWindow : Window case WID_CI_WATER_DESC: DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT); - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS); break; case WID_CI_WATER_COUNT: @@ -2106,18 +2105,18 @@ struct CompanyInfrastructureWindow : Window case WID_CI_TOTAL: if (_settings_game.economy.infrastructure_maintenance) { - int left = _current_text_dir == TD_RTL ? r.right - this->total_width : r.left; - GfxFillRect(left, y, left + this->total_width, y, PC_WHITE); - y += EXP_LINESPACE; + Rect tr = r.WithWidth(this->total_width, _current_text_dir == TD_RTL); + GfxFillRect(tr.left, y, tr.right, y, PC_WHITE); + y += WidgetDimensions::scaled.vsep_normal; SetDParam(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year - DrawString(left, left + this->total_width, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT); + DrawString(tr.left, tr.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT); } break; case WID_CI_STATION_DESC: DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT); - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS); - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS); + DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS); break; case WID_CI_STATION_COUNT: @@ -2218,7 +2217,7 @@ static const NWidgetPart _nested_company_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_C_SELECT_DESC_OWNERS), NWidget(NWID_VERTICAL), SetPIP(5, 5, 4), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_C_DESC_OWNERS), SetMinimalTextLines(3, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_C_DESC_OWNERS), SetMinimalTextLines(MAX_COMPANY_SHARE_OWNERS, 0), NWidget(NWID_SPACER), SetFill(0, 1), EndContainer(), EndContainer(), @@ -2445,6 +2444,70 @@ struct CompanyWindow : Window } } + void DrawVehicleCountsWidget(const Rect &r, const Company *c) const + { + static_assert(VEH_COMPANY_END == lengthof(_company_view_vehicle_count_strings)); + + int y = r.top; + for (VehicleType type = VEH_BEGIN; type < VEH_COMPANY_END; type++) { + uint amount = c->group_all[type].num_vehicle; + if (amount != 0) { + SetDParam(0, amount); + DrawString(r.left, r.right, y, _company_view_vehicle_count_strings[type]); + y += FONT_HEIGHT_NORMAL; + } + } + + if (y == r.top) { + /* No String was emited before, so there must be no vehicles at all. */ + DrawString(r.left, r.right, y, STR_COMPANY_VIEW_VEHICLES_NONE); + } + } + + void DrawInfrastructureCountsWidget(const Rect &r, const Company *c) const + { + int y = r.top; + + uint rail_pieces = c->infrastructure.signal; + for (uint i = 0; i < lengthof(c->infrastructure.rail); i++) rail_pieces += c->infrastructure.rail[i]; + if (rail_pieces != 0) { + SetDParam(0, rail_pieces); + DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_RAIL); + y += FONT_HEIGHT_NORMAL; + } + + uint road_pieces = 0; + for (uint i = 0; i < lengthof(c->infrastructure.road); i++) road_pieces += c->infrastructure.road[i]; + if (road_pieces != 0) { + SetDParam(0, road_pieces); + DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_ROAD); + y += FONT_HEIGHT_NORMAL; + } + + if (c->infrastructure.water != 0) { + SetDParam(0, c->infrastructure.water); + DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_WATER); + y += FONT_HEIGHT_NORMAL; + } + + if (c->infrastructure.station != 0) { + SetDParam(0, c->infrastructure.station); + DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_STATION); + y += FONT_HEIGHT_NORMAL; + } + + if (c->infrastructure.airport != 0) { + SetDParam(0, c->infrastructure.airport); + DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_AIRPORT); + y += FONT_HEIGHT_NORMAL; + } + + if (y == r.top) { + /* No String was emited before, so there must be no infrastructure at all. */ + DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE); + } + } + void DrawWidget(const Rect &r, int widget) const override { const Company *c = Company::Get((CompanyID)this->window_number); @@ -2462,74 +2525,17 @@ struct CompanyWindow : Window Point offset; Dimension d = GetSpriteSize(SPR_VEH_BUS_SW_VIEW, &offset); d.height -= offset.y; - DrawSprite(SPR_VEH_BUS_SW_VIEW, COMPANY_SPRITE_COLOUR(c->index), r.left - offset.x, (r.top + r.bottom - d.height) / 2 - offset.y); + DrawSprite(SPR_VEH_BUS_SW_VIEW, COMPANY_SPRITE_COLOUR(c->index), r.left - offset.x, CenterBounds(r.top, r.bottom, d.height) - offset.y); break; } - case WID_C_DESC_VEHICLE_COUNTS: { - uint amounts[4]; - amounts[0] = c->group_all[VEH_TRAIN].num_vehicle; - amounts[1] = c->group_all[VEH_ROAD].num_vehicle; - amounts[2] = c->group_all[VEH_SHIP].num_vehicle; - amounts[3] = c->group_all[VEH_AIRCRAFT].num_vehicle; - - int y = r.top; - if (amounts[0] + amounts[1] + amounts[2] + amounts[3] == 0) { - DrawString(r.left, r.right, y, STR_COMPANY_VIEW_VEHICLES_NONE); - } else { - static_assert(lengthof(amounts) == lengthof(_company_view_vehicle_count_strings)); - - for (uint i = 0; i < lengthof(amounts); i++) { - if (amounts[i] != 0) { - SetDParam(0, amounts[i]); - DrawString(r.left, r.right, y, _company_view_vehicle_count_strings[i]); - y += FONT_HEIGHT_NORMAL; - } - } - } + case WID_C_DESC_VEHICLE_COUNTS: + DrawVehicleCountsWidget(r, c); break; - } - - case WID_C_DESC_INFRASTRUCTURE_COUNTS: { - uint y = r.top; - - /* Collect rail and road counts. */ - uint rail_pieces = c->infrastructure.signal; - uint road_pieces = 0; - for (uint i = 0; i < lengthof(c->infrastructure.rail); i++) rail_pieces += c->infrastructure.rail[i]; - for (uint i = 0; i < lengthof(c->infrastructure.road); i++) road_pieces += c->infrastructure.road[i]; - - if (rail_pieces == 0 && road_pieces == 0 && c->infrastructure.water == 0 && c->infrastructure.station == 0 && c->infrastructure.airport == 0) { - DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE); - } else { - if (rail_pieces != 0) { - SetDParam(0, rail_pieces); - DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_RAIL); - y += FONT_HEIGHT_NORMAL; - } - if (road_pieces != 0) { - SetDParam(0, road_pieces); - DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_ROAD); - y += FONT_HEIGHT_NORMAL; - } - if (c->infrastructure.water != 0) { - SetDParam(0, c->infrastructure.water); - DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_WATER); - y += FONT_HEIGHT_NORMAL; - } - if (c->infrastructure.station != 0) { - SetDParam(0, c->infrastructure.station); - DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_STATION); - y += FONT_HEIGHT_NORMAL; - } - if (c->infrastructure.airport != 0) { - SetDParam(0, c->infrastructure.airport); - DrawString(r.left, r.right, y, STR_COMPANY_VIEW_INFRASTRUCTURE_AIRPORT); - } - } + case WID_C_DESC_INFRASTRUCTURE_COUNTS: + DrawInfrastructureCountsWidget(r, c); break; - } case WID_C_DESC_OWNERS: { uint y = r.top; diff --git a/src/company_manager_face.h b/src/company_manager_face.h index fe6365a121040..83bfd29e11d9d 100644 --- a/src/company_manager_face.h +++ b/src/company_manager_face.h @@ -199,15 +199,13 @@ static inline void ScaleAllCompanyManagerFaceBits(CompanyManagerFace &cmf) * @param cmf the company manager's face to write the bits to * @param ge the gender and ethnicity of the old company manager's face * @param adv if it for the advanced company manager's face window - * @param interactive is the call from within the user interface? + * @param randomizer the source of random to use for creating the manager face * * @pre scale 'ge' to a valid gender/ethnicity combination */ -static inline void RandomCompanyManagerFaceBits(CompanyManagerFace &cmf, GenderEthnicity ge, bool adv, bool interactive = true) +static inline void RandomCompanyManagerFaceBits(CompanyManagerFace &cmf, GenderEthnicity ge, bool adv, Randomizer &randomizer) { - /* This method is called from a command when not interactive and - * then we must use Random to get the same result on all clients. */ - cmf = interactive ? InteractiveRandom() : Random(); // random all company manager's face bits + cmf = randomizer.Next(); // random all company manager's face bits /* scale ge: 0 == GE_WM, 1 == GE_WF, 2 == GE_BM, 3 == GE_BF (and maybe in future: ...) */ ge = (GenderEthnicity)((uint)ge % GE_END); diff --git a/src/console.cpp b/src/console.cpp index 10e0bc279a254..393dca27547d0 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -123,6 +123,7 @@ void IConsolePrint(TextColour colour_code, const std::string &string) IConsoleWriteToLogFile(str); IConsoleGUIPrint(colour_code, str); + free(str); } /** diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 426b5017396b4..36b9900c6411b 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -23,6 +23,7 @@ #include "settings_func.h" #include "fios.h" #include "fileio_func.h" +#include "fontcache.h" #include "screenshot.h" #include "genworld.h" #include "strings_func.h" @@ -45,6 +46,8 @@ #include "company_cmd.h" #include "misc_cmd.h" +#include + #include "safeguards.h" /* scriptfile handling */ @@ -283,7 +286,11 @@ DEF_CONSOLE_CMD(ConZoomToLevel) case 2: { uint32 level; if (GetArgumentInteger(&level, argv[1])) { - if (level < ZOOM_LVL_MIN) { + /* In case ZOOM_LVL_MIN is more than 0, the next if statement needs to be amended. + * A simple check for less than ZOOM_LVL_MIN does not work here because we are + * reading an unsigned integer from the console, so just check for a '-' char. */ + static_assert(ZOOM_LVL_MIN == 0); + if (argv[1][0] == '-') { IConsolePrint(CC_ERROR, "Zoom-in levels below {} are not supported.", ZOOM_LVL_MIN); } else if (level < _settings_client.gui.zoom_min) { IConsolePrint(CC_ERROR, "Current client settings do not allow zooming in below level {}.", _settings_client.gui.zoom_min); @@ -292,7 +299,7 @@ DEF_CONSOLE_CMD(ConZoomToLevel) } else if (level > _settings_client.gui.zoom_max) { IConsolePrint(CC_ERROR, "Current client settings do not allow zooming out beyond level {}.", _settings_client.gui.zoom_max); } else { - Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + Window *w = GetMainWindow(); Viewport *vp = w->viewport; while (vp->zoom > level) DoZoomInOutWindow(ZOOM_IN, w); while (vp->zoom < level) DoZoomInOutWindow(ZOOM_OUT, w); @@ -337,7 +344,7 @@ DEF_CONSOLE_CMD(ConScrollToTile) case 1: { uint32 result; if (GetArgumentInteger(&result, argv[arg_index])) { - if (result >= MapSize()) { + if (result >= Map::Size()) { IConsolePrint(CC_ERROR, "Tile does not exist."); return true; } @@ -350,7 +357,7 @@ DEF_CONSOLE_CMD(ConScrollToTile) case 2: { uint32 x, y; if (GetArgumentInteger(&x, argv[arg_index]) && GetArgumentInteger(&y, argv[arg_index + 1])) { - if (x >= MapSizeX() || y >= MapSizeY()) { + if (x >= Map::SizeX() || y >= Map::SizeY()) { IConsolePrint(CC_ERROR, "Tile does not exist."); return true; } @@ -451,8 +458,8 @@ DEF_CONSOLE_CMD(ConRemove) _console_file_list.ValidateFileList(); const FiosItem *item = _console_file_list.FindItem(file); if (item != nullptr) { - if (!FiosDelete(item->name)) { - IConsolePrint(CC_ERROR, "Failed to delete '{}'.", file); + if (unlink(item->name) != 0) { + IConsolePrint(CC_ERROR, "Failed to delete '{}'.", item->name); } } else { IConsolePrint(CC_ERROR, "'{}' could not be found.", file); @@ -922,6 +929,7 @@ DEF_CONSOLE_CMD(ConResetCompany) return false; } const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); + assert(ci != nullptr); if (ci->client_playas == index) { IConsolePrint(CC_ERROR, "Cannot remove company: the server is connected to that company."); return true; @@ -1061,6 +1069,9 @@ DEF_CONSOLE_CMD(ConReturn) * default console commands ******************************/ extern bool CloseConsoleLogIfActive(); +extern const std::vector &GetAllGRFFiles(); +extern void ConPrintFramerate(); // framerate_gui.cpp +extern void ShowFramerateWindow(); DEF_CONSOLE_CMD(ConScript) { @@ -1135,8 +1146,8 @@ DEF_CONSOLE_CMD(ConRestart) } /* Don't copy the _newgame pointers to the real pointers, so call SwitchToMode directly */ - _settings_game.game_creation.map_x = MapLogX(); - _settings_game.game_creation.map_y = FindFirstBit(MapSizeY()); + _settings_game.game_creation.map_x = Map::LogX(); + _settings_game.game_creation.map_y = Map::LogY(); _switch_mode = SM_RESTARTGAME; return true; } @@ -1152,66 +1163,73 @@ DEF_CONSOLE_CMD(ConReload) } /* Don't copy the _newgame pointers to the real pointers, so call SwitchToMode directly */ - _settings_game.game_creation.map_x = MapLogX(); - _settings_game.game_creation.map_y = FindFirstBit(MapSizeY()); + _settings_game.game_creation.map_x = Map::LogX(); + _settings_game.game_creation.map_y = Map::LogY(); _switch_mode = SM_RELOADGAME; return true; } /** * Print a text buffer line by line to the console. Lines are separated by '\n'. - * @param buf The buffer to print. - * @note All newlines are replace by '\0' characters. + * @param full_string The multi-line string to print. */ -static void PrintLineByLine(char *buf) -{ - char *p = buf; - /* Print output line by line */ - for (char *p2 = buf; *p2 != '\0'; p2++) { - if (*p2 == '\n') { - *p2 = '\0'; - IConsolePrint(CC_DEFAULT, p); - p = p2 + 1; - } +static void PrintLineByLine(const std::string &full_string) +{ + std::istringstream in(full_string); + std::string line; + while (std::getline(in, line)) { + IConsolePrint(CC_DEFAULT, line.c_str()); } } DEF_CONSOLE_CMD(ConListAILibs) { - char buf[4096]; - AI::GetConsoleLibraryList(buf, lastof(buf)); + if (argc == 0) { + IConsolePrint(CC_HELP, "List installed AI libraries. Usage: 'list_ai_libs'."); + return true; + } - PrintLineByLine(buf); + const std::string output_str = AI::GetConsoleLibraryList(); + PrintLineByLine(output_str); return true; } DEF_CONSOLE_CMD(ConListAI) { - char buf[4096]; - AI::GetConsoleList(buf, lastof(buf)); + if (argc == 0) { + IConsolePrint(CC_HELP, "List installed AIs. Usage: 'list_ai'."); + return true; + } - PrintLineByLine(buf); + const std::string output_str = AI::GetConsoleList(); + PrintLineByLine(output_str); return true; } DEF_CONSOLE_CMD(ConListGameLibs) { - char buf[4096]; - Game::GetConsoleLibraryList(buf, lastof(buf)); + if (argc == 0) { + IConsolePrint(CC_HELP, "List installed Game Script libraries. Usage: 'list_game_libs'."); + return true; + } - PrintLineByLine(buf); + const std::string output_str = Game::GetConsoleLibraryList(); + PrintLineByLine(output_str); return true; } DEF_CONSOLE_CMD(ConListGame) { - char buf[4096]; - Game::GetConsoleList(buf, lastof(buf)); + if (argc == 0) { + IConsolePrint(CC_HELP, "List installed Game Scripts. Usage: 'list_game'."); + return true; + } - PrintLineByLine(buf); + const std::string output_str = Game::GetConsoleList(); + PrintLineByLine(output_str); return true; } @@ -1484,6 +1502,7 @@ DEF_CONSOLE_CMD(ConScreenShot) IConsolePrint(CC_HELP, " 'minimap' makes a top-viewed minimap screenshot of the whole world which represents one tile by one pixel."); IConsolePrint(CC_HELP, " 'no_con' hides the console to create the screenshot (only useful in combination with 'viewport')."); IConsolePrint(CC_HELP, " 'size' sets the width and height of the viewport to make a screenshot of (only useful in combination with 'normal' or 'big')."); + IConsolePrint(CC_HELP, " A filename ending in # will prevent overwriting existing files and will number files counting upwards."); return true; } @@ -1587,7 +1606,7 @@ DEF_CONSOLE_CMD(ConDebugLevel) if (argc == 1) { IConsolePrint(CC_DEFAULT, "Current debug-level: '{}'", GetDebugString()); } else { - SetDebugString(argv[1]); + SetDebugString(argv[1], [](const char *err) { IConsolePrint(CC_ERROR, std::string(err)); }); } return true; @@ -1972,6 +1991,79 @@ DEF_CONSOLE_CMD(ConContent) } #endif /* defined(WITH_ZLIB) */ +DEF_CONSOLE_CMD(ConFont) +{ + if (argc == 0) { + IConsolePrint(CC_HELP, "Manage the fonts configuration."); + IConsolePrint(CC_HELP, "Usage 'font'."); + IConsolePrint(CC_HELP, " Print out the fonts configuration."); + IConsolePrint(CC_HELP, "Usage 'font [medium|small|large|mono] [] [] [aa|noaa]'."); + IConsolePrint(CC_HELP, " Change the configuration for a font."); + IConsolePrint(CC_HELP, " Omitting an argument will keep the current value."); + IConsolePrint(CC_HELP, " Set to \"\" for the sprite font (size and aa have no effect on sprite font)."); + return true; + } + + FontSize argfs; + for (argfs = FS_BEGIN; argfs < FS_END; argfs++) { + if (argc > 1 && strcasecmp(argv[1], FontSizeToName(argfs)) == 0) break; + } + + /* First argument must be a FontSize. */ + if (argc > 1 && argfs == FS_END) return false; + + if (argc > 2) { + FontCacheSubSetting *setting = GetFontCacheSubSetting(argfs); + std::string font = setting->font; + uint size = setting->size; + bool aa = setting->aa; + + byte arg_index = 2; + /* We may encounter "aa" or "noaa" but it must be the last argument. */ + if (strcasecmp(argv[arg_index], "aa") == 0 || strcasecmp(argv[arg_index], "noaa") == 0) { + aa = strncasecmp(argv[arg_index++], "no", 2) != 0; + if (argc > arg_index) return false; + } else { + /* For we want a string. */ + uint v; + if (!GetArgumentInteger(&v, argv[arg_index])) { + font = argv[arg_index++]; + } + } + + if (argc > arg_index) { + /* For we want a number. */ + uint v; + if (GetArgumentInteger(&v, argv[arg_index])) { + size = v; + arg_index++; + } + } + + if (argc > arg_index) { + /* Last argument must be "aa" or "noaa". */ + if (strcasecmp(argv[arg_index], "aa") != 0 && strcasecmp(argv[arg_index], "noaa") != 0) return false; + aa = strncasecmp(argv[arg_index++], "no", 2) != 0; + if (argc > arg_index) return false; + } + + SetFont(argfs, font, size, aa); + } + + for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) { + FontCache *fc = FontCache::Get(fs); + FontCacheSubSetting *setting = GetFontCacheSubSetting(fs); + /* Make sure all non sprite fonts are loaded. */ + if (!setting->font.empty() && !fc->HasParent()) { + InitFontCache(fs == FS_MONO); + fc = FontCache::Get(fs); + } + IConsolePrint(CC_DEFAULT, "{}: \"{}\" {} {} [\"{}\" {} {}]", FontSizeToName(fs), fc->GetFontName(), fc->GetFontSize(), GetFontAAState(fs) ? "aa" : "noaa", setting->font, setting->size, setting->aa ? "aa" : "noaa"); + } + + return true; +} + DEF_CONSOLE_CMD(ConSetting) { if (argc == 0) { @@ -2124,7 +2216,6 @@ DEF_CONSOLE_CMD(ConNewGRFProfile) return true; } - extern const std::vector &GetAllGRFFiles(); const std::vector &files = GetAllGRFFiles(); /* "list" sub-command */ @@ -2249,8 +2340,6 @@ static void IConsoleDebugLibRegister() DEF_CONSOLE_CMD(ConFramerate) { - extern void ConPrintFramerate(); // framerate_gui.cpp - if (argc == 0) { IConsolePrint(CC_HELP, "Show frame rate and game speed information."); return true; @@ -2262,8 +2351,6 @@ DEF_CONSOLE_CMD(ConFramerate) DEF_CONSOLE_CMD(ConFramerateWindow) { - extern void ShowFramerateWindow(); - if (argc == 0) { IConsolePrint(CC_HELP, "Open the frame rate window."); return true; @@ -2470,6 +2557,7 @@ void IConsoleStdLibRegister() IConsole::CmdRegister("cd", ConChangeDirectory); IConsole::CmdRegister("pwd", ConPrintWorkingDirectory); IConsole::CmdRegister("clear", ConClearBuffer); + IConsole::CmdRegister("font", ConFont); IConsole::CmdRegister("setting", ConSetting); IConsole::CmdRegister("setting_newgame", ConSettingNewgame); IConsole::CmdRegister("list_settings", ConListSettings); diff --git a/src/console_gui.cpp b/src/console_gui.cpp index 81978f08a234e..972ef23b24030 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.cpp @@ -21,6 +21,8 @@ #include "console_func.h" #include "rev.h" #include "video/video_driver.hpp" +#include +#include #include "widgets/console_widget.h" @@ -29,7 +31,6 @@ #include "safeguards.h" static const uint ICON_HISTORY_SIZE = 20; -static const uint ICON_LINE_SPACING = 2; static const uint ICON_RIGHT_BORDERWIDTH = 10; static const uint ICON_BOTTOM_BORDERWIDTH = 12; @@ -37,94 +38,36 @@ static const uint ICON_BOTTOM_BORDERWIDTH = 12; * Container for a single line of console output */ struct IConsoleLine { - static IConsoleLine *front; ///< The front of the console backlog buffer - static int size; ///< The amount of items in the backlog - - IConsoleLine *previous; ///< The previous console message. - char *buffer; ///< The data to store. + std::string buffer; ///< The data to store. TextColour colour; ///< The colour of the line. uint16 time; ///< The amount of time the line is in the backlog. + IConsoleLine() : buffer(), colour(TC_BEGIN), time(0) + { + + } + /** * Initialize the console line. * @param buffer the data to print. * @param colour the colour of the line. */ - IConsoleLine(char *buffer, TextColour colour) : - previous(IConsoleLine::front), - buffer(buffer), + IConsoleLine(std::string buffer, TextColour colour) : + buffer(std::move(buffer)), colour(colour), time(0) { - IConsoleLine::front = this; - IConsoleLine::size++; } - /** - * Clear this console line and any further ones. - */ ~IConsoleLine() { - IConsoleLine::size--; - free(buffer); - - delete previous; - } - - /** - * Get the index-ed item in the list. - */ - static const IConsoleLine *Get(uint index) - { - const IConsoleLine *item = IConsoleLine::front; - while (index != 0 && item != nullptr) { - index--; - item = item->previous; - } - - return item; - } - - /** - * Truncate the list removing everything older than/more than the amount - * as specified in the config file. - * As a side effect also increase the time the other lines have been in - * the list. - * @return true if and only if items got removed. - */ - static bool Truncate() - { - IConsoleLine *cur = IConsoleLine::front; - if (cur == nullptr) return false; - - int count = 1; - for (IConsoleLine *item = cur->previous; item != nullptr; count++, cur = item, item = item->previous) { - if (item->time > _settings_client.gui.console_backlog_timeout && - count > _settings_client.gui.console_backlog_length) { - delete item; - cur->previous = nullptr; - return true; - } - - if (item->time != MAX_UVALUE(uint16)) item->time++; - } - - return false; - } - - /** - * Reset the complete console line backlog. - */ - static void Reset() - { - delete IConsoleLine::front; - IConsoleLine::front = nullptr; - IConsoleLine::size = 0; } }; -/* static */ IConsoleLine *IConsoleLine::front = nullptr; -/* static */ int IConsoleLine::size = 0; +/** The console backlog buffer. Item index 0 is the newest line. */ +static std::deque _iconsole_buffer; + +static bool TruncateBuffer(); /* ** main console cmd buffer ** */ @@ -169,7 +112,7 @@ static WindowDesc _console_window_desc( struct IConsoleWindow : Window { - static int scroll; + static size_t scroll; int line_height; ///< Height of one line of text in the console. int line_offset; GUITimer truncate_timer; @@ -177,14 +120,18 @@ struct IConsoleWindow : Window IConsoleWindow() : Window(&_console_window_desc) { _iconsole_mode = ICONSOLE_OPENED; - this->line_height = FONT_HEIGHT_NORMAL + ICON_LINE_SPACING; - this->line_offset = GetStringBoundingBox("] ").width + 5; this->InitNested(0); this->truncate_timer.SetInterval(3000); ResizeWindow(this, _screen.width, _screen.height / 3); } + void OnInit() override + { + this->line_height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.hsep_normal; + this->line_offset = GetStringBoundingBox("] ").width + WidgetDimensions::scaled.frametext.left; + } + void Close() override { _iconsole_mode = ICONSOLE_CLOSED; @@ -198,26 +145,34 @@ struct IConsoleWindow : Window */ void Scroll(int amount) { - int max_scroll = std::max(0, IConsoleLine::size + 1 - this->height / this->line_height); - IConsoleWindow::scroll = Clamp(IConsoleWindow::scroll + amount, 0, max_scroll); + if (amount < 0) { + size_t namount = (size_t) -amount; + IConsoleWindow::scroll = (namount > IConsoleWindow::scroll) ? 0 : IConsoleWindow::scroll - namount; + } else { + assert(this->height >= 0 && this->line_height > 0); + size_t visible_lines = (size_t)(this->height / this->line_height); + size_t max_scroll = (visible_lines > _iconsole_buffer.size()) ? 0 : _iconsole_buffer.size() + 1 - visible_lines; + IConsoleWindow::scroll = std::min(IConsoleWindow::scroll + amount, max_scroll); + } this->SetDirty(); } void OnPaint() override { - const int right = this->width - 5; + const int right = this->width - WidgetDimensions::scaled.frametext.right; GfxFillRect(0, 0, this->width - 1, this->height - 1, PC_BLACK); int ypos = this->height - this->line_height; - for (const IConsoleLine *print = IConsoleLine::Get(IConsoleWindow::scroll); print != nullptr; print = print->previous) { - SetDParamStr(0, print->buffer); - ypos = DrawStringMultiLine(5, right, -this->line_height, ypos, STR_JUST_RAW_STRING, print->colour, SA_LEFT | SA_BOTTOM | SA_FORCE) - ICON_LINE_SPACING; + for (size_t line_index = IConsoleWindow::scroll; line_index < _iconsole_buffer.size(); line_index++) { + const IConsoleLine &print = _iconsole_buffer[line_index]; + SetDParamStr(0, print.buffer); + ypos = DrawStringMultiLine(WidgetDimensions::scaled.frametext.left, right, -this->line_height, ypos, STR_JUST_RAW_STRING, print.colour, SA_LEFT | SA_BOTTOM | SA_FORCE) - WidgetDimensions::scaled.hsep_normal; if (ypos < 0) break; } /* If the text is longer than the window, don't show the starting ']' */ int delta = this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH; if (delta > 0) { - DrawString(5, right, this->height - this->line_height, "]", (TextColour)CC_COMMAND, SA_LEFT | SA_FORCE); + DrawString(WidgetDimensions::scaled.frametext.left, right, this->height - this->line_height, "]", (TextColour)CC_COMMAND, SA_LEFT | SA_FORCE); delta = 0; } @@ -235,9 +190,12 @@ struct IConsoleWindow : Window { if (this->truncate_timer.CountElapsed(delta_ms) == 0) return; - if (IConsoleLine::Truncate() && - (IConsoleWindow::scroll > IConsoleLine::size)) { - IConsoleWindow::scroll = std::max(0, IConsoleLine::size - (this->height / this->line_height) + 1); + assert(this->height >= 0 && this->line_height > 0); + size_t visible_lines = (size_t)(this->height / this->line_height); + + if (TruncateBuffer() && IConsoleWindow::scroll + visible_lines > _iconsole_buffer.size()) { + size_t max_scroll = (visible_lines > _iconsole_buffer.size()) ? 0 : _iconsole_buffer.size() + 1 - visible_lines; + IConsoleWindow::scroll = std::min(IConsoleWindow::scroll, max_scroll); this->SetDirty(); } } @@ -389,14 +347,14 @@ struct IConsoleWindow : Window } }; -int IConsoleWindow::scroll = 0; +size_t IConsoleWindow::scroll = 0; void IConsoleGUIInit() { IConsoleResetHistoryPos(); _iconsole_mode = ICONSOLE_CLOSED; - IConsoleLine::Reset(); + IConsoleClearBuffer(); memset(_iconsole_history, 0, sizeof(_iconsole_history)); IConsolePrint(TC_LIGHT_BLUE, "OpenTTD Game Console Revision 7 - {}", _openttd_revision); @@ -408,7 +366,7 @@ void IConsoleGUIInit() void IConsoleClearBuffer() { - IConsoleLine::Reset(); + _iconsole_buffer.clear(); } void IConsoleGUIFree() @@ -511,10 +469,38 @@ static void IConsoleHistoryNavigate(int direction) */ void IConsoleGUIPrint(TextColour colour_code, char *str) { - new IConsoleLine(str, colour_code); + _iconsole_buffer.push_front(IConsoleLine(str, colour_code)); SetWindowDirty(WC_CONSOLE, 0); } +/** + * Remove old lines from the backlog buffer. + * The buffer is limited by a maximum size and a minimum age. Every time truncation runs, + * all lines in the buffer are aged by one. When a line exceeds both the maximum position + * and also the maximum age, it gets removed. + * @return true if any lines were removed +*/ +static bool TruncateBuffer() +{ + bool need_truncation = false; + size_t count = 0; + for (IConsoleLine &line : _iconsole_buffer) { + count++; + line.time++; + if (line.time > _settings_client.gui.console_backlog_timeout && count > _settings_client.gui.console_backlog_length) { + /* Any messages after this are older and need to be truncated */ + need_truncation = true; + break; + } + } + + if (need_truncation) { + _iconsole_buffer.resize(count - 1); + } + + return need_truncation; +} + /** * Check whether the given TextColour is valid for console usage. diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 1c14067ae4832..d0a4cc3313d55 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -23,7 +23,6 @@ add_files( random_func.cpp random_func.hpp smallmap_type.hpp - smallmatrix_type.hpp smallstack_type.hpp smallvec_type.hpp span_type.hpp diff --git a/src/core/backup_type.hpp b/src/core/backup_type.hpp index fc67b73ad98f3..62e6d313297f7 100644 --- a/src/core/backup_type.hpp +++ b/src/core/backup_type.hpp @@ -144,4 +144,46 @@ struct Backup { const int line; }; +/** + * Class to backup a specific variable and restore it upon destruction of this object to prevent + * stack values going out of scope before resetting the global to its original value. Contrary to + * #Backup this restores the variable automatically and there is no manual option to restore. + */ +template +struct AutoRestoreBackup { + /* + * There is explicitly no only original constructor version, as that would make it possible + * for the new value to go out of scope before this object goes out of scope, thus defeating + * the whole goal and reason for existing of this object. + */ + + /** + * Backup variable and switch to new value. + * @param original Variable to backup. + * @param new_value New value for variable. + */ + AutoRestoreBackup(T &original, T new_value) : original(original), original_value(original) + { + original = new_value; + } + + /** + * Restore the variable upon object destruction. + */ + ~AutoRestoreBackup() + { + this->original = this->original_value; + } + +private: + T &original; + T original_value; + + /* Prevent copy, assignment and allocation on stack. */ + AutoRestoreBackup(const AutoRestoreBackup&) = delete; + AutoRestoreBackup& operator=(AutoRestoreBackup&) = delete; + static void *operator new(std::size_t) = delete; + static void *operator new[](std::size_t) = delete; +}; + #endif /* BACKUP_TYPE_HPP */ diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index 979d9b73b7a6c..745a32afc4b19 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -29,7 +29,7 @@ * @return The selected bits, aligned to a LSB. */ template -static inline uint GB(const T x, const uint8 s, const uint8 n) +debug_inline static uint GB(const T x, const uint8 s, const uint8 n) { return (x >> s) & (((T)1U << n) - 1); } @@ -100,7 +100,7 @@ static inline T AB(T &x, const uint8 s, const uint8 n, const U i) * @return True if the bit is set, false else. */ template -static inline bool HasBit(const T x, const uint8 y) +debug_inline static bool HasBit(const T x, const uint8 y) { return (x & ((T)1U << y)) != 0; } diff --git a/src/core/geometry_func.cpp b/src/core/geometry_func.cpp index dccef72ecc588..3dd680347cbfe 100644 --- a/src/core/geometry_func.cpp +++ b/src/core/geometry_func.cpp @@ -48,3 +48,5 @@ Rect BoundingRect(const Rect &r1, const Rect &r2) return r; } + +const RectPadding RectPadding::zero = {0, 0, 0, 0}; diff --git a/src/core/geometry_type.hpp b/src/core/geometry_type.hpp index cba944fb6fca3..36933de6efcd3 100644 --- a/src/core/geometry_type.hpp +++ b/src/core/geometry_type.hpp @@ -43,12 +43,182 @@ struct Dimension { } }; +/** Padding dimensions to apply to each side of a Rect. */ +struct RectPadding { + uint8 left; + uint8 top; + uint8 right; + uint8 bottom; + + static const RectPadding zero; + + /** + * Get total horizontal padding of RectPadding. + * @return total horizontal padding. + */ + inline uint Horizontal() const { return this->left + this->right; } + + /** + * Get total vertical padding of RectPadding. + * @return total vertical padding. + */ + inline uint Vertical() const { return this->top + this->bottom; } +}; + /** Specification of a rectangle with absolute coordinates of all edges */ struct Rect { int left; int top; int right; int bottom; + + /** + * Get width of Rect. + * @return width of Rect. + */ + inline int Width() const { return this->right - this->left + 1; } + + /** + * Get height of Rect. + * @return height of Rect. + */ + inline int Height() const { return this->bottom - this->top + 1; } + + /** + * Copy and shrink Rect by s pixels. + * @param s number of pixels to remove from each side of Rect. + * @return the new smaller Rect. + */ + [[nodiscard]] inline Rect Shrink(int s) const + { + return {this->left + s, this->top + s, this->right - s, this->bottom - s}; + } + + /** + * Copy and shrink Rect by h horizontal and v vertical pixels. + * @param h number of pixels to remove from left and right sides. + * @param v number of pixels to remove from top and bottom sides. + * @return the new smaller Rect. + */ + [[nodiscard]] inline Rect Shrink(int h, int v) const + { + return {this->left + h, this->top + v, this->right - h, this->bottom - v}; + } + + /** + * Copy and shrink Rect by pixels. + * @param left number of pixels to remove from left side. + * @param top number of pixels to remove from top side. + * @param right number of pixels to remove from right side. + * @param bottom number of pixels to remove from bottom side. + * @return the new smaller Rect. + */ + [[nodiscard]] inline Rect Shrink(int left, int top, int right, int bottom) const + { + return {this->left + left, this->top + top, this->right - right, this->bottom - bottom}; + } + + /** + * Copy and shrink Rect by a RectPadding. + * @param other RectPadding to remove from each side of Rect. + * @return the new smaller Rect. + */ + [[nodiscard]] inline Rect Shrink(const RectPadding &other) const + { + return {this->left + other.left, this->top + other.top, this->right - other.right, this->bottom - other.bottom}; + } + + /** + * Copy and shrink Rect by a different horizontal and vertical RectPadding. + * @param horz RectPadding to remove from left and right of Rect. + * @param vert RectPadding to remove from top and bottom of Rect. + * @return the new smaller Rect. + */ + [[nodiscard]] inline Rect Shrink(const RectPadding &horz, const RectPadding &vert) const + { + return {this->left + horz.left, this->top + vert.top, this->right - horz.right, this->bottom - vert.bottom}; + } + + /** + * Copy and expand Rect by s pixels. + * @param s number of pixels to add to each side of Rect. + * @return the new larger Rect. + */ + [[nodiscard]] inline Rect Expand(int s) const + { + return this->Shrink(-s); + } + + /** + * Copy and expand Rect by a RectPadding. + * @param other RectPadding to add to each side of Rect. + * @return the new larger Rect. + */ + [[nodiscard]] inline Rect Expand(const RectPadding &other) const + { + return {this->left - other.left, this->top - other.top, this->right + other.right, this->bottom + other.bottom}; + } + + /** + * Copy and translate Rect by x,y pixels. + * @param x number of pixels to move horizontally. + * @param y number of pixels to move vertically. + * @return the new translated Rect. + */ + [[nodiscard]] inline Rect Translate(int x, int y) const + { + return {this->left + x, this->top + y, this->right + x, this->bottom + y}; + } + + /** + * Copy Rect and set its width. + * @param width width in pixels for new Rect. + * @param end if set, set width at end of Rect, i.e. on right. + * @return the new resized Rect. + */ + [[nodiscard]] inline Rect WithWidth(int width, bool end) const + { + return end + ? Rect {this->right - width + 1, this->top, this->right, this->bottom} + : Rect {this->left, this->top, this->left + width - 1, this->bottom}; + } + + /** + * Copy Rect and indent it from its position. + * @param indent offset in pixels for new Rect. + * @param end if set, set indent at end of Rect, i.e. on right. + * @return the new resized Rect. + */ + [[nodiscard]] inline Rect Indent(int indent, bool end) const + { + return end + ? Rect {this->left, this->top, this->right - indent, this->bottom} + : Rect {this->left + indent, this->top, this->right, this->bottom}; + } + + /** + * Copy Rect and set its height. + * @param width height in pixels for new Rect. + * @param end if set, set height at end of Rect, i.e. at bottom. + * @return the new resized Rect. + */ + [[nodiscard]] inline Rect WithHeight(int height, bool end = false) const + { + return end + ? Rect {this->left, this->bottom - height + 1, this->right, this->bottom} + : Rect {this->left, this->top, this->right, this->top + height - 1}; + } + + /** + * Test if a point falls inside this Rect. + * @param pt the point to test. + * @return true iif the point falls inside the Rect. + */ + inline bool Contains(const Point &pt) const + { + /* This is a local version of IsInsideMM, to avoid including math_func everywhere. */ + return (uint)(pt.x - this->left) < (uint)(this->right - this->left) && (uint)(pt.y - this->top) < (uint)(this->bottom - this->top); + } }; /** diff --git a/src/core/overflowsafe_type.hpp b/src/core/overflowsafe_type.hpp index 14f0eaa7a710c..0c3957aaadd76 100644 --- a/src/core/overflowsafe_type.hpp +++ b/src/core/overflowsafe_type.hpp @@ -176,6 +176,9 @@ class OverflowSafeInt inline constexpr bool operator <= (const int other) const { return !(*this > other); } inline constexpr operator T () const { return this->m_value; } + + static inline constexpr OverflowSafeInt max() { return T_MAX; } + static inline constexpr OverflowSafeInt min() { return T_MIN; } }; diff --git a/src/core/pool_func.hpp b/src/core/pool_func.hpp index 3b2d24b145aa6..0857a5142b4e4 100644 --- a/src/core/pool_func.hpp +++ b/src/core/pool_func.hpp @@ -14,6 +14,8 @@ #include "mem_func.hpp" #include "pool_type.hpp" +extern void NORETURN SlErrorCorruptFmt(const char *format, ...) WARN_FORMAT(1, 2); + /** * Helper for defining the method's signature. * @param type The return type of the method. @@ -154,8 +156,6 @@ DEFINE_POOL_METHOD(void *)::GetNew(size_t size) */ DEFINE_POOL_METHOD(void *)::GetNew(size_t size, size_t index) { - extern void NORETURN SlErrorCorruptFmt(const char *format, ...); - if (index >= Tmax_size) { SlErrorCorruptFmt("%s index " PRINTF_SIZE " out of range (" PRINTF_SIZE ")", this->name, index, Tmax_size); } diff --git a/src/core/smallmatrix_type.hpp b/src/core/smallmatrix_type.hpp deleted file mode 100644 index 03fd1b790828e..0000000000000 --- a/src/core/smallmatrix_type.hpp +++ /dev/null @@ -1,320 +0,0 @@ -/* - * 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 smallmatrix_type.hpp Simple matrix class that allows allocating an item without the need to copy this->data needlessly. */ - -#ifndef SMALLMATRIX_TYPE_HPP -#define SMALLMATRIX_TYPE_HPP - -#include "alloc_func.hpp" -#include "mem_func.hpp" - -/** - * Simple matrix template class. - * - * Allocating a matrix in one piece reduces overhead in allocations compared - * with allocating a vector of vectors and saves some pointer dereferencing. - * However, you can only get rectangular matrixes like this and if you're - * changing their height very often performance will probably be worse than - * with a vector of vectors, due to more frequent copying of memory blocks. - * - * No iterators are provided as iterating the columns would require persistent - * column objects. Those do not exist. Providing iterators with transient - * column objects would tie each iterator to a column object, thus replacing - * previously retrieved columns when iterating and defeating the point of - * iteration. - * - * It's expected that the items don't need to be constructed or deleted by the - * container. Only memory allocation and deallocation is performed. This is the - * same for all openttd "SmallContainer" classes. - * - * @tparam T The type of the items stored - */ -template -class SmallMatrix { -protected: - T *data; ///< The pointer to the first item - uint width; ///< Number of items over first axis - uint height; ///< Number of items over second axis - uint capacity; ///< The available space for storing items - -public: - - SmallMatrix() : data(nullptr), width(0), height(0), capacity(0) {} - - /** - * Copy constructor. - * @param other The other matrix to copy. - */ - SmallMatrix(const SmallMatrix &other) : data(nullptr), width(0), height(0), capacity(0) - { - this->Assign(other); - } - - ~SmallMatrix() - { - free(this->data); - } - - /** - * Assignment. - * @param other The other matrix to assign. - */ - SmallMatrix &operator=(const SmallMatrix &other) - { - this->Assign(other); - return *this; - } - - /** - * Assign items from other vector. - */ - inline void Assign(const SmallMatrix &other) - { - if (&other == this) return; - - this->height = other.Height(); - this->width = other.Width(); - uint num_items = this->width * this->height; - if (num_items > this->capacity) { - this->capacity = num_items; - free(this->data); - this->data = MallocT(num_items); - MemCpyT(this->data, other[0], num_items); - } else if (num_items > 0) { - MemCpyT(this->data, other[0], num_items); - } - } - - /** - * Remove all rows from the matrix. - */ - inline void Clear() - { - /* In fact we just reset the width avoiding the need to - * probably reallocate the same amount of memory the matrix was - * previously using. */ - this->width = 0; - } - - /** - * Remove all items from the list and free allocated memory. - */ - inline void Reset() - { - this->height = 0; - this->width = 0; - this->capacity = 0; - free(this->data); - this->data = nullptr; - } - - /** - * Compact the matrix down to the smallest possible size. - */ - inline void Compact() - { - uint capacity = this->height * this->width; - if (capacity >= this->capacity) return; - this->capacity = capacity; - this->data = ReallocT(this->data, this->capacity); - } - - /** - * Erase a column, replacing it with the last one. - * @param x Position of the column. - */ - void EraseColumn(uint x) - { - if (x < --this->width) { - MemCpyT(this->data + x * this->height, - this->data + this->width * this->height, - this->height); - } - } - - /** - * Remove columns from the matrix while preserving the order of other columns. - * @param x First column to remove. - * @param count Number of consecutive columns to remove. - */ - void EraseColumnPreservingOrder(uint x, uint count = 1) - { - if (count == 0) return; - assert(x < this->width); - assert(x + count <= this->width); - this->width -= count; - uint to_move = (this->width - x) * this->height; - if (to_move > 0) { - MemMoveT(this->data + x * this->height, - this->data + (x + count) * this->height, to_move); - } - } - - /** - * Erase a row, replacing it with the last one. - * @param y Position of the row. - */ - void EraseRow(uint y) - { - if (y < this->height - 1) { - for (uint x = 0; x < this->width; ++x) { - this->data[x * this->height + y] = - this->data[(x + 1) * this->height - 1]; - } - } - this->Resize(this->width, this->height - 1); - } - - /** - * Remove columns from the matrix while preserving the order of other columns. - * @param y First column to remove. - * @param count Number of consecutive columns to remove. - */ - void EraseRowPreservingOrder(uint y, uint count = 1) - { - if (this->height > count + y) { - for (uint x = 0; x < this->width; ++x) { - MemMoveT(this->data + x * this->height + y, - this->data + x * this->height + y + count, - this->height - count - y); - } - } - this->Resize(this->width, this->height - count); - } - - /** - * Append rows. - * @param to_add Number of rows to append. - */ - inline void AppendRow(uint to_add = 1) - { - this->Resize(this->width, to_add + this->height); - } - - /** - * Append rows. - * @param to_add Number of rows to append. - */ - inline void AppendColumn(uint to_add = 1) - { - this->Resize(to_add + this->width, this->height); - } - - /** - * Set the size to a specific width and height, preserving item positions - * as far as possible in the process. - * @param new_width Target width. - * @param new_height Target height. - */ - inline void Resize(uint new_width, uint new_height) - { - uint new_capacity = new_width * new_height; - T *new_data = nullptr; - void (*copy)(T *dest, const T *src, size_t count) = nullptr; - if (new_capacity > this->capacity) { - /* If the data doesn't fit into current capacity, resize and copy ... */ - new_data = MallocT(new_capacity); - copy = &MemCpyT; - } else { - /* ... otherwise just move the columns around, if necessary. */ - new_data = this->data; - copy = &MemMoveT; - } - if (this->height != new_height || new_data != this->data) { - if (this->height > 0) { - if (new_height > this->height) { - /* If matrix is growing, copy from the back to avoid - * overwriting uncopied data. */ - for (uint x = this->width; x > 0; --x) { - if (x * new_height > new_capacity) continue; - (*copy)(new_data + (x - 1) * new_height, - this->data + (x - 1) * this->height, - std::min(this->height, new_height)); - } - } else { - /* If matrix is shrinking copy from the front. */ - for (uint x = 0; x < this->width; ++x) { - if ((x + 1) * new_height > new_capacity) break; - (*copy)(new_data + x * new_height, - this->data + x * this->height, - std::min(this->height, new_height)); - } - } - } - this->height = new_height; - if (new_data != this->data) { - free(this->data); - this->data = new_data; - this->capacity = new_capacity; - } - } - this->width = new_width; - } - - inline uint Height() const - { - return this->height; - } - - inline uint Width() const - { - return this->width; - } - - /** - * Get item x/y (const). - * - * @param x X-position of the item. - * @param y Y-position of the item. - * @return Item at specified position. - */ - inline const T &Get(uint x, uint y) const - { - assert(x < this->width && y < this->height); - return this->data[x * this->height + y]; - } - - /** - * Get item x/y. - * - * @param x X-position of the item. - * @param y Y-position of the item. - * @return Item at specified position. - */ - inline T &Get(uint x, uint y) - { - assert(x < this->width && y < this->height); - return this->data[x * this->height + y]; - } - - /** - * Get column "number" (const) - * - * @param x Position of the column. - * @return Column at "number". - */ - inline const T *operator[](uint x) const - { - assert(x < this->width); - return this->data + x * this->height; - } - - /** - * Get column "number" (const) - * - * @param x Position of the column. - * @return Column at "number". - */ - inline T *operator[](uint x) - { - assert(x < this->width); - return this->data + x * this->height; - } -}; - -#endif /* SMALLMATRIX_TYPE_HPP */ diff --git a/src/core/span_type.hpp b/src/core/span_type.hpp index 0df528816ece2..1cee60288b6a5 100644 --- a/src/core/span_type.hpp +++ b/src/core/span_type.hpp @@ -94,6 +94,8 @@ class span { constexpr reference operator[](size_type idx) const { return first[idx]; } + constexpr pointer data() const noexcept { return first; } + private: pointer first; pointer last; diff --git a/src/core/strong_typedef_type.hpp b/src/core/strong_typedef_type.hpp index b5df28b2fb13d..179d2b3a0de3b 100644 --- a/src/core/strong_typedef_type.hpp +++ b/src/core/strong_typedef_type.hpp @@ -29,15 +29,15 @@ struct StrongTypedef : StrongTypedefBase { T value{}; ///< Backing storage field. - constexpr StrongTypedef() = default; - constexpr StrongTypedef(const StrongTypedef &o) = default; - constexpr StrongTypedef(StrongTypedef &&o) = default; + debug_inline constexpr StrongTypedef() = default; + debug_inline constexpr StrongTypedef(const StrongTypedef &o) = default; + debug_inline constexpr StrongTypedef(StrongTypedef &&o) = default; - constexpr StrongTypedef(const T &value) : value(value) {} + debug_inline constexpr StrongTypedef(const T &value) : value(value) {} - constexpr Tthis &operator =(const StrongTypedef &rhs) { this->value = rhs.value; return static_cast(*this); } - constexpr Tthis &operator =(StrongTypedef &&rhs) { this->value = std::move(rhs.value); return static_cast(*this); } - constexpr Tthis &operator =(const T &rhs) { this->value = rhs; return static_cast(*this); } + debug_inline constexpr Tthis &operator =(const StrongTypedef &rhs) { this->value = rhs.value; return static_cast(*this); } + debug_inline constexpr Tthis &operator =(StrongTypedef &&rhs) { this->value = std::move(rhs.value); return static_cast(*this); } + debug_inline constexpr Tthis &operator =(const T &rhs) { this->value = rhs; return static_cast(*this); } explicit constexpr operator T() const { return this->value; } @@ -56,6 +56,16 @@ template struct StrongIntegralTypedef : StrongTypedef { using StrongTypedef::StrongTypedef; + debug_inline constexpr StrongIntegralTypedef() = default; + debug_inline constexpr StrongIntegralTypedef(const StrongIntegralTypedef &o) = default; + debug_inline constexpr StrongIntegralTypedef(StrongIntegralTypedef &&o) = default; + + debug_inline constexpr StrongIntegralTypedef(const T &value) : StrongTypedef(value) {} + + debug_inline constexpr Tthis &operator =(const StrongIntegralTypedef &rhs) { this->value = rhs.value; return static_cast(*this); } + debug_inline constexpr Tthis &operator =(StrongIntegralTypedef &&rhs) { this->value = std::move(rhs.value); return static_cast(*this); } + debug_inline constexpr Tthis &operator =(const T &rhs) { this->value = rhs; return static_cast(*this); } + constexpr Tthis &operator ++() { this->value++; return static_cast(*this); } constexpr Tthis &operator --() { this->value--; return static_cast(*this); } constexpr Tthis operator ++(int) { auto res = static_cast(*this); this->value++; return res; } diff --git a/src/crashlog.cpp b/src/crashlog.cpp index c080ec241c1bd..5d26a472782fa 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.cpp @@ -64,12 +64,13 @@ #ifdef WITH_ZLIB # include #endif +#ifdef WITH_CURL +# include +#endif #include "safeguards.h" -/* static */ const char *CrashLog::message = nullptr; -/* static */ char *CrashLog::gamelog_buffer = nullptr; -/* static */ const char *CrashLog::gamelog_last = nullptr; +/* static */ std::string CrashLog::message{ "" }; char *CrashLog::LogCompiler(char *buffer, const char *last) const { @@ -275,19 +276,20 @@ char *CrashLog::LogLibraries(char *buffer, const char *last) const buffer += seprintf(buffer, last, " Zlib: %s\n", zlibVersion()); #endif +#ifdef WITH_CURL + auto *curl_v = curl_version_info(CURLVERSION_NOW); + buffer += seprintf(buffer, last, " Curl: %s\n", curl_v->version); + if (curl_v->ssl_version != nullptr) { + buffer += seprintf(buffer, last, " Curl SSL: %s\n", curl_v->ssl_version); + } else { + buffer += seprintf(buffer, last, " Curl SSL: none\n"); + } +#endif + buffer += seprintf(buffer, last, "\n"); return buffer; } -/** - * Helper function for printing the gamelog. - * @param s the string to print. - */ -/* static */ void CrashLog::GamelogFillCrashLog(const char *s) -{ - CrashLog::gamelog_buffer += seprintf(CrashLog::gamelog_buffer, CrashLog::gamelog_last, "%s\n", s); -} - /** * Writes the gamelog data to the buffer. * @param buffer The begin where to write at. @@ -296,10 +298,10 @@ char *CrashLog::LogLibraries(char *buffer, const char *last) const */ char *CrashLog::LogGamelog(char *buffer, const char *last) const { - CrashLog::gamelog_buffer = buffer; - CrashLog::gamelog_last = last; - GamelogPrint(&CrashLog::GamelogFillCrashLog); - return CrashLog::gamelog_buffer + seprintf(CrashLog::gamelog_buffer, last, "\n"); + GamelogPrint([&buffer, last](const char *s) { + buffer += seprintf(buffer, last, "%s\n", s); + }); + return buffer + seprintf(buffer, last, "\n"); } /** @@ -358,7 +360,7 @@ char *CrashLog::FillCrashLog(char *buffer, const char *last) const ConvertDateToYMD(_date, &ymd); buffer += seprintf(buffer, last, "In game date: %i-%02i-%02i (%i)\n\n", ymd.year, ymd.month + 1, ymd.day, _date_fract); - buffer = this->LogError(buffer, last, CrashLog::message); + buffer = this->LogError(buffer, last, CrashLog::message.c_str()); buffer = this->LogOpenTTDVersion(buffer, last); buffer = this->LogRegisters(buffer, last); buffer = this->LogStacktrace(buffer, last); @@ -413,9 +415,9 @@ bool CrashLog::WriteCrashLog(const char *buffer, char *filename, const char *fil */ bool CrashLog::WriteSavegame(char *filename, const char *filename_last) const { - /* If the map array doesn't exist, saving will fail too. If the map got + /* If the map doesn't exist, saving will fail too. If the map got * initialised, there is a big chance the rest is initialised too. */ - if (_m == nullptr) return false; + if (!Map::IsInitialized()) return false; try { GamelogEmergency(); diff --git a/src/crashlog.h b/src/crashlog.h index b7945a9839de0..5f24fc80d6ac4 100644 --- a/src/crashlog.h +++ b/src/crashlog.h @@ -15,16 +15,8 @@ */ class CrashLog { private: - /** Pointer to the error message. */ - static const char *message; - - /** Temporary 'local' location of the buffer. */ - static char *gamelog_buffer; - - /** Temporary 'local' location of the end of the buffer. */ - static const char *gamelog_last; - - static void GamelogFillCrashLog(const char *s); + /** Error message coming from #error(const char *, ...). */ + static std::string message; protected: /** * Writes OS' version to the buffer. @@ -46,7 +38,7 @@ class CrashLog { * Writes actually encountered error to the buffer. * @param buffer The begin where to write at. * @param last The last position in the buffer to write to. - * @param message Message passed to use for possible errors. Can be nullptr. + * @param message Message passed to use for errors. * @return the position of the \c '\0' character after the buffer. */ virtual char *LogError(char *buffer, const char *last, const char *message) const = 0; diff --git a/src/date.cpp b/src/date.cpp index 0ad55dd67ed4d..1e172bdb1de63 100644 --- a/src/date.cpp +++ b/src/date.cpp @@ -27,7 +27,7 @@ Year _cur_year; ///< Current year, starting at 0 Month _cur_month; ///< Current month (0..11) Date _date; ///< Current date in days (day counter) DateFract _date_fract; ///< Fractional part of the day. -uint32 _tick_counter; ///< Ever incrementing (and sometimes wrapping) tick counter for setting off various events +uint64 _tick_counter; ///< Ever incrementing tick counter for setting off various events /** * Set the date. @@ -264,6 +264,8 @@ static void OnNewYear() VehiclesYearlyLoop(); TownsYearlyLoop(); InvalidateWindowClassesData(WC_BUILD_STATION); + InvalidateWindowClassesData(WC_BUS_STATION); + InvalidateWindowClassesData(WC_TRUCK_STATION); if (_network_server) NetworkServerYearlyLoop(); if (_cur_year == _settings_client.gui.semaphore_build_before) ResetSignalVariant(); diff --git a/src/date_func.h b/src/date_func.h index 8e5ad81b25ab3..c317a5a982976 100644 --- a/src/date_func.h +++ b/src/date_func.h @@ -16,7 +16,7 @@ extern Year _cur_year; extern Month _cur_month; extern Date _date; extern DateFract _date_fract; -extern uint32 _tick_counter; +extern uint64 _tick_counter; enum struct StandardTimeUnits { MINUTES, HOURS, DAYS, length, VANILLA_DAY_MAX_UNITS = length diff --git a/src/debug.cpp b/src/debug.cpp index cf0006e31d66a..7dc90b2bb71eb 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -46,7 +46,7 @@ int _debug_sprite_level; int _debug_oldloader_level; int _debug_npf_level; int _debug_yapf_level; -int _debug_freetype_level; +int _debug_fontcache_level; int _debug_script_level; int _debug_sl_level; int _debug_gamelog_level; @@ -72,7 +72,7 @@ struct DebugLevel { DEBUG_LEVEL(oldloader), DEBUG_LEVEL(npf), DEBUG_LEVEL(yapf), - DEBUG_LEVEL(freetype), + DEBUG_LEVEL(fontcache), DEBUG_LEVEL(script), DEBUG_LEVEL(sl), DEBUG_LEVEL(gamelog), @@ -159,28 +159,31 @@ void DebugPrint(const char *level, const std::string &message) * For setting individual levels a string like \c "net=3,grf=6" should be used. * If the string starts with a number, the number is used as global debugging level. * @param s Text describing the wanted debugging levels. + * @param error_func The function to call if a parse error occurs. */ -void SetDebugString(const char *s) +void SetDebugString(const char *s, void (*error_func)(const char *)) { int v; char *end; const char *t; - /* global debugging level? */ + /* Store planned changes into map during parse */ + std::map new_levels; + + /* Global debugging level? */ if (*s >= '0' && *s <= '9') { const DebugLevel *i; v = strtoul(s, &end, 0); s = end; - for (i = debug_level; i != endof(debug_level); ++i) *i->level = v; + for (i = debug_level; i != endof(debug_level); ++i) { + new_levels[i->name] = v; + } } - /* individual levels */ + /* Individual levels */ for (;;) { - const DebugLevel *i; - int *p; - /* skip delimiters */ while (*s == ' ' || *s == ',' || *s == '\t') s++; if (*s == '\0') break; @@ -189,10 +192,10 @@ void SetDebugString(const char *s) while (*s >= 'a' && *s <= 'z') s++; /* check debugging levels */ - p = nullptr; - for (i = debug_level; i != endof(debug_level); ++i) { + const DebugLevel *found = nullptr; + for (const DebugLevel *i = debug_level; i != endof(debug_level); ++i) { if (s == t + strlen(i->name) && strncmp(t, i->name, s - t) == 0) { - p = i->level; + found = i; break; } } @@ -200,13 +203,22 @@ void SetDebugString(const char *s) if (*s == '=') s++; v = strtoul(s, &end, 0); s = end; - if (p != nullptr) { - *p = v; + if (found != nullptr) { + new_levels[found->name] = v; } else { - ShowInfoF("Unknown debug level '%.*s'", (int)(s - t), t); + std::string error_string = fmt::format("Unknown debug level '{}'", std::string(t, s - t)); + error_func(error_string.c_str()); return; } } + + /* Apply the changes after parse is successful */ + for (const DebugLevel *i = debug_level; i != endof(debug_level); ++i) { + const auto &nl = new_levels.find(i->name); + if (nl != new_levels.end()) { + *i->level = nl->second; + } + } } /** diff --git a/src/debug.h b/src/debug.h index 770bc78823c70..e7db3ee0e3322 100644 --- a/src/debug.h +++ b/src/debug.h @@ -46,7 +46,7 @@ extern int _debug_sprite_level; extern int _debug_oldloader_level; extern int _debug_npf_level; extern int _debug_yapf_level; -extern int _debug_freetype_level; +extern int _debug_fontcache_level; extern int _debug_script_level; extern int _debug_sl_level; extern int _debug_gamelog_level; @@ -57,7 +57,7 @@ extern int _debug_random_level; #endif char *DumpDebugFacilityNames(char *buf, char *last); -void SetDebugString(const char *s); +void SetDebugString(const char *s, void (*error_func)(const char *)); const char *GetDebugString(); /* Shorter form for passing filename and linenumber */ diff --git a/src/depot_func.h b/src/depot_func.h index 42ac476ec3597..bf0bdb3d93388 100644 --- a/src/depot_func.h +++ b/src/depot_func.h @@ -14,6 +14,7 @@ #include "slope_func.h" void ShowDepotWindow(TileIndex tile, VehicleType type); +void InitDepotWindowBlockSizes(); void DeleteDepotHighlightOfVehicle(const Vehicle *v); diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index f95f9ade60656..7f454946ce008 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -24,11 +24,14 @@ #include "tilehighlight_func.h" #include "window_gui.h" #include "vehiclelist.h" +#include "vehicle_func.h" #include "order_backup.h" #include "zoom_func.h" +#include "error.h" #include "depot_cmd.h" #include "train_cmd.h" #include "vehicle_cmd.h" +#include "core/geometry_func.hpp" #include "widgets/depot_widget.h" @@ -190,17 +193,17 @@ static void InitBlocksizeForVehicles(VehicleType type, EngineImageType image_typ if ((int)x + x_offs > max_extend_right) max_extend_right = x + x_offs; } - int min_extend = ScaleGUITrad(16); - int max_extend = ScaleGUITrad(98); + int min_extend = ScaleSpriteTrad(16); + int max_extend = ScaleSpriteTrad(98); switch (image_type) { case EIT_IN_DEPOT: - _base_block_sizes_depot[type].height = std::max(ScaleGUITrad(GetVehicleHeight(type)), max_height); + _base_block_sizes_depot[type].height = std::max(ScaleSpriteTrad(GetVehicleHeight(type)), max_height); _base_block_sizes_depot[type].extend_left = Clamp(max_extend_left, min_extend, max_extend); _base_block_sizes_depot[type].extend_right = Clamp(max_extend_right, min_extend, max_extend); break; case EIT_PURCHASE: - _base_block_sizes_purchase[type].height = std::max(ScaleGUITrad(GetVehicleHeight(type)), max_height); + _base_block_sizes_purchase[type].height = std::max(ScaleSpriteTrad(GetVehicleHeight(type)), max_height); _base_block_sizes_purchase[type].extend_left = Clamp(max_extend_left, min_extend, max_extend); _base_block_sizes_purchase[type].extend_right = Clamp(max_extend_right, min_extend, max_extend); break; @@ -303,18 +306,15 @@ struct DepotWindow : Window { /** * Draw a vehicle in the depot window in the box with the top left corner at x,y. * @param v Vehicle to draw. - * @param left Left side of the box to draw in. - * @param right Right side of the box to draw in. - * @param y Top of the box to draw in. + * @param r Rect to draw in. */ - void DrawVehicleInDepot(const Vehicle *v, int left, int right, int y) const + void DrawVehicleInDepot(const Vehicle *v, const Rect &r) const { bool free_wagon = false; - int sprite_y = y + (this->resize.step_height - ScaleGUITrad(GetVehicleHeight(v->type))) / 2; bool rtl = _current_text_dir == TD_RTL; - int image_left = rtl ? left + this->count_width : left + this->header_width; - int image_right = rtl ? right - this->header_width : right - this->count_width; + Rect text = r.Shrink(RectPadding::zero, WidgetDimensions::scaled.matrix); /* Ract for text elements, horizontal is already applied. */ + Rect image = r.Indent(this->header_width, rtl).Indent(this->count_width, !rtl); /* Rect for vehicle images */ switch (v->type) { case VEH_TRAIN: { @@ -322,45 +322,45 @@ struct DepotWindow : Window { free_wagon = u->IsFreeWagon(); uint x_space = free_wagon ? - ScaleGUITrad(_consistent_train_width != 0 ? _consistent_train_width : TRAININFO_DEFAULT_VEHICLE_WIDTH) : + ScaleSpriteTrad(_consistent_train_width != 0 ? _consistent_train_width : TRAININFO_DEFAULT_VEHICLE_WIDTH) : 0; - DrawTrainImage(u, image_left + (rtl ? 0 : x_space), image_right - (rtl ? x_space : 0), sprite_y - 1, - this->sel, EIT_IN_DEPOT, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over); + DrawTrainImage(u, image.Indent(x_space, rtl), this->sel, EIT_IN_DEPOT, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over); /* Length of consist in tiles with 1 fractional digit (rounded up) */ SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE)); SetDParam(1, 1); - DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter + Rect count = text.WithWidth(this->count_width - WidgetDimensions::scaled.hsep_normal, !rtl); + DrawString(count.left, count.right, count.bottom - FONT_HEIGHT_SMALL + 1, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter break; } - case VEH_ROAD: DrawRoadVehImage( v, image_left, image_right, sprite_y, this->sel, EIT_IN_DEPOT); break; - case VEH_SHIP: DrawShipImage( v, image_left, image_right, sprite_y, this->sel, EIT_IN_DEPOT); break; - case VEH_AIRCRAFT: DrawAircraftImage(v, image_left, image_right, sprite_y, this->sel, EIT_IN_DEPOT); break; + case VEH_ROAD: DrawRoadVehImage( v, image, this->sel, EIT_IN_DEPOT); break; + case VEH_SHIP: DrawShipImage( v, image, this->sel, EIT_IN_DEPOT); break; + case VEH_AIRCRAFT: DrawAircraftImage(v, image, this->sel, EIT_IN_DEPOT); break; default: NOT_REACHED(); } uint diff_x, diff_y; if (v->IsGroundVehicle()) { /* Arrange unitnumber and flag horizontally */ - diff_x = this->flag_width + WD_FRAMERECT_LEFT; - diff_y = (this->resize.step_height - this->flag_height) / 2 - 2; + diff_x = this->flag_size.width + WidgetDimensions::scaled.hsep_normal; + diff_y = WidgetDimensions::scaled.matrix.top; } else { /* Arrange unitnumber and flag vertically */ - diff_x = WD_FRAMERECT_LEFT; - diff_y = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; + diff_x = 0; + diff_y = WidgetDimensions::scaled.matrix.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; } - int text_left = rtl ? right - this->header_width - 1 : left + diff_x; - int text_right = rtl ? right - diff_x : left + this->header_width - 1; + text = text.WithWidth(this->header_width - WidgetDimensions::scaled.hsep_normal, rtl).WithHeight(FONT_HEIGHT_NORMAL).Indent(diff_x, rtl); if (free_wagon) { - DrawString(text_left, text_right, y + 2, STR_DEPOT_NO_ENGINE); + DrawString(text, STR_DEPOT_NO_ENGINE); } else { - DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, rtl ? right - this->flag_width : left + WD_FRAMERECT_LEFT, y + diff_y); + Rect flag = r.WithWidth(this->flag_size.width, rtl).WithHeight(this->flag_size.height).Translate(0, diff_y); + DrawSpriteIgnorePadding((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, flag, false, SA_CENTER); SetDParam(0, v->unitnumber); - DrawString(text_left, text_right, y + 2, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA); + DrawString(text, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA); } } @@ -373,24 +373,28 @@ struct DepotWindow : Window { /* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */ const NWidgetCore *wid = this->GetWidget(WID_D_MATRIX); + /* Set up rect for each cell */ + Rect ir = r.WithHeight(this->resize.step_height); + if (this->num_columns != 1) ir = ir.WithWidth(this->resize.step_width, rtl); + ir = ir.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero); + /* Draw vertical separators at whole tiles. * This only works in two cases: * - All vehicles use VEHICLEINFO_FULL_VEHICLE_WIDTH as reference width. * - All vehicles are 8/8. This cannot be checked for NewGRF, so instead we check for "all vehicles are original vehicles". */ if (this->type == VEH_TRAIN && _consistent_train_width != 0) { - int w = ScaleGUITrad(2 * _consistent_train_width); + int w = ScaleSpriteTrad(2 * _consistent_train_width); int col = _colour_gradient[wid->colour][4]; - int image_left = rtl ? r.left + this->count_width : r.left + this->header_width; - int image_right = rtl ? r.right - this->header_width : r.right - this->count_width; + Rect image = ir.Indent(this->header_width, rtl).Indent(this->count_width, !rtl); int first_line = w + (-this->hscroll->GetPosition()) % w; if (rtl) { - for (int x = image_right - first_line; x >= image_left; x -= w) { - GfxDrawLine(x, r.top, x, r.bottom, col, 1, 3); + for (int x = image.right - first_line; x >= image.left; x -= w) { + GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3)); } } else { - for (int x = image_left + first_line; x <= image_right; x += w) { - GfxDrawLine(x, r.top, x, r.bottom, col, 1, 3); + for (int x = image.left + first_line; x <= image.right; x += w) { + GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3)); } } } @@ -399,26 +403,22 @@ struct DepotWindow : Window { 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 (; num < maxval; ir = ir.Translate(0, this->resize.step_height)) { // Draw the rows + Rect cell = ir; /* Keep track of horizontal cells */ 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) { - this->DrawVehicleInDepot(v, r.left, r.right, y); - } else { - int x = r.left + (rtl ? (this->num_columns - i - 1) : i) * this->resize.step_width; - this->DrawVehicleInDepot(v, x, x + this->resize.step_width - 1, y); - } + this->DrawVehicleInDepot(v, cell); + cell = cell.Translate(rtl ? -(int)this->resize.step_width : (int)this->resize.step_width, 0); } } maxval = static_cast(std::min(this->vehicle_list.size() + this->wagon_list.size(), (this->vscroll->GetPosition() * this->num_columns) + (rows_in_display * this->num_columns))); /* Draw the train wagons without an engine in front. */ - for (; num < maxval; num++, y += this->resize.step_height) { + for (; num < maxval; num++, ir = ir.Translate(0, this->resize.step_height)) { const Vehicle *v = this->wagon_list[num - this->vehicle_list.size()]; - this->DrawVehicleInDepot(v, r.left, r.right, y); + this->DrawVehicleInDepot(v, ir); } } @@ -484,7 +484,7 @@ struct DepotWindow : Window { pos -= (uint)this->vehicle_list.size(); *veh = this->wagon_list[pos]; /* free wagons don't have an initial loco. */ - x -= ScaleGUITrad(VEHICLEINFO_FULL_VEHICLE_WIDTH); + x -= ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH); wagon = true; } @@ -501,12 +501,12 @@ struct DepotWindow : Window { FALLTHROUGH; case VEH_ROAD: - if (xm <= this->flag_width) return MODE_START_STOP; + if (xm <= this->flag_size.width) return MODE_START_STOP; break; case VEH_SHIP: case VEH_AIRCRAFT: - if (xm <= this->flag_width && ym >= (uint)(FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL)) return MODE_START_STOP; + if (xm <= this->flag_size.width && ym >= (uint)(FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal)) return MODE_START_STOP; break; default: NOT_REACHED(); @@ -643,10 +643,16 @@ struct DepotWindow : Window { } } - uint count_width; - uint header_width; - uint flag_width; - uint flag_height; + uint count_width; ///< Width of length count, including separator. + uint header_width; ///< Width of unit number and flag, including separator. + Dimension flag_size; ///< Size of start/stop flag. + VehicleCellSize cell_size; ///< Vehicle sprite cell size. + + void OnInit() override + { + this->cell_size = GetVehicleImageCellSize(this->type, EIT_IN_DEPOT); + this->flag_size = maxdim(GetScaledSpriteSize(SPR_FLAG_VEH_STOPPED), GetScaledSpriteSize(SPR_FLAG_VEH_RUNNING)); + } void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { @@ -657,33 +663,30 @@ struct DepotWindow : Window { if (this->type == VEH_TRAIN) { SetDParamMaxValue(0, 1000, 0, FS_SMALL); SetDParam(1, 1); - this->count_width = GetStringBoundingBox(STR_TINY_BLACK_DECIMAL).width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + this->count_width = GetStringBoundingBox(STR_TINY_BLACK_DECIMAL).width + WidgetDimensions::scaled.hsep_normal; } else { this->count_width = 0; } SetDParamMaxDigits(0, this->unitnumber_digits); Dimension unumber = GetStringBoundingBox(STR_BLACK_COMMA); - const Sprite *spr = GetSprite(SPR_FLAG_VEH_STOPPED, ST_NORMAL); - this->flag_width = UnScaleGUI(spr->width) + WD_FRAMERECT_RIGHT; - this->flag_height = UnScaleGUI(spr->height); if (this->type == VEH_TRAIN || this->type == VEH_ROAD) { - min_height = std::max(unumber.height + WD_MATRIX_TOP, UnScaleGUI(spr->height)); - this->header_width = unumber.width + this->flag_width + WD_FRAMERECT_LEFT; + min_height = std::max(unumber.height, this->flag_size.height); + this->header_width = unumber.width + WidgetDimensions::scaled.hsep_normal + this->flag_size.width + WidgetDimensions::scaled.hsep_normal; } else { - min_height = unumber.height + UnScaleGUI(spr->height) + WD_MATRIX_TOP + WD_PAR_VSEP_NORMAL + WD_MATRIX_BOTTOM; - this->header_width = std::max(unumber.width, this->flag_width) + WD_FRAMERECT_RIGHT; + min_height = unumber.height + WidgetDimensions::scaled.vsep_normal + this->flag_size.height; + this->header_width = std::max(unumber.width, this->flag_size.width) + WidgetDimensions::scaled.hsep_normal; } - int base_width = this->count_width + this->header_width; + int base_width = this->count_width + this->header_width + padding.width; - resize->height = std::max(GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).height, min_height); + resize->height = std::max(this->cell_size.height, min_height + padding.height); if (this->type == VEH_TRAIN) { resize->width = 1; - size->width = base_width + 2 * ScaleGUITrad(29); // about 2 parts + size->width = base_width + 2 * ScaleSpriteTrad(29); // about 2 parts size->height = resize->height * 6; } else { - resize->width = base_width + GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).extend_left + GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).extend_right; + resize->width = base_width + this->cell_size.extend_left + this->cell_size.extend_right; size->width = resize->width * (this->type == VEH_ROAD ? 5 : 3); size->height = resize->height * (this->type == VEH_ROAD ? 5 : 3); } @@ -723,7 +726,7 @@ struct DepotWindow : Window { /* determine amount of items for scroller */ if (this->type == VEH_TRAIN) { - uint max_width = ScaleGUITrad(VEHICLEINFO_FULL_VEHICLE_WIDTH); + uint max_width = ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH); for (uint num = 0; num < this->vehicle_list.size(); num++) { uint width = 0; for (const Train *v = Train::From(this->vehicle_list[num]); v != nullptr; v = v->Next()) { @@ -734,7 +737,7 @@ struct DepotWindow : Window { /* Always have 1 empty row, so people can change the setting of the train */ this->vscroll->SetCount((uint)this->vehicle_list.size() + (uint)this->wagon_list.size() + 1); /* Always make it longer than the longest train, so you can attach vehicles at the end, and also see the next vertical tile separator line */ - this->hscroll->SetCount(max_width + ScaleGUITrad(2 * VEHICLEINFO_FULL_VEHICLE_WIDTH + 1)); + this->hscroll->SetCount(max_width + ScaleSpriteTrad(2 * VEHICLEINFO_FULL_VEHICLE_WIDTH + 1)); } else { this->vscroll->SetCount(CeilDiv((uint)this->vehicle_list.size(), this->num_columns)); } @@ -916,6 +919,49 @@ struct DepotWindow : Window { return true; } + /** + * Clones a vehicle from a vehicle list. If this doesn't make sense (because not all vehicles in the list have the same orders), then it displays an error. + * @return This always returns true, which indicates that the contextual action handled the mouse click. + * Note that it's correct behaviour to always handle the click even though an error is displayed, + * because users aren't going to expect the default action to be performed just because they overlooked that cloning doesn't make sense. + */ + bool OnVehicleSelect(VehicleList::const_iterator begin, VehicleList::const_iterator end) override + { + if (!_ctrl_pressed) { + /* If CTRL is not pressed: If all the vehicles in this list have the same orders, then copy orders */ + if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) { + return VehiclesHaveSameEngineList(v1, v2); + })) { + if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) { + return VehiclesHaveSameOrderList(v1, v2); + })) { + OnVehicleSelect(*begin); + } else { + ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST, WL_INFO); + } + } else { + ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_CLONE_VEHICLE_LIST, WL_INFO); + } + } else { + /* If CTRL is pressed: If all the vehicles in this list share orders, then copy orders */ + if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) { + return VehiclesHaveSameEngineList(v1, v2); + })) { + if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) { + return v1->FirstShared() == v2->FirstShared(); + })) { + OnVehicleSelect(*begin); + } else { + ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST, WL_INFO); + } + } else { + ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_CLONE_VEHICLE_LIST, WL_INFO); + } + } + + return true; + } + void OnPlaceObjectAbort() override { /* abort clone */ diff --git a/src/depot_map.h b/src/depot_map.h index f92ca9f6e40e9..939569bd8546f 100644 --- a/src/depot_map.h +++ b/src/depot_map.h @@ -15,7 +15,7 @@ /** * Check if a tile is a depot and it is a depot of the given type. */ -static inline bool IsDepotTypeTile(TileIndex tile, TransportType type) +static inline bool IsDepotTypeTile(Tile tile, TransportType type) { switch (type) { default: NOT_REACHED(); @@ -38,7 +38,7 @@ static inline bool IsDepotTypeTile(TileIndex tile, TransportType type) * @param tile the tile to check * @return true if and only if there is a depot on the tile. */ -static inline bool IsDepotTile(TileIndex tile) +static inline bool IsDepotTile(Tile tile) { return IsRailDepotTile(tile) || IsRoadDepotTile(tile) || IsShipDepotTile(tile) || IsHangarTile(tile); } @@ -49,11 +49,11 @@ static inline bool IsDepotTile(TileIndex tile) * @pre IsRailDepotTile(t) || IsRoadDepotTile(t) || IsShipDepotTile(t) * @return DepotID */ -static inline DepotID GetDepotIndex(TileIndex t) +static inline DepotID GetDepotIndex(Tile t) { /* Hangars don't have a Depot class, thus store no DepotID. */ assert(IsRailDepotTile(t) || IsRoadDepotTile(t) || IsShipDepotTile(t)); - return _m[t].m2; + return t.m2(); } /** @@ -62,7 +62,7 @@ static inline DepotID GetDepotIndex(TileIndex t) * @pre IsDepotTile(t) * @return the type of vehicles that can use the depot */ -static inline VehicleType GetDepotVehicleType(TileIndex t) +static inline VehicleType GetDepotVehicleType(Tile t) { switch (GetTileType(t)) { default: NOT_REACHED(); diff --git a/src/depot_type.h b/src/depot_type.h index a2326794a06a0..8c41857138d26 100644 --- a/src/depot_type.h +++ b/src/depot_type.h @@ -10,9 +10,13 @@ #ifndef DEPOT_TYPE_H #define DEPOT_TYPE_H +#include "station_type.h" + typedef uint16 DepotID; ///< Type for the unique identifier of depots. struct Depot; +static const DepotID INVALID_DEPOT = (DepotID)INVALID_STATION; + static const uint MAX_LENGTH_DEPOT_NAME_CHARS = 32; ///< The maximum length of a depot name in characters including '\0' #endif /* DEPOT_TYPE_H */ diff --git a/src/direction_type.h b/src/direction_type.h index f025d113e7b96..cb4595f09a5a1 100644 --- a/src/direction_type.h +++ b/src/direction_type.h @@ -102,10 +102,12 @@ template <> struct EnumPropsT : MakeEnumPropsTNext(); if (u != nullptr) { - int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE); - int safe_y = Clamp(y - 1, 0, MapMaxY() * TILE_SIZE); + int safe_x = Clamp(x, 0, Map::MaxX() * TILE_SIZE); + int safe_y = Clamp(y - 1, 0, Map::MaxY() * TILE_SIZE); u->x_pos = x; u->y_pos = y - 1 - (std::max(z - GetSlopePixelZ(safe_x, safe_y), 0) >> 3); - safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE); + safe_y = Clamp(u->y_pos, 0, Map::MaxY() * TILE_SIZE); u->z_pos = GetSlopePixelZ(safe_x, safe_y); u->direction = this->direction; @@ -249,7 +250,7 @@ static bool DisasterTick_Zeppeliner(DisasterVehicle *v) } } - if (v->y_pos >= (int)((MapSizeY() + 9) * TILE_SIZE - 1)) { + if (v->y_pos >= (int)((Map::SizeY() + 9) * TILE_SIZE - 1)) { delete v; return false; } @@ -399,7 +400,7 @@ static bool DisasterTick_Ufo(DisasterVehicle *v) static void DestructIndustry(Industry *i) { - for (TileIndex tile = 0; tile != MapSize(); tile++) { + for (TileIndex tile = 0; tile != Map::Size(); tile++) { if (i->TileBelongsToIndustry(tile)) { ResetIndustryConstructionStage(tile); MarkTileDirtyByTile(tile); @@ -428,7 +429,7 @@ static bool DisasterTick_Aircraft(DisasterVehicle *v, uint16 image_override, boo GetNewVehiclePosResult gp = GetNewVehiclePos(v); v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v)); - if ((leave_at_top && gp.x < (-10 * (int)TILE_SIZE)) || (!leave_at_top && gp.x > (int)(MapSizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1)) { + if ((leave_at_top && gp.x < (-10 * (int)TILE_SIZE)) || (!leave_at_top && gp.x > (int)(Map::SizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1)) { delete v; return false; } @@ -464,7 +465,7 @@ static bool DisasterTick_Aircraft(DisasterVehicle *v, uint16 image_override, boo int x = v->x_pos + ((leave_at_top ? -15 : 15) * TILE_SIZE); int y = v->y_pos; - if ((uint)x > MapMaxX() * TILE_SIZE - 1) return true; + if ((uint)x > Map::MaxX() * TILE_SIZE - 1) return true; TileIndex tile = TileVirtXY(x, y); if (!IsTileType(tile, MP_INDUSTRY)) return true; @@ -578,17 +579,34 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v) } v->current_order.SetDestination(1); - TileIndex tile_org = RandomTile(); - TileIndex tile = tile_org; - do { - if (IsPlainRailTile(tile) && - Company::IsHumanID(GetTileOwner(tile))) { + const auto is_valid_target = [](const Train *t) { + return t->IsFrontEngine() // Only the engines + && Company::IsHumanID(t->owner) // Don't break AIs + && IsPlainRailTile(t->tile) // No tunnels + && (t->vehstatus & VS_CRASHED) == 0; // Not crashed + }; + + uint n = 0; // Total number of targetable trains. + for (const Train *t : Train::Iterate()) { + if (is_valid_target(t)) n++; + } + + if (n == 0) { + /* If there are no targetable trains, destroy the UFO. */ + delete v; + return false; + } + + n = RandomRange(n); // Choose one of them. + for (const Train *t : Train::Iterate()) { + /* Find (n+1)-th train. */ + if (is_valid_target(t) && (n-- == 0)) { + /* Target it. */ + v->dest_tile = t->tile; + v->age = 0; break; } - tile = TILE_MASK(tile + 1); - } while (tile != tile_org); - v->dest_tile = tile; - v->age = 0; + } } return true; @@ -605,7 +623,7 @@ static bool DisasterTick_Big_Ufo_Destroyer(DisasterVehicle *v) GetNewVehiclePosResult gp = GetNewVehiclePos(v); v->UpdatePosition(gp.x, gp.y, GetAircraftFlightLevel(v)); - if (gp.x > (int)(MapSizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1) { + if (gp.x > (int)(Map::SizeX() * TILE_SIZE + 9 * TILE_SIZE) - 1) { delete v; return false; } @@ -733,7 +751,7 @@ static void Disaster_Small_Ufo_Init() int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; DisasterVehicle *v = new DisasterVehicle(x, 0, DIR_SE, ST_SMALL_UFO); - v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2); + v->dest_tile = TileXY(Map::SizeX() / 2, Map::SizeY() / 2); /* Allocate shadow */ DisasterVehicle *u = new DisasterVehicle(x, 0, DIR_SE, ST_SMALL_UFO_SHADOW); @@ -758,7 +776,7 @@ static void Disaster_Airplane_Init() if (found == nullptr) return; /* Start from the bottom (south side) of the map */ - int x = (MapSizeX() + 9) * TILE_SIZE - 1; + int x = (Map::SizeX() + 9) * TILE_SIZE - 1; int y = TileY(found->location.tile) * TILE_SIZE + 37; DisasterVehicle *v = new DisasterVehicle(x, y, DIR_NE, ST_AIRPLANE); @@ -802,10 +820,10 @@ static void Disaster_Big_Ufo_Init() if (!Vehicle::CanAllocateItem(2)) return; int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; - int y = MapMaxX() * TILE_SIZE - 1; + int y = Map::MaxX() * TILE_SIZE - 1; DisasterVehicle *v = new DisasterVehicle(x, y, DIR_NW, ST_BIG_UFO); - v->dest_tile = TileXY(MapSizeX() / 2, MapSizeY() / 2); + v->dest_tile = TileXY(Map::SizeX() / 2, Map::SizeY() / 2); /* Allocate shadow */ DisasterVehicle *u = new DisasterVehicle(x, y, DIR_NW, ST_BIG_UFO_SHADOW); @@ -823,7 +841,7 @@ static void Disaster_Submarine_Init(DisasterSubType subtype) int x = TileX(r) * TILE_SIZE + TILE_SIZE / 2; if (HasBit(r, 31)) { - y = MapMaxY() * TILE_SIZE - TILE_SIZE / 2 - 1; + y = Map::MaxY() * TILE_SIZE - TILE_SIZE / 2 - 1; dir = DIR_NW; } else { y = TILE_SIZE / 2; diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp index 2ec10fe8ce927..2477450fa3b3a 100644 --- a/src/dock_gui.cpp +++ b/src/dock_gui.cpp @@ -192,7 +192,7 @@ struct BuildDocksToolbarWindow : Window { { switch (this->last_clicked_widget) { case WID_DT_CANAL: // Build canal button - VpStartPlaceSizing(tile, (_game_mode == GM_EDITOR) ? VPM_X_AND_Y : VPM_X_OR_Y, DDSP_CREATE_WATER); + VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_WATER); break; case WID_DT_LOCK: // Build lock button @@ -416,6 +416,7 @@ enum BuildDockStationWidgets { BDSW_LT_OFF, ///< 'Off' button of coverage high light. BDSW_LT_ON, ///< 'On' button of coverage high light. BDSW_INFO, ///< 'Coverage highlight' label. + BDSW_ACCEPTANCE, ///< Acceptance info. }; struct BuildDocksStationWindow : public PickerWindowBase { @@ -445,17 +446,15 @@ struct BuildDocksStationWindow : public PickerWindowBase { } /* strings such as 'Size' and 'Coverage Area' */ - int top = this->GetWidget(BDSW_LT_OFF)->pos_y + this->GetWidget(BDSW_LT_OFF)->current_y + WD_PAR_VSEP_NORMAL; - NWidgetBase *back_nwi = this->GetWidget(BDSW_BACKGROUND); - int right = back_nwi->pos_x + back_nwi->current_x; - int bottom = back_nwi->pos_y + back_nwi->current_y; - top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, SCT_ALL, rad, false) + WD_PAR_VSEP_NORMAL; - top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, SCT_ALL, rad, true) + WD_PAR_VSEP_NORMAL; + Rect r = this->GetWidget(BDSW_ACCEPTANCE)->GetCurrentRect(); + int top = r.top + WidgetDimensions::scaled.vsep_normal; + top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, false) + WidgetDimensions::scaled.vsep_normal; + top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, true) + WidgetDimensions::scaled.vsep_normal; /* Resize background if the window is too small. * Never make the window smaller to avoid oscillating if the size change affects the acceptance. * (This is the case, if making the window bigger moves the mouse into the window.) */ - if (top > bottom) { - ResizeWindow(this, 0, top - bottom, false); + if (top > r.bottom) { + ResizeWindow(this, 0, top - r.bottom, false); } } @@ -487,13 +486,12 @@ static const NWidgetPart _nested_build_dock_station_widgets[] = { NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_DOCK_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BDSW_BACKGROUND), - NWidget(NWID_SPACER), SetMinimalSize(0, 3), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN, BDSW_INFO), SetMinimalSize(148, 14), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), - NWidget(NWID_HORIZONTAL), SetPIP(14, 0, 14), - NWidget(WWT_TEXTBTN, COLOUR_GREY, BDSW_LT_OFF), SetMinimalSize(40, 12), SetFill(1, 0), SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, BDSW_LT_ON), SetMinimalSize(40, 12), SetFill(1, 0), SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN, BDSW_INFO), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(14, 0, 14), + NWidget(WWT_TEXTBTN, COLOUR_GREY, BDSW_LT_OFF), SetMinimalSize(60, 12), SetFill(1, 0), SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, BDSW_LT_ON), SetMinimalSize(60, 12), SetFill(1, 0), SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 20), SetResize(0, 1), + NWidget(WWT_EMPTY, COLOUR_GREY, BDSW_ACCEPTANCE), SetPadding(WidgetDimensions::unscaled.framerect), SetResize(0, 1), EndContainer(), }; @@ -533,25 +531,33 @@ struct BuildDocksDepotWindow : public PickerWindowBase { switch (widget) { case WID_BDD_X: case WID_BDD_Y: - size->width = ScaleGUITrad(96) + 2; - size->height = ScaleGUITrad(64) + 2; + size->width = ScaleGUITrad(96) + WidgetDimensions::scaled.fullbevel.Horizontal(); + size->height = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Vertical(); break; } } - void OnPaint() override + void DrawWidget(const Rect &r, int widget) const override { - this->DrawWidgets(); - - int x1 = ScaleGUITrad(63) + 1; - int x2 = ScaleGUITrad(31) + 1; - int y1 = ScaleGUITrad(17) + 1; - int y2 = ScaleGUITrad(33) + 1; + DrawPixelInfo tmp_dpi; - DrawShipDepotSprite(this->GetWidget(WID_BDD_X)->pos_x + x1, this->GetWidget(WID_BDD_X)->pos_y + y1, AXIS_X, DEPOT_PART_NORTH); - DrawShipDepotSprite(this->GetWidget(WID_BDD_X)->pos_x + x2, this->GetWidget(WID_BDD_X)->pos_y + y2, AXIS_X, DEPOT_PART_SOUTH); - DrawShipDepotSprite(this->GetWidget(WID_BDD_Y)->pos_x + x2, this->GetWidget(WID_BDD_Y)->pos_y + y1, AXIS_Y, DEPOT_PART_NORTH); - DrawShipDepotSprite(this->GetWidget(WID_BDD_Y)->pos_x + x1, this->GetWidget(WID_BDD_Y)->pos_y + y2, AXIS_Y, DEPOT_PART_SOUTH); + switch (widget) { + case WID_BDD_X: + case WID_BDD_Y: { + Axis axis = widget == WID_BDD_X ? AXIS_X : AXIS_Y; + + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); + int x = (r.Width() - ScaleSpriteTrad(96)) / 2; + int y = (r.Height() - ScaleSpriteTrad(64)) / 2; + int x1 = ScaleSpriteTrad(63); + int x2 = ScaleSpriteTrad(31); + DrawShipDepotSprite(x + (axis == AXIS_X ? x1 : x2), y + ScaleSpriteTrad(17), axis, DEPOT_PART_NORTH); + DrawShipDepotSprite(x + (axis == AXIS_X ? x2 : x1), y + ScaleSpriteTrad(33), axis, DEPOT_PART_SOUTH); + } + break; + } + } } void OnClick(Point pt, int widget, int click_count) override @@ -576,17 +582,14 @@ static const NWidgetPart _nested_build_docks_depot_widgets[] = { NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_DEPOT_BUILD_SHIP_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BDD_BACKGROUND), - NWidget(NWID_SPACER), SetMinimalSize(0, 3), - NWidget(NWID_HORIZONTAL_LTR), - NWidget(NWID_SPACER), SetMinimalSize(3, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_X), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(2, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_Y), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), + NWidget(NWID_HORIZONTAL), SetPadding(3), + NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, 2, 0), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_X), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_Y), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), EndContainer(), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(3, 0), + NWidget(NWID_SPACER), SetFill(1, 0), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 3), EndContainer(), }; diff --git a/src/economy.cpp b/src/economy.cpp index a30c8a9805d9e..a23794d070c03 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -26,6 +26,7 @@ #include "newgrf_industrytiles.h" #include "newgrf_station.h" #include "newgrf_airporttiles.h" +#include "newgrf_roadstop.h" #include "object.h" #include "strings_func.h" #include "date_func.h" @@ -103,6 +104,8 @@ Economy _economy; Prices _price; static PriceMultipliers _price_base_multiplier; +extern int GetAmountOwnedBy(const Company *c, Owner owner); + int GetLoanInterval() { return VANILLA_LOAN_INTERVAL * GetPaceFactor(); } @@ -121,18 +124,12 @@ Money CalculateCompanyValue(const Company *c, bool including_loan) Money owned_shares_value = 0; for (const Company *co : Company::Iterate()) { - uint8 shares_owned = 0; - - for (uint8 i = 0; i < 4; i++) { - if (co->share_owners[i] == c->index) { - shares_owned++; - } - } + int shares_owned = GetAmountOwnedBy(co, c->index); - owned_shares_value += (CalculateCompanyValueExcludingShares(co) / 4) * shares_owned; + if (shares_owned > 0) owned_shares_value += (CalculateCompanyValueExcludingShares(co) / 4) * shares_owned; } - return std::max(owned_shares_value + CalculateCompanyValueExcludingShares(c), 1); + return owned_shares_value + CalculateCompanyValueExcludingShares(c); } Money CalculateCompanyValueExcludingShares(const Company *c, bool including_loan) @@ -501,7 +498,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) TileIndex tile = 0; do { ChangeTileOwner(tile, old_owner, new_owner); - } while (++tile != MapSize()); + } while (++tile != Map::Size()); if (new_owner != INVALID_OWNER) { /* Update all signals because there can be new segment that was owned by two companies @@ -520,7 +517,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } else if (IsLevelCrossingTile(tile) && IsTileOwner(tile, new_owner)) { UpdateLevelCrossing(tile); } - } while (++tile != MapSize()); + } while (++tile != Map::Size()); } /* update signals in buffer */ @@ -577,7 +574,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) static void CompanyCheckBankrupt(Company *c) { /* If the company has money again, it does not go bankrupt */ - if (c->money - c->current_loan >= -_economy.max_loan) { + if (c->money - c->current_loan >= -_economy.max_loan * GetPaceFactor()) { int previous_months_of_bankruptcy = CeilDiv(c->months_of_bankruptcy, 3); c->months_of_bankruptcy = 0; c->bankrupt_asked = 0; @@ -767,11 +764,8 @@ bool AddInflation(bool check_year) */ void RecomputePrices() { - /* Setup maximum loan */ - _economy.max_loan = ((uint64)_settings_game.difficulty.max_loan * _economy.inflation_prices >> 16) / 50000 * 50000; - - // SLOWPACE: money scaling - _economy.max_loan *= GetPaceFactor(); + /* Setup maximum loan as a rounded down multiple of LOAN_INTERVAL. */ + _economy.max_loan = ((uint64)_settings_game.difficulty.max_loan * _economy.inflation_prices >> 16) / LOAN_INTERVAL * LOAN_INTERVAL; /* Setup price bases */ for (Price i = PR_BEGIN; i < PR_END; i++) { @@ -920,7 +914,7 @@ void SetPriceBaseMultiplier(Price price, int factor) */ void StartupIndustryDailyChanges(bool init_counter) { - uint map_size = MapLogX() + MapLogY(); + uint map_size = Map::LogX() + Map::LogY(); /* After getting map size, it needs to be scaled appropriately and divided by 31, * which stands for the days in a month. * Using just 31 will make it so that a monthly reset (based on the real number of days of that month) @@ -1515,7 +1509,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station if (st->goods[cid].cargo.HasCargoFor(next_station)) { /* Try to find out if auto-refitting would succeed. In case the refit is allowed, * the returned refit capacity will be greater than zero. */ - auto [cc, refit_capacity, mail_capacity] = Command::Do(DC_QUERY_COST, v_start->index, cid, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts. + auto [cc, refit_capacity, mail_capacity, cargo_capacities] = Command::Do(DC_QUERY_COST, v_start->index, cid, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts. /* Try to balance different loadable cargoes between parts of the consist, so that * all of them can be loaded. Avoid a situation where all vehicles suddenly switch * to the first loadable cargo for which there is only one packet. If the capacities @@ -1834,6 +1828,8 @@ static void LoadUnloadVehicle(Vehicle *front) TriggerStationRandomisation(st, st->xy, SRT_CARGO_TAKEN, v->cargo_type); TriggerStationAnimation(st, st->xy, SAT_CARGO_TAKEN, v->cargo_type); AirportAnimationTrigger(st, AAT_STATION_CARGO_TAKEN, v->cargo_type); + TriggerRoadStopRandomisation(st, st->xy, RSRT_CARGO_TAKEN, v->cargo_type); + TriggerRoadStopAnimation(st, st->xy, SAT_CARGO_TAKEN, v->cargo_type); } new_load_unload_ticks += loaded; @@ -1854,6 +1850,9 @@ static void LoadUnloadVehicle(Vehicle *front) if (front->type == VEH_TRAIN) { TriggerStationRandomisation(st, front->tile, SRT_TRAIN_LOADS); TriggerStationAnimation(st, front->tile, SAT_TRAIN_LOADS); + } else if (front->type == VEH_ROAD) { + TriggerRoadStopRandomisation(st, front->tile, RSRT_VEH_LOADS); + TriggerRoadStopAnimation(st, front->tile, SAT_TRAIN_LOADS); } } @@ -2035,8 +2034,6 @@ static void DoAcquireCompany(Company *c) delete c; } -extern int GetAmountOwnedBy(const Company *c, Owner owner); - /** * Acquire shares in an opposing company. * @param flags type of operation diff --git a/src/economy_type.h b/src/economy_type.h index 749e9a7fc8d28..ff3982085df57 100644 --- a/src/economy_type.h +++ b/src/economy_type.h @@ -26,7 +26,7 @@ enum EconomyType : uint8 { /** Data of the economy. */ struct Economy { - Money max_loan; ///< NOSAVE: Maximum possible loan + Money max_loan; ///< NOSAVE: Maximum possible loan. Not Pace-scaled! int16 fluct; ///< Economy fluctuation status byte interest_rate; ///< Interest byte infl_amount; ///< inflation amount diff --git a/src/effectvehicle.cpp b/src/effectvehicle.cpp index 9f1f070172995..c0ac226953b62 100644 --- a/src/effectvehicle.cpp +++ b/src/effectvehicle.cpp @@ -621,8 +621,8 @@ EffectVehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicleType type) */ EffectVehicle *CreateEffectVehicleAbove(int x, int y, int z, EffectVehicleType type) { - int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE); - int safe_y = Clamp(y, 0, MapMaxY() * TILE_SIZE); + int safe_x = Clamp(x, 0, Map::MaxX() * TILE_SIZE); + int safe_y = Clamp(y, 0, Map::MaxY() * TILE_SIZE); return CreateEffectVehicle(x, y, GetSlopePixelZ(safe_x, safe_y) + z, type); } diff --git a/src/elrail.cpp b/src/elrail.cpp index 03adb0c8c945e..36c5396f11ba3 100644 --- a/src/elrail.cpp +++ b/src/elrail.cpp @@ -234,7 +234,9 @@ static int GetPCPElevation(TileIndex tile, DiagDirection PCPpos) int z = GetSlopePixelZ(TileX(tile) * TILE_SIZE + std::min(x_pcp_offsets[PCPpos], TILE_SIZE - 1), TileY(tile) * TILE_SIZE + std::min(y_pcp_offsets[PCPpos], TILE_SIZE - 1)); - return (z + 2) & ~3; // this means z = (z + TILE_HEIGHT / 4) / (TILE_HEIGHT / 2) * (TILE_HEIGHT / 2); + /* Round the Z to the nearest half tile height. */ + static const uint HALF_TILE_HEIGHT = TILE_HEIGHT / 2; + return (z + HALF_TILE_HEIGHT / 2) / HALF_TILE_HEIGHT * HALF_TILE_HEIGHT; } /** @@ -485,10 +487,11 @@ static void DrawRailCatenaryRailway(const TileInfo *ti) /* * The "wire"-sprite position is inside the tile, i.e. 0 <= sss->?_offset < TILE_SIZE. * Therefore it is safe to use GetSlopePixelZ() for the elevation. - * Also note that the result of GetSlopePixelZ() is very special for bridge-ramps. + * Also note that the result of GetSlopePixelZ() is very special for bridge-ramps, so we round the result up or + * down to the nearest full height change. */ AddSortableSpriteToDraw(wire_base + sss->image_offset, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset, - sss->x_size, sss->y_size, sss->z_size, GetSlopePixelZ(ti->x + sss->x_offset, ti->y + sss->y_offset) + sss->z_offset, + sss->x_size, sss->y_size, sss->z_size, (GetSlopePixelZ(ti->x + sss->x_offset, ti->y + sss->y_offset) + 4) / 8 * 8 + sss->z_offset, IsTransparencySet(TO_CATENARY)); } } @@ -596,16 +599,14 @@ void SettingsDisableElrail(int32 new_value) { bool disable = (new_value != 0); - /* we will now walk through all electric train engines and change their railtypes if it is the wrong one*/ - const RailType old_railtype = disable ? RAILTYPE_ELECTRIC : RAILTYPE_RAIL; + /* pick appropriate railtype for elrail engines depending on setting */ const RailType new_railtype = disable ? RAILTYPE_RAIL : RAILTYPE_ELECTRIC; /* walk through all train engines */ for (Engine *e : Engine::IterateType(VEH_TRAIN)) { RailVehicleInfo *rv_info = &e->u.rail; - /* if it is an electric rail engine and its railtype is the wrong one */ - if (rv_info->engclass == 2 && rv_info->railtype == old_railtype) { - /* change it to the proper one */ + /* update railtype of engines intended to use elrail */ + if (rv_info->intended_railtype == RAILTYPE_ELECTRIC) { rv_info->railtype = new_railtype; } } diff --git a/src/engine.cpp b/src/engine.cpp index 6d0b25fcc751c..649c49804dec6 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -73,9 +73,12 @@ Engine::Engine(VehicleType type, EngineID base) this->grf_prop.local_id = base; this->list_position = base; this->preview_company = INVALID_COMPANY; + this->display_last_variant = INVALID_ENGINE; /* Check if this base engine is within the original engine data range */ if (base >= _engine_counts[type]) { + /* 'power' defaults to zero, so we also have to default to 'wagon' */ + if (type == VEH_TRAIN) this->u.rail.railveh_type = RAILVEH_WAGON; /* Set model life to maximum to make wagons available */ this->info.base_life = 0xFF; /* Set road vehicle tractive effort to the default value */ @@ -91,6 +94,8 @@ Engine::Engine(VehicleType type, EngineID base) } /* Set cargo aging period to the default value. */ this->info.cargo_age_period = CARGO_AGING_TICKS; + /* Not a variant */ + this->info.variant_id = INVALID_ENGINE; return; } @@ -533,7 +538,7 @@ void SetupEngines() _engine_pool.CleanPool(); assert(_engine_mngr.size() >= _engine_mngr.NUM_DEFAULT_ENGINES); - uint index = 0; + [[maybe_unused]] uint index = 0; for (const EngineIDMapping &eid : _engine_mngr) { /* Assert is safe; there won't be more than 256 original vehicles * in any case, and we just cleaned the pool. */ @@ -557,13 +562,32 @@ static bool IsWagon(EngineID index) return e->type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON; } +/** + * Ensure engine is not set as the last used variant for any other engine. + * @param engine_id Engine being removed. + * @param type Type of engine. + */ +static void ClearLastVariant(EngineID engine_id, VehicleType type) +{ + for (Engine *e : Engine::IterateType(type)) { + if (e->display_last_variant == engine_id) e->display_last_variant = INVALID_ENGINE; + } +} + /** * Update #Engine::reliability and (if needed) update the engine GUIs. * @param e %Engine to update. */ -static void CalcEngineReliability(Engine *e) +void CalcEngineReliability(Engine *e, bool new_month) { - uint age = e->age; + /* Get source engine for reliability age. This is normally our engine unless variant reliability syncing is requested. */ + Engine *re = e; + while (re->info.variant_id != INVALID_ENGINE && re->info.variant_id != re->index && (re->info.extra_flags & ExtraEngineFlags::SyncReliability) != ExtraEngineFlags::None) { + re = Engine::Get(re->info.variant_id); + } + + uint age = re->age; + if (new_month && re->index > e->index && age != MAX_DAY) age++; /* parent variant's age has not yet updated. */ /* Check for early retirement */ if (e->company_avail != 0 && !_settings_game.vehicle.never_expire_vehicles && e->info.base_life != 0xFF) { @@ -572,6 +596,7 @@ static void CalcEngineReliability(Engine *e) if (retire_early != 0 && age >= retire_early_max_age) { /* Early retirement is enabled and we're past the date... */ e->company_avail = 0; + ClearLastVariant(e->index, e->type); AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type); } } @@ -592,10 +617,10 @@ static void CalcEngineReliability(Engine *e) e->company_avail = 0; e->reliability = e->reliability_final; /* Kick this engine out of the lists */ + ClearLastVariant(e->index, e->type); AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type); } - SetWindowClassesDirty(WC_BUILD_VEHICLE); // Update to show the new reliability - SetWindowClassesDirty(WC_REPLACE_VEHICLE); + } /** Compute the value for #_year_engine_aging_stops. */ @@ -623,8 +648,9 @@ void SetYearEngineAgingStops() * Start/initialise one engine. * @param e The engine to initialise. * @param aging_date The date used for age calculations. + * @param seed Random seed. */ -void StartupOneEngine(Engine *e, Date aging_date) +void StartupOneEngine(Engine *e, Date aging_date, uint32 seed) { const EngineInfo *ei = &e->info; @@ -637,7 +663,7 @@ void StartupOneEngine(Engine *e, Date aging_date) * Make sure they use the same randomisation of the date. */ SavedRandomSeeds saved_seeds; SaveRandomSeeds(&saved_seeds); - SetRandomSeed(_settings_game.game_creation.generation_seed ^ + SetRandomSeed(_settings_game.game_creation.generation_seed ^ seed ^ ei->base_intro ^ e->type ^ e->GetGRFID()); @@ -653,7 +679,17 @@ void StartupOneEngine(Engine *e, Date aging_date) e->flags |= ENGINE_AVAILABLE; } - RestoreRandomSeeds(saved_seeds); + /* Get parent variant index for syncing reliability via random seed. */ + const Engine *re = e; + while (re->info.variant_id != INVALID_ENGINE && re->info.variant_id != re->index && (re->info.extra_flags & ExtraEngineFlags::SyncReliability) != ExtraEngineFlags::None) { + re = Engine::Get(re->info.variant_id); + } + + SetRandomSeed(_settings_game.game_creation.generation_seed ^ seed ^ + (re->index << 16) ^ (re->info.base_intro << 12) ^ (re->info.decay_speed << 8) ^ + (re->info.lifelength << 4) ^ re->info.retire_early ^ + e->type ^ + e->GetGRFID()); r = Random(); e->reliability_start = GB(r, 16, 14) + 0x7AE0; @@ -665,9 +701,9 @@ void StartupOneEngine(Engine *e, Date aging_date) e->duration_phase_2 = GB(r, 5, 4) + ei->base_life * 12 - 96; e->duration_phase_3 = GB(r, 9, 7) + 120; - e->reliability_spd_dec = ei->decay_speed << 2; + RestoreRandomSeeds(saved_seeds); - CalcEngineReliability(e); + e->reliability_spd_dec = ei->decay_speed << 2; /* prevent certain engines from ever appearing. */ if (!HasBit(ei->climates, _settings_game.game_creation.landscape)) { @@ -684,9 +720,13 @@ void StartupEngines() { /* Aging of vehicles stops, so account for that when starting late */ const Date aging_date = std::min(_date, ConvertYMDToDate(_year_engine_aging_stops, 0, 1)); + uint32 seed = Random(); for (Engine *e : Engine::Iterate()) { - StartupOneEngine(e, aging_date); + StartupOneEngine(e, aging_date, seed); + } + for (Engine *e : Engine::Iterate()) { + CalcEngineReliability(e, false); } /* Update the bitmasks for the vehicle lists */ @@ -697,6 +737,9 @@ void StartupEngines() /* Invalidate any open purchase lists */ InvalidateWindowClassesData(WC_BUILD_VEHICLE); + + SetWindowClassesDirty(WC_BUILD_VEHICLE); + SetWindowClassesDirty(WC_REPLACE_VEHICLE); } /** @@ -745,6 +788,7 @@ static void DisableEngineForCompany(EngineID eid, CompanyID company) } if (company == _local_company) { + ClearLastVariant(e->index, e->type); AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type); } } @@ -753,8 +797,9 @@ static void DisableEngineForCompany(EngineID eid, CompanyID company) * Company \a company accepts engine \a eid for preview. * @param eid Engine being accepted (is under preview). * @param company Current company previewing the engine. + * @param recursion_depth Recursion depth to avoid infinite loop. */ -static void AcceptEnginePreview(EngineID eid, CompanyID company) +static void AcceptEnginePreview(EngineID eid, CompanyID company, int recursion_depth = 0) { Engine *e = Engine::Get(eid); @@ -769,6 +814,16 @@ static void AcceptEnginePreview(EngineID eid, CompanyID company) * we have to use the GUI-scope scheduling of InvalidateWindowData. */ InvalidateWindowData(WC_ENGINE_PREVIEW, eid); + + /* Don't search for variants to include if we are 10 levels deep already. */ + if (recursion_depth >= 10) return; + + /* Find variants to be included in preview. */ + for (Engine *ve : Engine::IterateType(e->type)) { + if (ve->index != eid && ve->info.variant_id == eid && (ve->info.extra_flags & ExtraEngineFlags::JoinPreview) != ExtraEngineFlags::None) { + AcceptEnginePreview(ve->index, company, recursion_depth + 1); + } + } } /** @@ -992,9 +1047,9 @@ static void NewVehicleAvailable(Engine *e) if (!IsVehicleTypeDisabled(e->type, true)) AI::BroadcastNewEvent(new ScriptEventEngineAvailable(index)); /* Only provide the "New Vehicle available" news paper entry, if engine can be built. */ - if (!IsVehicleTypeDisabled(e->type, false)) { + if (!IsVehicleTypeDisabled(e->type, false) && (e->info.extra_flags & ExtraEngineFlags::NoNews) == ExtraEngineFlags::None) { SetDParam(0, GetEngineCategoryName(index)); - SetDParam(1, index); + SetDParam(1, PackEngineNameDParam(index, EngineNameContext::PreviewNews)); AddNewsItem(STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE, NT_NEW_VEHICLES, NF_VEHICLE, NR_ENGINE, index); } @@ -1011,11 +1066,13 @@ static void NewVehicleAvailable(Engine *e) void EnginesMonthlyLoop() { if (_cur_year < _year_engine_aging_stops) { + bool refresh = false; for (Engine *e : Engine::Iterate()) { /* Age the vehicle */ if ((e->flags & ENGINE_AVAILABLE) && e->age != MAX_DAY) { e->age++; - CalcEngineReliability(e); + CalcEngineReliability(e, true); + refresh = true; } /* Do not introduce invalid engines */ @@ -1034,6 +1091,9 @@ void EnginesMonthlyLoop() /* Do not introduce new rail wagons */ if (IsWagon(e->index)) continue; + /* Engine has no preview */ + if ((e->info.extra_flags & ExtraEngineFlags::NoPreview) != ExtraEngineFlags::None) continue; + /* Show preview dialog to one of the companies. */ e->flags |= ENGINE_EXCLUSIVE_PREVIEW; e->preview_company = INVALID_COMPANY; @@ -1042,6 +1102,11 @@ void EnginesMonthlyLoop() } InvalidateWindowClassesData(WC_BUILD_VEHICLE); // rebuild the purchase list (esp. when sorted by reliability) + + if (refresh) { + SetWindowClassesDirty(WC_BUILD_VEHICLE); + SetWindowClassesDirty(WC_REPLACE_VEHICLE); + } } } diff --git a/src/engine_base.h b/src/engine_base.h index 7822111e77cba..14af402021f3b 100644 --- a/src/engine_base.h +++ b/src/engine_base.h @@ -21,6 +21,15 @@ struct WagonOverride { const SpriteGroup *group; }; +/** Flags used client-side in the purchase/autorenew engine list. */ +enum class EngineDisplayFlags : byte { + None = 0, ///< No flag set. + HasVariants = (1U << 0), ///< Set if engine has variants. + IsFolded = (1U << 1), ///< Set if display of variants should be folded (hidden). + Shaded = (1U << 2), ///< Set if engine should be masked. +}; +DECLARE_ENUM_AS_BIT_SET(EngineDisplayFlags) + typedef Pool EnginePool; extern EnginePool _engine_pool; @@ -45,6 +54,9 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { uint8 original_image_index; ///< Original vehicle image index, thus the image index of the overridden vehicle VehicleType type; ///< %Vehicle type, ie #VEH_ROAD, #VEH_TRAIN, etc. + EngineDisplayFlags display_flags; ///< NOSAVE client-side-only display flags for build engine list. + EngineID display_last_variant; ///< NOSAVE client-side-only last variant selected. + EngineInfo info; union { diff --git a/src/engine_func.h b/src/engine_func.h index 97bfd0894b43f..25ec83e404ba1 100644 --- a/src/engine_func.h +++ b/src/engine_func.h @@ -24,9 +24,9 @@ extern const uint8 _engine_offsets[4]; bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company); bool IsEngineRefittable(EngineID engine); -void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, CargoTypes *refits, CargoID cargo_type, uint cargo_capacity); void SetYearEngineAgingStops(); -void StartupOneEngine(Engine *e, Date aging_date); +void CalcEngineReliability(Engine *e, bool new_month); +void StartupOneEngine(Engine *e, Date aging_date, uint32 seed); uint GetTotalCapacityOfArticulatedParts(EngineID engine); diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index a14bc2652c0c5..11a1cd7f3e698 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.cpp @@ -24,6 +24,7 @@ #include "ship.h" #include "aircraft.h" #include "engine_cmd.h" +#include "zoom_func.h" #include "widgets/engine_widget.h" @@ -94,11 +95,11 @@ struct EnginePreviewWindow : Window { case VEH_SHIP: GetShipSpriteSize( engine, x, y, x_offs, y_offs, image_type); break; case VEH_AIRCRAFT: GetAircraftSpriteSize(engine, x, y, x_offs, y_offs, image_type); break; } - this->vehicle_space = std::max(40, y - y_offs); + this->vehicle_space = std::max(ScaleSpriteTrad(40), y - y_offs); size->width = std::max(size->width, x - x_offs); SetDParam(0, GetEngineCategoryName(engine)); - size->height = GetStringHeight(STR_ENGINE_PREVIEW_MESSAGE, size->width) + WD_PAR_VSEP_WIDE + FONT_HEIGHT_NORMAL + this->vehicle_space; + size->height = GetStringHeight(STR_ENGINE_PREVIEW_MESSAGE, size->width) + WidgetDimensions::scaled.vsep_wide + FONT_HEIGHT_NORMAL + this->vehicle_space; SetDParam(0, engine); size->height += GetStringHeight(GetEngineInfoString(engine), size->width); } @@ -109,17 +110,16 @@ struct EnginePreviewWindow : Window { EngineID engine = this->window_number; SetDParam(0, GetEngineCategoryName(engine)); - int y = r.top + GetStringHeight(STR_ENGINE_PREVIEW_MESSAGE, r.right - r.left + 1); - y = DrawStringMultiLine(r.left, r.right, r.top, y, STR_ENGINE_PREVIEW_MESSAGE, TC_FROMSTRING, SA_CENTER) + WD_PAR_VSEP_WIDE; + int y = DrawStringMultiLine(r, STR_ENGINE_PREVIEW_MESSAGE, TC_FROMSTRING, SA_HOR_CENTER | SA_TOP) + WidgetDimensions::scaled.vsep_wide; - SetDParam(0, engine); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_ENGINE_NAME, TC_BLACK, SA_HOR_CENTER); + SetDParam(0, PackEngineNameDParam(engine, EngineNameContext::PreviewNews)); + DrawString(r.left, r.right, y, STR_ENGINE_NAME, TC_BLACK, SA_HOR_CENTER); y += FONT_HEIGHT_NORMAL; - DrawVehicleEngine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, this->width >> 1, y + this->vehicle_space / 2, engine, GetEnginePalette(engine, _local_company), EIT_PREVIEW); + DrawVehicleEngine(r.left, r.right, this->width >> 1, y + this->vehicle_space / 2, engine, GetEnginePalette(engine, _local_company), EIT_PREVIEW); y += this->vehicle_space; - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, r.bottom, GetEngineInfoString(engine), TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(r.left, r.right, y, r.bottom, GetEngineInfoString(engine), TC_FROMSTRING, SA_CENTER); } void OnClick(Point pt, int widget, int click_count) override @@ -337,7 +337,7 @@ void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare) * @param begin start of sorting * @param num_items count of items to be sorted */ -void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items) +void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, size_t begin, size_t num_items) { if (num_items < 2) return; assert(begin < el->size()); diff --git a/src/engine_gui.h b/src/engine_gui.h index f987f57d35b7a..87af6f3562b49 100644 --- a/src/engine_gui.h +++ b/src/engine_gui.h @@ -14,12 +14,25 @@ #include "sortlist_type.h" #include "gfx_type.h" #include "vehicle_type.h" +#include "engine_base.h" -typedef GUIList GUIEngineList; +struct GUIEngineListItem { + EngineID engine_id; ///< Engine to display in build purchase list + EngineID variant_id; ///< Variant group of the engine. + EngineDisplayFlags flags; ///< Flags for toggling/drawing (un)folded status and controlling indentation. + int8 indent; ///< Display indentation level. -typedef bool EngList_SortTypeFunction(const EngineID&, const EngineID&); ///< argument type for #EngList_Sort. + GUIEngineListItem(EngineID engine_id, EngineID variant_id, EngineDisplayFlags flags, int indent) : engine_id(engine_id), variant_id(variant_id), flags(flags), indent(indent) {} + + /* Used when searching list only by engine_id. */ + bool operator == (const EngineID &other) const { return this->engine_id == other; } +}; + +typedef GUIList GUIEngineList; + +typedef bool EngList_SortTypeFunction(const GUIEngineListItem&, const GUIEngineListItem&); ///< argument type for #EngList_Sort. void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare); -void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items); +void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, size_t begin, size_t num_items); StringID GetEngineCategoryName(EngineID engine); StringID GetEngineInfoString(EngineID engine); diff --git a/src/engine_type.h b/src/engine_type.h index f0b6ea5450a21..789ddbbca0a88 100644 --- a/src/engine_type.h +++ b/src/engine_type.h @@ -43,7 +43,8 @@ struct RailVehicleInfo { byte image_index; RailVehicleTypes railveh_type; byte cost_factor; ///< Purchase cost factor; For multiheaded engines the sum of both engine prices. - RailType railtype; + RailType railtype; ///< Railtype, mangled if elrail is disabled. + RailType intended_railtype; ///< Intended railtype, regardless of elrail being enabled or disabled. uint16 max_speed; ///< Maximum speed (1 unit = 1/1.6 mph = 1 km-ish/h) uint16 power; ///< Power of engine (hp); For multiheaded engines the sum of both engine powers. uint16 weight; ///< Weight of vehicle (tons); For multiheaded engines the weight of each single engine. @@ -126,6 +127,15 @@ struct RoadVehicleInfo { RoadType roadtype; ///< Road type }; +enum class ExtraEngineFlags : uint32 { + None = 0, + NoNews = (1U << 0), ///< No 'new vehicle' news will be generated. + NoPreview = (1U << 1), ///< No exclusive preview will be offered. + JoinPreview = (1U << 2), ///< Engine will join exclusive preview with variant parent. + SyncReliability = (1U << 3), ///< Engine reliability will be synced with variant parent. +}; +DECLARE_ENUM_AS_BIT_SET(ExtraEngineFlags); + /** * Information about a vehicle * @see table/engines.h @@ -140,11 +150,13 @@ struct EngineInfo { CargoID cargo_type; CargoTypes refit_mask; byte refit_cost; - byte misc_flags; ///< Miscellaneous flags. @see EngineMiscFlags - byte callback_mask; ///< Bitmask of vehicle callbacks that have to be called - int8 retire_early; ///< Number of years early to retire vehicle - StringID string_id; ///< Default name of engine + byte misc_flags; ///< Miscellaneous flags. @see EngineMiscFlags + uint16 callback_mask; ///< Bitmask of vehicle callbacks that have to be called + int8 retire_early; ///< Number of years early to retire vehicle + StringID string_id; ///< Default name of engine uint16 cargo_age_period; ///< Number of ticks before carried cargo is aged. + EngineID variant_id; ///< Engine variant ID. If set, will be treated specially in purchase lists. + ExtraEngineFlags extra_flags; }; /** @@ -155,7 +167,7 @@ enum EngineMiscFlags { EF_ROAD_TRAM = 0, ///< Road vehicle is a tram/light rail vehicle EF_USES_2CC = 1, ///< Vehicle uses two company colours EF_RAIL_IS_MU = 2, ///< Rail vehicle is a multiple-unit (DMU/EMU) - EF_RAIL_FLIPS = 3, ///< Rail vehicle can be flipped in the depot + EF_RAIL_FLIPS = 3, ///< Rail vehicle has old depot-flip handling EF_AUTO_REFIT = 4, ///< Automatic refitting is allowed EF_NO_DEFAULT_CARGO_MULTIPLIER = 5, ///< Use the new capacity algorithm. The default cargotype of the vehicle does not affect capacity multipliers. CB 15 is also called in purchase list. EF_NO_BREAKDOWN_SMOKE = 6, ///< Do not show black smoke during a breakdown. @@ -170,6 +182,22 @@ enum EngineFlags { ENGINE_EXCLUSIVE_PREVIEW = 2, ///< This vehicle is in the exclusive preview stage, either being used or being offered to a company. }; +/** + * Contexts an engine name can be shown in. + */ +enum EngineNameContext : uint8 { + Generic = 0x00, ///< No specific context available. + VehicleDetails = 0x11, ///< Name is shown in the vehicle details GUI. + PurchaseList = 0x20, ///< Name is shown in the purchase list (including autoreplace window). + PreviewNews = 0x21, ///< Name is shown in exclusive preview or newspaper. +}; + +/** Combine an engine ID and a name context to an engine name dparam. */ +inline uint64 PackEngineNameDParam(EngineID engine_id, EngineNameContext context, uint32 extra_data = 0) +{ + return engine_id | (static_cast(context) << 32) | (static_cast(extra_data) << 40); +} + static const uint MAX_LENGTH_ENGINE_NAME_CHARS = 32; ///< The maximum length of an engine name in characters including '\0' static const EngineID INVALID_ENGINE = 0xFFFF; ///< Constant denoting an invalid engine. diff --git a/src/error.h b/src/error.h index 06440c127c7a3..51b164c4329c4 100644 --- a/src/error.h +++ b/src/error.h @@ -10,8 +10,10 @@ #ifndef ERROR_H #define ERROR_H +#include #include "strings_type.h" #include "company_type.h" +#include "command_type.h" #include "core/geometry_type.hpp" #include "guitimer_func.h" @@ -36,13 +38,14 @@ class ErrorMessageData { uint32 textref_stack[16]; ///< Values to put on the #TextRefStack for the error message. StringID summary_msg; ///< General error message showed in first line. Must be valid. StringID detailed_msg; ///< Detailed error message showed in second line. Can be #INVALID_STRING_ID. + StringID extra_msg; ///< Extra error message shown in third line. Can be #INVALID_STRING_ID. Point position; ///< Position of the error message window. CompanyID face; ///< Company belonging to the face being shown. #INVALID_COMPANY if no face present. public: ErrorMessageData(const ErrorMessageData &data); ~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); + 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; @@ -57,9 +60,14 @@ class ErrorMessageData { void CopyOutDParams(); }; +/** Define a queue with errors. */ +typedef std::list ErrorList; + +void ScheduleErrorMessage(ErrorList &datas); void ScheduleErrorMessage(const ErrorMessageData &data); -void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x = 0, int y = 0, const GRFFile *textref_stack_grffile = nullptr, uint textref_stack_size = 0, const uint32 *textref_stack = nullptr); +void ShowErrorMessage(StringID summary_msg, int x, int y, CommandCost cc); +void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, 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); bool HideActiveErrorMessage(); void ClearErrorMessages(); diff --git a/src/error_gui.cpp b/src/error_gui.cpp index d23589683a564..6d05d24395303 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.cpp @@ -35,7 +35,7 @@ static const NWidgetPart _nested_errmsg_widgets[] = { NWidget(WWT_CAPTION, COLOUR_RED, WID_EM_CAPTION), SetDataTip(STR_ERROR_MESSAGE_CAPTION, STR_NULL), EndContainer(), NWidget(WWT_PANEL, COLOUR_RED), - NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetPadding(0, 2, 0, 2), SetMinimalSize(236, 32), + NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetPadding(WidgetDimensions::unscaled.modalpopup), SetFill(1, 0), SetMinimalSize(236, 0), EndContainer(), }; @@ -52,9 +52,9 @@ static const NWidgetPart _nested_errmsg_face_widgets[] = { NWidget(WWT_CAPTION, COLOUR_RED, WID_EM_CAPTION), SetDataTip(STR_ERROR_MESSAGE_CAPTION_OTHER_COMPANY, STR_NULL), EndContainer(), NWidget(WWT_PANEL, COLOUR_RED), - NWidget(NWID_HORIZONTAL), SetPIP(2, 1, 2), - NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_FACE), SetMinimalSize(92, 119), SetFill(0, 1), SetPadding(2, 0, 1, 0), - NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetFill(0, 1), SetMinimalSize(238, 123), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_FACE), SetPadding(2, 0, 2, 2), SetFill(0, 1), SetMinimalSize(92, 119), + NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetPadding(WidgetDimensions::unscaled.modalpopup), SetFill(1, 1), SetMinimalSize(236, 0), EndContainer(), EndContainer(), }; @@ -72,7 +72,7 @@ static WindowDesc _errmsg_face_desc( */ ErrorMessageData::ErrorMessageData(const ErrorMessageData &data) : display_timer(data.display_timer), textref_stack_grffile(data.textref_stack_grffile), textref_stack_size(data.textref_stack_size), - summary_msg(data.summary_msg), detailed_msg(data.detailed_msg), position(data.position), face(data.face) + summary_msg(data.summary_msg), detailed_msg(data.detailed_msg), extra_msg(data.extra_msg), position(data.position), face(data.face) { memcpy(this->textref_stack, data.textref_stack, sizeof(this->textref_stack)); memcpy(this->decode_params, data.decode_params, sizeof(this->decode_params)); @@ -101,12 +101,14 @@ ErrorMessageData::~ErrorMessageData() * @param textref_stack_grffile NewGRF that provides the #TextRefStack for the error message. * @param textref_stack_size Number of uint32 values to put on the #TextRefStack for the error message; 0 if the #TextRefStack shall not be used. * @param textref_stack Values to put on the #TextRefStack. + * @param extra_msg Extra error message showed in third line. Can be INVALID_STRING_ID. */ -ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack) : +ErrorMessageData::ErrorMessageData(StringID summary_msg, StringID detailed_msg, uint duration, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack, StringID extra_msg) : textref_stack_grffile(textref_stack_grffile), textref_stack_size(textref_stack_size), summary_msg(summary_msg), detailed_msg(detailed_msg), + extra_msg(extra_msg), face(INVALID_COMPANY) { this->position.x = x; @@ -174,10 +176,8 @@ void ErrorMessageData::SetDParamStr(uint n, const std::string &str) this->SetDParamStr(n, str.c_str()); } -/** Define a queue with errors. */ -typedef std::list ErrorList; /** The actual queue with errors. */ -ErrorList _error_list; +static ErrorList _error_list; /** Whether the window system is initialized or not. */ bool _window_system_initialized = false; @@ -186,6 +186,7 @@ struct ErrmsgWindow : public Window, ErrorMessageData { private: uint height_summary; ///< Height of the #summary_msg string in pixels in the #WID_EM_MESSAGE widget. uint height_detailed; ///< Height of the #detailed_msg string in pixels in the #WID_EM_MESSAGE widget. + uint height_extra; ///< Height of the #extra_msg string in pixels in the #WID_EM_MESSAGE widget. public: ErrmsgWindow(const ErrorMessageData &data) : Window(data.HasFace() ? &_errmsg_face_desc : &_errmsg_desc), ErrorMessageData(data) @@ -200,14 +201,15 @@ struct ErrmsgWindow : public Window, ErrorMessageData { CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_grffile, this->textref_stack_size, this->textref_stack); - int text_width = std::max(0, (int)size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT); - this->height_summary = GetStringHeight(this->summary_msg, text_width); - this->height_detailed = (this->detailed_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(this->detailed_msg, text_width); + this->height_summary = GetStringHeight(this->summary_msg, size->width); + this->height_detailed = (this->detailed_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(this->detailed_msg, size->width); + this->height_extra = (this->extra_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(this->extra_msg, size->width); if (this->textref_stack_size > 0) StopTextRefStackUsage(); - uint panel_height = WD_FRAMERECT_TOP + this->height_summary + WD_FRAMERECT_BOTTOM; - if (this->detailed_msg != INVALID_STRING_ID) panel_height += this->height_detailed + WD_PAR_VSEP_WIDE; + uint panel_height = this->height_summary; + if (this->detailed_msg != INVALID_STRING_ID) panel_height += this->height_detailed + WidgetDimensions::scaled.vsep_wide; + if (this->extra_msg != INVALID_STRING_ID) panel_height += this->height_extra + WidgetDimensions::scaled.vsep_wide; size->height = std::max(size->height, panel_height); break; @@ -236,7 +238,7 @@ struct ErrmsgWindow : public Window, ErrorMessageData { int scr_bot = GetMainViewBottom() - 20; Point pt = RemapCoords(this->position.x, this->position.y, GetSlopePixelZOutsideMap(this->position.x, this->position.y)); - const Viewport *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; + const Viewport *vp = GetMainWindow()->viewport; if (this->face == INVALID_COMPANY) { /* move x pos to opposite corner */ pt.x = UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left; @@ -246,8 +248,8 @@ struct ErrmsgWindow : public Window, ErrorMessageData { pt.y = UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top; pt.y = (pt.y < (_screen.height >> 1)) ? scr_bot - sm_height : scr_top; } else { - pt.x = Clamp(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (sm_width / 2), 0, _screen.width - sm_width); - pt.y = Clamp(UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top - (sm_height / 2), scr_top, scr_bot - sm_height); + pt.x = std::min(std::max(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (sm_width / 2), 0), _screen.width - sm_width); + pt.y = std::min(std::max(UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top - (sm_height / 2), scr_top), scr_bot - sm_height); } return pt; } @@ -282,19 +284,25 @@ struct ErrmsgWindow : public Window, ErrorMessageData { if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_grffile, this->textref_stack_size, this->textref_stack); if (this->detailed_msg == INVALID_STRING_ID) { - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, - this->summary_msg, TC_FROMSTRING, SA_CENTER); - } else { - int extra = (r.bottom - r.top + 1 - this->height_summary - this->height_detailed - WD_PAR_VSEP_WIDE) / 2; + DrawStringMultiLine(r, this->summary_msg, TC_FROMSTRING, SA_CENTER); + } else if (this->extra_msg == INVALID_STRING_ID) { + /* Extra space when message is shorter than company face window */ + int extra = (r.Height() - this->height_summary - this->height_detailed - WidgetDimensions::scaled.vsep_wide) / 2; /* Note: NewGRF supplied error message often do not start with a colour code, so default to white. */ - int top = r.top + WD_FRAMERECT_TOP; - int bottom = top + this->height_summary + extra; - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, top, bottom, this->summary_msg, TC_WHITE, SA_CENTER); + DrawStringMultiLine(r.WithHeight(this->height_summary + extra, false), this->summary_msg, TC_WHITE, SA_CENTER); + DrawStringMultiLine(r.WithHeight(this->height_detailed + extra, true), this->detailed_msg, TC_WHITE, SA_CENTER); + } else { + /* Extra space when message is shorter than company face window */ + int extra = (r.Height() - this->height_summary - this->height_detailed - this->height_extra - (WidgetDimensions::scaled.vsep_wide * 2)) / 3; - bottom = r.bottom - WD_FRAMERECT_BOTTOM; - top = bottom - this->height_detailed - extra; - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, top, bottom, this->detailed_msg, TC_WHITE, SA_CENTER); + /* Note: NewGRF supplied error message often do not start with a colour code, so default to white. */ + Rect top_section = r.WithHeight(this->height_summary + extra, false); + Rect bottom_section = r.WithHeight(this->height_extra + extra, true); + Rect middle_section = { top_section.left, top_section.bottom, top_section.right, bottom_section.top }; + DrawStringMultiLine(top_section, this->summary_msg, TC_WHITE, SA_CENTER); + DrawStringMultiLine(middle_section, this->detailed_msg, TC_WHITE, SA_CENTER); + DrawStringMultiLine(bottom_section, this->extra_msg, TC_WHITE, SA_CENTER); } if (this->textref_stack_size > 0) StopTextRefStackUsage(); @@ -369,6 +377,19 @@ void UnshowCriticalError() } } +/** + * Display an error message in a window. + * Note: CommandCost errors are always severity level WL_INFO. + * @param summary_msg General error message showed in first line. Must be valid. + * @param x World X position (TileVirtX) of the error location. Set both x and y to 0 to just center the message when there is no related error tile. + * @param y World Y position (TileVirtY) of the error location. Set both x and y to 0 to just center the message when there is no related error tile. + * @param cc CommandCost containing the optional detailed and extra error messages shown in the second and third lines (can be INVALID_STRING_ID) and TextRefStack info. + */ +void ShowErrorMessage(StringID summary_msg, int x, int y, CommandCost cc) +{ + ShowErrorMessage(summary_msg, cc.GetErrorMessage(), WL_INFO, x, y, cc.GetTextRefStackGRF(), cc.GetTextRefStackSize(), cc.GetTextRefStack(), cc.GetExtraErrorMessage()); +} + /** * Display an error message in a window. * @param summary_msg General error message showed in first line. Must be valid. @@ -379,8 +400,9 @@ void UnshowCriticalError() * @param textref_stack_grffile NewGRF providing the #TextRefStack for the error message. * @param textref_stack_size Number of uint32 values to put on the #TextRefStack for the error message; 0 if the #TextRefStack shall not be used. * @param textref_stack Values to put on the #TextRefStack. + * @param extra_msg Extra error message shown in third line. Can be INVALID_STRING_ID. */ -void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack) +void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x, int y, const GRFFile *textref_stack_grffile, uint textref_stack_size, const uint32 *textref_stack, StringID extra_msg) { assert(textref_stack_size == 0 || (textref_stack_grffile != nullptr && textref_stack != nullptr)); if (summary_msg == STR_NULL) summary_msg = STR_EMPTY; @@ -396,6 +418,10 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel b += seprintf(b, lastof(buf), " "); GetString(b, detailed_msg, lastof(buf)); } + if (extra_msg != INVALID_STRING_ID) { + b += seprintf(b, lastof(buf), " "); + GetString(b, extra_msg, lastof(buf)); + } if (textref_stack_size > 0) StopTextRefStackUsage(); @@ -407,7 +433,7 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel if (_game_mode == GM_BOOTSTRAP) return; if (_settings_client.gui.errmsg_duration == 0 && !no_timeout) return; - ErrorMessageData data(summary_msg, detailed_msg, no_timeout ? 0 : _settings_client.gui.errmsg_duration, x, y, textref_stack_grffile, textref_stack_size, textref_stack); + ErrorMessageData data(summary_msg, detailed_msg, no_timeout ? 0 : _settings_client.gui.errmsg_duration, x, y, textref_stack_grffile, textref_stack_size, textref_stack, extra_msg); data.CopyOutDParams(); ErrmsgWindow *w = (ErrmsgWindow*)FindWindowById(WC_ERRMSG, 0); diff --git a/src/fileio.cpp b/src/fileio.cpp index 23562cf6a59d4..ee12b25639d7d 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -69,6 +69,8 @@ TarFileList _tar_filelist[NUM_SUBDIRS]; typedef std::map TarLinkList; static TarLinkList _tar_linklist[NUM_SUBDIRS]; ///< List of directory links +extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb); + /** * Checks whether the given search path is a valid search path * @param sp the search path to check @@ -418,7 +420,7 @@ uint TarScanner::DoScan(Subdirectory sd) /* static */ uint TarScanner::DoScan(TarScanner::Mode mode) { - Debug(misc, 1, "Scanning for tars"); + Debug(misc, 2, "Scanning for tars"); TarScanner fs; uint num = 0; if (mode & TarScanner::BASESET) { @@ -439,7 +441,7 @@ uint TarScanner::DoScan(Subdirectory sd) num += fs.DoScan(SCENARIO_DIR); num += fs.DoScan(HEIGHTMAP_DIR); } - Debug(misc, 1, "Scan complete, found {} files", num); + Debug(misc, 2, "Scan complete, found {} files", num); return num; } @@ -571,7 +573,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co /* Only allow relative links */ if (link[0] == PATHSEPCHAR) { - Debug(misc, 1, "Ignoring absolute link in tar: {} -> {}", name, link); + Debug(misc, 5, "Ignoring absolute link in tar: {} -> {}", name, link); break; } @@ -597,7 +599,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co } else if (strcmp(pos, "..") == 0) { /* level up */ if (dest[0] == '\0') { - Debug(misc, 1, "Ignoring link pointing outside of data directory: {} -> {}", name, link); + Debug(misc, 5, "Ignoring link pointing outside of data directory: {} -> {}", name, link); break; } @@ -652,7 +654,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co pos += skip; } - Debug(misc, 1, "Found tar '{}' with {} new files", filename, num); + Debug(misc, 4, "Found tar '{}' with {} new files", filename, num); fclose(f); /* Resolve file links and store directory links. @@ -690,7 +692,7 @@ bool ExtractTar(const std::string &tar_filename, Subdirectory subdir) /* The file doesn't have a sub directory! */ if (dirname.empty()) { - Debug(misc, 1, "Extracting {} failed; archive rejected, the contents must be in a sub directory", tar_filename); + Debug(misc, 3, "Extracting {} failed; archive rejected, the contents must be in a sub directory", tar_filename); return false; } @@ -987,7 +989,7 @@ void DeterminePaths(const char *exe, bool only_local_path) for (Searchpath sp : _valid_searchpaths) { if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue; - Debug(misc, 4, "{} added as search path", _searchpaths[sp]); + Debug(misc, 3, "{} added as search path", _searchpaths[sp]); } std::string config_dir; @@ -1020,7 +1022,7 @@ void DeterminePaths(const char *exe, bool only_local_path) _config_file = config_dir + "openttd.cfg"; } - Debug(misc, 3, "{} found as config directory", config_dir); + Debug(misc, 1, "{} found as config directory", config_dir); _highscore_file = config_dir + "hs.dat"; extern std::string _hotkeys_file; @@ -1056,7 +1058,7 @@ void DeterminePaths(const char *exe, bool only_local_path) FioCreateDirectory(_personal_dir); #endif - Debug(misc, 3, "{} found as personal directory", _personal_dir); + Debug(misc, 1, "{} found as personal directory", _personal_dir); static const Subdirectory default_subdirs[] = { SAVE_DIR, AUTOSAVE_DIR, SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR, GAME_LIBRARY_DIR, SCREENSHOT_DIR @@ -1068,7 +1070,7 @@ void DeterminePaths(const char *exe, bool only_local_path) /* If we have network we make a directory for the autodownloading of content */ _searchpaths[SP_AUTODOWNLOAD_DIR] = _personal_dir + "content_download" PATHSEP; - Debug(misc, 4, "{} added as search path", _searchpaths[SP_AUTODOWNLOAD_DIR]); + Debug(misc, 3, "{} added as search path", _searchpaths[SP_AUTODOWNLOAD_DIR]); FioCreateDirectory(_searchpaths[SP_AUTODOWNLOAD_DIR]); FillValidSearchPaths(only_local_path); @@ -1154,8 +1156,6 @@ static bool MatchesExtension(const char *extension, const char *filename) */ static uint ScanPath(FileScanner *fs, const char *extension, const char *path, size_t basepath_length, bool recursive) { - extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb); - uint num = 0; struct stat sb; struct dirent *dirent; diff --git a/src/fios.cpp b/src/fios.cpp index 0491c1e51b686..b07db3c8b1a1d 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -295,7 +295,7 @@ bool FiosFileScanner::AddFile(const std::string &filename, size_t basepath_lengt std::string ext = filename.substr(sep); char fios_title[64]; - fios_title[0] = '\0'; // reset the title; + fios_title[0] = '\0'; // reset the title FiosType type = this->callback_proc(this->fop, filename, ext.c_str(), fios_title, lastof(fios_title)); if (type == FIOS_TYPE_INVALID) return false; diff --git a/src/fios.h b/src/fios.h index c0e51629756fd..fc6f4bcef92bc 100644 --- a/src/fios.h +++ b/src/fios.h @@ -125,6 +125,9 @@ std::string FiosMakeSavegameName(const char *name); FiosType FiosGetSavegameListCallback(SaveLoadOperation fop, const std::string &file, const char *ext, char *title, const char *last); +void ScanScenarios(); +const char *FindScenario(const ContentInfo *ci, bool md5sum); + /** * A savegame name automatically numbered. */ diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 3014bc00ecf60..4d963e5ff3a6b 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -80,13 +80,15 @@ static const NWidgetPart _nested_load_dialog_widgets[] = { NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), /* Left side : filter box and available files */ - NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1), + NWidget(NWID_VERTICAL), /* Filter box with label */ - NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, 0, WD_FRAMERECT_BOTTOM, 0), - SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, 0), - NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL), - NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), - SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1), + NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect.top, 0, WidgetDimensions::unscaled.framerect.bottom, 0), + SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0), + NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), + SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + EndContainer(), EndContainer(), /* Sort buttons */ NWidget(NWID_HORIZONTAL), @@ -97,22 +99,24 @@ static const NWidgetPart _nested_load_dialog_widgets[] = { NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON), EndContainer(), /* Files */ - NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_FILE_BACKGROUND), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 1, 2, 2), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_FILE_BACKGROUND), + NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 2, 2, 2), SetDataTip(0x0, STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR), EndContainer(), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SL_SCROLLBAR), - EndContainer(), - NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SL_CONTENT_DOWNLOAD_SEL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_CONTENT_DOWNLOAD), SetResize(1, 0), - SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SL_SCROLLBAR), + EndContainer(), + /* Online Content button */ + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SL_CONTENT_DOWNLOAD_SEL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_CONTENT_DOWNLOAD), SetResize(1, 0), + SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), EndContainer(), EndContainer(), /* Right side : game details */ - NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1), + NWidget(NWID_VERTICAL), + NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1), + EndContainer(), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_MISSING_NEWGRFS), SetDataTip(STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_BUTTON, STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_TOOLTIP), SetFill(1, 0), SetResize(1, 0), NWidget(NWID_HORIZONTAL), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), @@ -135,37 +139,38 @@ static const NWidgetPart _nested_load_heightmap_dialog_widgets[] = { /* Current directory and free space */ NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(), + /* Filter box with label */ NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1), - /* Filter box with label */ - NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, 0, WD_FRAMERECT_BOTTOM, 0), - SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, 0), + NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect.top, 0, WidgetDimensions::unscaled.framerect.bottom, 0), + SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0), NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL), NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), EndContainer(), - /* Sort Buttons */ - NWidget(NWID_HORIZONTAL), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetDataTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYDATE), SetDataTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0), - EndContainer(), - NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON), + EndContainer(), + /* Sort Buttons */ + NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYNAME), SetDataTip(STR_SORT_BY_CAPTION_NAME, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_SORT_BYDATE), SetDataTip(STR_SORT_BY_CAPTION_DATE, STR_TOOLTIP_SORT_ORDER), SetFill(1, 0), SetResize(1, 0), EndContainer(), - /* Files */ + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON), + EndContainer(), + /* Files */ + NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_FILE_BACKGROUND), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 1, 2, 2), - SetDataTip(0x0, STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR), EndContainer(), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SL_SCROLLBAR), - EndContainer(), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_CONTENT_DOWNLOAD), SetResize(1, 0), SetFill(1, 0), - SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_LOAD_BUTTON), SetResize(1, 0), SetFill(1, 0), - SetDataTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_HEIGHTMAP_TOOLTIP), - NWidget(WWT_RESIZEBOX, COLOUR_GREY), - EndContainer(), + NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetFill(1, 1), SetPadding(2, 2, 2, 2), + SetDataTip(0x0, STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR), EndContainer(), EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SL_SCROLLBAR), + EndContainer(), + /* Online Content and Load button */ + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_CONTENT_DOWNLOAD), SetResize(1, 0), SetFill(1, 0), + SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SL_LOAD_BUTTON), SetResize(1, 0), SetFill(1, 0), + SetDataTip(STR_SAVELOAD_LOAD_BUTTON, STR_SAVELOAD_LOAD_HEIGHTMAP_TOOLTIP), + NWidget(WWT_RESIZEBOX, COLOUR_GREY), EndContainer(), }; @@ -180,13 +185,15 @@ static const NWidgetPart _nested_save_dialog_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_BACKGROUND), SetFill(1, 0), SetResize(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), /* Left side : filter box and available files */ - NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1), + NWidget(NWID_VERTICAL), /* Filter box with label */ - NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, 0, WD_FRAMERECT_BOTTOM, 0), - SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, 0), - NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL), - NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), - SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1), + NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect.top, 0, WidgetDimensions::unscaled.framerect.bottom, 0), + SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0), + NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), + SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + EndContainer(), EndContainer(), /* Sort buttons */ NWidget(NWID_HORIZONTAL), @@ -197,13 +204,15 @@ static const NWidgetPart _nested_save_dialog_widgets[] = { NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SL_HOME_BUTTON), SetMinimalSize(12, 12), SetDataTip(SPR_HOUSE_ICON, STR_SAVELOAD_HOME_BUTTON), EndContainer(), /* Files */ - NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_FILE_BACKGROUND), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetPadding(2, 1, 0, 2), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_FILE_BACKGROUND), + NWidget(WWT_INSET, COLOUR_GREY, WID_SL_DRIVES_DIRECTORIES_LIST), SetPadding(2, 2, 2, 2), SetDataTip(0x0, STR_SAVELOAD_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SL_SCROLLBAR), EndContainer(), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SL_SCROLLBAR), EndContainer(), - NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_SAVE_OSK_TITLE), SetPadding(3, 2, 2, 2), SetFill(1, 0), SetResize(1, 0), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SL_SCROLLBAR), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_SAVE_OSK_TITLE), SetPadding(2, 2, 2, 2), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_SAVELOAD_OSKTITLE, STR_SAVELOAD_EDITBOX_TOOLTIP), EndContainer(), /* Save/delete buttons */ @@ -214,10 +223,10 @@ static const NWidgetPart _nested_save_dialog_widgets[] = { EndContainer(), /* Right side : game details */ - NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1), + NWidget(NWID_VERTICAL), + NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(NWID_SPACER), SetResize(1, 0), SetFill(1, 1), + NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(), NWidget(WWT_RESIZEBOX, COLOUR_GREY), EndContainer(), EndContainer(), @@ -428,18 +437,21 @@ struct SaveLoadWindow : public Window { _fios_path_changed = false; } + Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); + if (str != STR_ERROR_UNABLE_TO_READ_DRIVE) SetDParam(0, tot); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP, str); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, path, TC_BLACK); + DrawString(ir.left, ir.right, ir.top + FONT_HEIGHT_NORMAL, str); + DrawString(ir.left, ir.right, ir.top, path, TC_BLACK); break; } case WID_SL_DRIVES_DIRECTORIES_LIST: { - GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, PC_BLACK); + const Rect br = r.Shrink(WidgetDimensions::scaled.bevel); + GfxFillRect(br, PC_BLACK); - uint y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WidgetDimensions::scaled.inset).WithHeight(this->resize.step_height); uint scroll_pos = this->vscroll->GetPosition(); - for (uint row = 0; row < this->fios_items.size(); row++) { + for (uint row = 0; row < this->fios_items.size() && tr.top < br.bottom; row++) { if (!this->fios_items_shown[row]) { /* The current item is filtered out : we do not show it */ scroll_pos++; @@ -449,108 +461,117 @@ struct SaveLoadWindow : public Window { const FiosItem *item = &this->fios_items[row]; if (item == this->selected) { - GfxFillRect(r.left + 1, y, r.right, y + this->resize.step_height, PC_DARK_BLUE); + GfxFillRect(br.left, tr.top, br.right, tr.bottom, PC_DARK_BLUE); } else if (item == this->highlighted) { - GfxFillRect(r.left + 1, y, r.right, y + this->resize.step_height, PC_VERY_DARK_BLUE); + GfxFillRect(br.left, tr.top, br.right, tr.bottom, PC_VERY_DARK_BLUE); } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, item->title, _fios_colours[GetDetailedFileType(item->type)]); - y += this->resize.step_height; - if (y >= this->vscroll->GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break; + DrawString(tr, item->title, _fios_colours[GetDetailedFileType(item->type)]); + tr = tr.Translate(0, this->resize.step_height); } break; } - case WID_SL_DETAILS: { - GfxFillRect(r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, - r.right - WD_FRAMERECT_RIGHT, r.top + FONT_HEIGHT_NORMAL * 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM, PC_GREY); - DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL / 2 + WD_FRAMERECT_TOP, STR_SAVELOAD_DETAIL_CAPTION, TC_FROMSTRING, SA_HOR_CENTER); - - if (this->selected == nullptr) break; - - uint y = r.top + FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; - uint y_max = r.bottom - FONT_HEIGHT_NORMAL - WD_FRAMERECT_BOTTOM; - - if (y > y_max) break; - if (!_load_check_data.checkable) { - /* Old savegame, no information available */ - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_NOT_AVAILABLE); - y += FONT_HEIGHT_NORMAL; - } else if (_load_check_data.error != INVALID_STRING_ID) { - /* Incompatible / broken savegame */ - SetDParamStr(0, _load_check_data.error_data); - y = DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, - y, r.bottom - WD_FRAMERECT_BOTTOM, _load_check_data.error, TC_RED); - } else { - /* Mapsize */ - SetDParam(0, _load_check_data.map_size_x); - SetDParam(1, _load_check_data.map_size_y); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_MAP_SIZE); - y += FONT_HEIGHT_NORMAL; - if (y > y_max) break; - - /* Climate */ - byte landscape = _load_check_data.settings.game_creation.landscape; - if (landscape < NUM_LANDSCAPE) { - SetDParam(0, STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE + landscape); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_LANDSCAPE); - y += FONT_HEIGHT_NORMAL; - } + case WID_SL_DETAILS: + this->DrawDetails(r); + break; + } + } - y += WD_PAR_VSEP_NORMAL; - if (y > y_max) break; + void DrawDetails(const Rect &r) const + { + /* Header panel */ + int HEADER_HEIGHT = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.frametext.Vertical(); + + Rect hr = r.WithHeight(HEADER_HEIGHT).Shrink(WidgetDimensions::scaled.frametext); + Rect tr = r.Shrink(WidgetDimensions::scaled.frametext); + tr.top += HEADER_HEIGHT; + + /* Create the nice grayish rectangle at the details top */ + GfxFillRect(r.WithHeight(HEADER_HEIGHT).Shrink(WidgetDimensions::scaled.bevel.left, WidgetDimensions::scaled.bevel.top, WidgetDimensions::scaled.bevel.right, 0), PC_GREY); + DrawString(hr.left, hr.right, hr.top, STR_SAVELOAD_DETAIL_CAPTION, TC_FROMSTRING, SA_HOR_CENTER); + + if (this->selected == nullptr) return; + + /* Details panel */ + tr.bottom -= FONT_HEIGHT_NORMAL - 1; + if (tr.top > tr.bottom) return; + + if (!_load_check_data.checkable) { + /* Old savegame, no information available */ + DrawString(tr, STR_SAVELOAD_DETAIL_NOT_AVAILABLE); + tr.top += FONT_HEIGHT_NORMAL; + } else if (_load_check_data.error != INVALID_STRING_ID) { + /* Incompatible / broken savegame */ + SetDParamStr(0, _load_check_data.error_data); + tr.top = DrawStringMultiLine(tr, _load_check_data.error, TC_RED); + } else { + /* Mapsize */ + SetDParam(0, _load_check_data.map_size_x); + SetDParam(1, _load_check_data.map_size_y); + DrawString(tr, STR_NETWORK_SERVER_LIST_MAP_SIZE); + tr.top += FONT_HEIGHT_NORMAL; + if (tr.top > tr.bottom) return; + + /* Climate */ + byte landscape = _load_check_data.settings.game_creation.landscape; + if (landscape < NUM_LANDSCAPE) { + SetDParam(0, STR_CLIMATE_TEMPERATE_LANDSCAPE + landscape); + DrawString(tr, STR_NETWORK_SERVER_LIST_LANDSCAPE); + tr.top += FONT_HEIGHT_NORMAL; + } - /* Start date (if available) */ - if (_load_check_data.settings.game_creation.starting_year != 0) { - SetDParam(0, ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1)); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_START_DATE); - y += FONT_HEIGHT_NORMAL; - } - if (y > y_max) break; - - /* Hide current date for scenarios */ - if (this->abstract_filetype != FT_SCENARIO) { - /* Current date */ - SetDParam(0, _load_check_data.current_date); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CURRENT_DATE); - y += FONT_HEIGHT_NORMAL; - } + tr.top += WidgetDimensions::scaled.vsep_normal; + if (tr.top > tr.bottom) return; - /* Hide the NewGRF stuff when saving. We also hide the button. */ - if (this->fop == SLO_LOAD && (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO)) { - y += WD_PAR_VSEP_NORMAL; - if (y > y_max) break; + /* Start date (if available) */ + if (_load_check_data.settings.game_creation.starting_year != 0) { + SetDParam(0, ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1)); + DrawString(tr, STR_NETWORK_SERVER_LIST_START_DATE); + tr.top += FONT_HEIGHT_NORMAL; + } + if (tr.top > tr.bottom) return; + + /* Hide current date for scenarios */ + if (this->abstract_filetype != FT_SCENARIO) { + /* Current date */ + SetDParam(0, _load_check_data.current_date); + DrawString(tr, STR_NETWORK_SERVER_LIST_CURRENT_DATE); + tr.top += FONT_HEIGHT_NORMAL; + } - /* NewGrf compatibility */ - SetDParam(0, _load_check_data.grfconfig == nullptr ? STR_NEWGRF_LIST_NONE : - STR_NEWGRF_LIST_ALL_FOUND + _load_check_data.grf_compatibility); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_GRFSTATUS); - y += FONT_HEIGHT_NORMAL; - } - if (y > y_max) break; - - /* Hide the company stuff for scenarios */ - if (this->abstract_filetype != FT_SCENARIO) { - y += FONT_HEIGHT_NORMAL; - if (y > y_max) break; - - /* Companies / AIs */ - for (auto &pair : _load_check_data.companies) { - SetDParam(0, pair.first + 1); - const CompanyProperties &c = *pair.second; - if (!c.name.empty()) { - SetDParam(1, STR_JUST_RAW_STRING); - SetDParamStr(2, c.name); - } else { - SetDParam(1, c.name_1); - SetDParam(2, c.name_2); - } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_COMPANY_INDEX); - y += FONT_HEIGHT_NORMAL; - if (y > y_max) break; - } + /* Hide the NewGRF stuff when saving. We also hide the button. */ + if (this->fop == SLO_LOAD && (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO)) { + tr.top += WidgetDimensions::scaled.vsep_normal; + if (tr.top > tr.bottom) return; + + /* NewGrf compatibility */ + SetDParam(0, _load_check_data.grfconfig == nullptr ? STR_NEWGRF_LIST_NONE : + STR_NEWGRF_LIST_ALL_FOUND + _load_check_data.grf_compatibility); + DrawString(tr, STR_SAVELOAD_DETAIL_GRFSTATUS); + tr.top += FONT_HEIGHT_NORMAL; + } + if (tr.top > tr.bottom) return; + + /* Hide the company stuff for scenarios */ + if (this->abstract_filetype != FT_SCENARIO) { + tr.top += WidgetDimensions::scaled.vsep_wide; + if (tr.top > tr.bottom) return; + + /* Companies / AIs */ + for (auto &pair : _load_check_data.companies) { + SetDParam(0, pair.first + 1); + const CompanyProperties &c = *pair.second; + if (!c.name.empty()) { + SetDParam(1, STR_JUST_RAW_STRING); + SetDParamStr(2, c.name); + } else { + SetDParam(1, c.name_1); + SetDParam(2, c.name_2); } + DrawString(tr, STR_SAVELOAD_DETAIL_COMPANY_INDEX); + tr.top += FONT_HEIGHT_NORMAL; + if (tr.top > tr.bottom) break; } - break; } } } @@ -559,12 +580,12 @@ struct SaveLoadWindow : public Window { { switch (widget) { case WID_SL_BACKGROUND: - size->height = 2 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + size->height = 2 * FONT_HEIGHT_NORMAL + padding.height; break; case WID_SL_DRIVES_DIRECTORIES_LIST: resize->height = FONT_HEIGHT_NORMAL; - size->height = resize->height * 10 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + size->height = resize->height * 10 + padding.height; break; case WID_SL_SORT_BYNAME: case WID_SL_SORT_BYDATE: { @@ -644,7 +665,7 @@ struct SaveLoadWindow : public Window { break; case WID_SL_DRIVES_DIRECTORIES_LIST: { // Click the listbox - int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WD_FRAMERECT_TOP); + int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WidgetDimensions::scaled.inset.top); if (y == INT_MAX) return; /* Get the corresponding non-filtered out item from the list */ @@ -721,13 +742,10 @@ struct SaveLoadWindow : public Window { } } - void OnMouseLoop() override + void OnMouseOver(Point pt, int widget) override { - const Point pt{ _cursor.pos.x - this->left, _cursor.pos.y - this->top }; - const int widget = GetWidgetFromPos(this, pt.x, pt.y); - if (widget == WID_SL_DRIVES_DIRECTORIES_LIST) { - int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WD_FRAMERECT_TOP); + int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WidgetDimensions::scaled.inset.top); if (y == INT_MAX) return; /* Get the corresponding non-filtered out item from the list */ diff --git a/src/fontcache.cpp b/src/fontcache.cpp index deb651e37c575..bcb9364994d9f 100644 --- a/src/fontcache.cpp +++ b/src/fontcache.cpp @@ -9,30 +9,23 @@ #include "stdafx.h" #include "fontcache.h" -#include "fontcache_internal.h" #include "fontdetection.h" #include "blitter/factory.hpp" -#include "core/math_func.hpp" -#include "core/smallmap_type.hpp" -#include "strings_func.h" -#include "zoom_type.h" #include "gfx_layout.h" -#include "zoom_func.h" -#include "fileio_func.h" - -#include "table/sprites.h" -#include "table/control_codes.h" -#include "table/unicode.h" +#include "fontcache/spritefontcache.h" +#include "openttd.h" +#include "settings_func.h" +#include "strings_func.h" +#include "viewport_func.h" +#include "window_func.h" #include "safeguards.h" -static const int ASCII_LETTERSTART = 32; ///< First printable ASCII letter. - /** Default heights for the different sizes of fonts. */ static const int _default_font_height[FS_END] = {10, 6, 18, 10}; static const int _default_font_ascender[FS_END] = { 8, 5, 15, 8}; -FreeTypeSettings _freetype; +FontCacheSettings _fcsettings; /** * Create a new font cache. @@ -72,613 +65,76 @@ int GetCharacterHeight(FontSize size) } -/** Font cache for fonts that are based on a freetype font. */ -class SpriteFontCache : public FontCache { -private: - SpriteID **glyph_to_spriteid_map; ///< Mapping of glyphs to sprite IDs. - - void ClearGlyphToSpriteMap(); -public: - SpriteFontCache(FontSize fs); - ~SpriteFontCache(); - virtual SpriteID GetUnicodeGlyph(WChar key); - virtual void SetUnicodeGlyph(WChar key, SpriteID sprite); - virtual void InitializeUnicodeGlyphMap(); - virtual void ClearFontCache(); - virtual const Sprite *GetGlyph(GlyphID key); - virtual uint GetGlyphWidth(GlyphID key); - virtual bool GetDrawGlyphShadow(); - virtual GlyphID MapCharToGlyph(WChar key) { assert(IsPrintable(key)); return SPRITE_GLYPH | key; } - virtual const void *GetFontTable(uint32 tag, size_t &length) { length = 0; return nullptr; } - virtual const char *GetFontName() { return "sprite"; } - virtual bool IsBuiltInFont() { return true; } -}; - -/** - * Create a new sprite font cache. - * @param fs The font size to create the cache for. - */ -SpriteFontCache::SpriteFontCache(FontSize fs) : FontCache(fs), glyph_to_spriteid_map(nullptr) -{ - this->InitializeUnicodeGlyphMap(); - this->height = ScaleFontTrad(this->GetDefaultFontHeight(this->fs)); -} - -/** - * Free everything we allocated. - */ -SpriteFontCache::~SpriteFontCache() -{ - this->ClearGlyphToSpriteMap(); -} - -SpriteID SpriteFontCache::GetUnicodeGlyph(WChar key) -{ - if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == nullptr) return 0; - return this->glyph_to_spriteid_map[GB(key, 8, 8)][GB(key, 0, 8)]; -} - -void SpriteFontCache::SetUnicodeGlyph(WChar key, SpriteID sprite) -{ - if (this->glyph_to_spriteid_map == nullptr) this->glyph_to_spriteid_map = CallocT(256); - if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == nullptr) this->glyph_to_spriteid_map[GB(key, 8, 8)] = CallocT(256); - this->glyph_to_spriteid_map[GB(key, 8, 8)][GB(key, 0, 8)] = sprite; -} - -void SpriteFontCache::InitializeUnicodeGlyphMap() -{ - /* Clear out existing glyph map if it exists */ - this->ClearGlyphToSpriteMap(); - - SpriteID base; - switch (this->fs) { - default: NOT_REACHED(); - case FS_MONO: // Use normal as default for mono spaced font - case FS_NORMAL: base = SPR_ASCII_SPACE; break; - case FS_SMALL: base = SPR_ASCII_SPACE_SMALL; break; - case FS_LARGE: base = SPR_ASCII_SPACE_BIG; break; - } - - for (uint i = ASCII_LETTERSTART; i < 256; i++) { - SpriteID sprite = base + i - ASCII_LETTERSTART; - if (!SpriteExists(sprite)) continue; - this->SetUnicodeGlyph(i, sprite); - this->SetUnicodeGlyph(i + SCC_SPRITE_START, sprite); - } - - for (uint i = 0; i < lengthof(_default_unicode_map); i++) { - byte key = _default_unicode_map[i].key; - if (key == CLRA) { - /* Clear the glyph. This happens if the glyph at this code point - * is non-standard and should be accessed by an SCC_xxx enum - * entry only. */ - this->SetUnicodeGlyph(_default_unicode_map[i].code, 0); - } else { - SpriteID sprite = base + key - ASCII_LETTERSTART; - this->SetUnicodeGlyph(_default_unicode_map[i].code, sprite); - } - } -} - -/** - * Clear the glyph to sprite mapping. - */ -void SpriteFontCache::ClearGlyphToSpriteMap() -{ - if (this->glyph_to_spriteid_map == nullptr) return; - - for (uint i = 0; i < 256; i++) { - free(this->glyph_to_spriteid_map[i]); - } - free(this->glyph_to_spriteid_map); - this->glyph_to_spriteid_map = nullptr; -} - -void SpriteFontCache::ClearFontCache() -{ - Layouter::ResetFontCache(this->fs); - this->height = ScaleFontTrad(this->GetDefaultFontHeight(this->fs)); -} - -const Sprite *SpriteFontCache::GetGlyph(GlyphID key) -{ - SpriteID sprite = this->GetUnicodeGlyph(key); - if (sprite == 0) sprite = this->GetUnicodeGlyph('?'); - return GetSprite(sprite, ST_FONT); -} - -uint SpriteFontCache::GetGlyphWidth(GlyphID key) -{ - SpriteID sprite = this->GetUnicodeGlyph(key); - if (sprite == 0) sprite = this->GetUnicodeGlyph('?'); - return SpriteExists(sprite) ? GetSprite(sprite, ST_FONT)->width + ScaleFontTrad(this->fs != FS_NORMAL ? 1 : 0) : 0; -} - -bool SpriteFontCache::GetDrawGlyphShadow() -{ - return false; -} - /* static */ FontCache *FontCache::caches[FS_END] = { new SpriteFontCache(FS_NORMAL), new SpriteFontCache(FS_SMALL), new SpriteFontCache(FS_LARGE), new SpriteFontCache(FS_MONO) }; -/** - * Create a new TrueTypeFontCache. - * @param fs The font size that is going to be cached. - * @param pixels The number of pixels this font should be high. - */ -TrueTypeFontCache::TrueTypeFontCache(FontSize fs, int pixels) : FontCache(fs), req_size(pixels), glyph_to_sprite(nullptr) -{ -} - -/** - * Free everything that was allocated for this font cache. - */ -TrueTypeFontCache::~TrueTypeFontCache() -{ - /* Virtual functions get called statically in destructors, so make it explicit to remove any confusion. */ - this->TrueTypeFontCache::ClearFontCache(); - - for (auto &iter : this->font_tables) { - free(iter.second.second); - } -} - -/** - * Reset cached glyphs. - */ -void TrueTypeFontCache::ClearFontCache() -{ - if (this->glyph_to_sprite == nullptr) return; - - for (int i = 0; i < 256; i++) { - if (this->glyph_to_sprite[i] == nullptr) continue; - - for (int j = 0; j < 256; j++) { - if (this->glyph_to_sprite[i][j].duplicate) continue; - free(this->glyph_to_sprite[i][j].sprite); - } - - free(this->glyph_to_sprite[i]); - } - - free(this->glyph_to_sprite); - this->glyph_to_sprite = nullptr; - - Layouter::ResetFontCache(this->fs); -} - - -TrueTypeFontCache::GlyphEntry *TrueTypeFontCache::GetGlyphPtr(GlyphID key) -{ - if (this->glyph_to_sprite == nullptr) return nullptr; - if (this->glyph_to_sprite[GB(key, 8, 8)] == nullptr) return nullptr; - return &this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)]; -} - -void TrueTypeFontCache::SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate) -{ - if (this->glyph_to_sprite == nullptr) { - Debug(freetype, 3, "Allocating root glyph cache for size {}", this->fs); - this->glyph_to_sprite = CallocT(256); - } - - if (this->glyph_to_sprite[GB(key, 8, 8)] == nullptr) { - Debug(freetype, 3, "Allocating glyph cache for range 0x{:02X}00, size {}", GB(key, 8, 8), this->fs); - this->glyph_to_sprite[GB(key, 8, 8)] = CallocT(256); - } - - Debug(freetype, 4, "Set glyph for unicode character 0x{:04X}, size {}", key, this->fs); - this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].sprite = glyph->sprite; - this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].width = glyph->width; - this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].duplicate = duplicate; -} - /* Check if a glyph should be rendered with anti-aliasing. */ -static bool GetFontAAState(FontSize size, bool check_blitter = true) +bool GetFontAAState(FontSize size, bool check_blitter) { /* AA is only supported for 32 bpp */ if (check_blitter && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32) return false; - switch (size) { - default: NOT_REACHED(); - case FS_NORMAL: return _freetype.medium.aa; - case FS_SMALL: return _freetype.small.aa; - case FS_LARGE: return _freetype.large.aa; - case FS_MONO: return _freetype.mono.aa; - } + return GetFontCacheSubSetting(size)->aa; } -bool TrueTypeFontCache::GetDrawGlyphShadow() +void SetFont(FontSize fontsize, const std::string& font, uint size, bool aa) { - return this->fs == FS_NORMAL && GetFontAAState(FS_NORMAL); -} + FontCacheSubSetting *setting = GetFontCacheSubSetting(fontsize); + bool changed = false; -uint TrueTypeFontCache::GetGlyphWidth(GlyphID key) -{ - if ((key & SPRITE_GLYPH) != 0) return this->parent->GetGlyphWidth(key); - - GlyphEntry *glyph = this->GetGlyphPtr(key); - if (glyph == nullptr || glyph->sprite == nullptr) { - this->GetGlyph(key); - glyph = this->GetGlyphPtr(key); + if (setting->font != font) { + setting->font = font; + changed = true; } - return glyph->width; -} - -const Sprite *TrueTypeFontCache::GetGlyph(GlyphID key) -{ - if ((key & SPRITE_GLYPH) != 0) return this->parent->GetGlyph(key); - - /* Check for the glyph in our cache */ - GlyphEntry *glyph = this->GetGlyphPtr(key); - if (glyph != nullptr && glyph->sprite != nullptr) return glyph->sprite; - - if (key == 0) { - GlyphID question_glyph = this->MapCharToGlyph('?'); - if (question_glyph == 0) { - /* The font misses the '?' character. Use built-in sprite. - * Note: We cannot use the baseset as this also has to work in the bootstrap GUI. */ -#define CPSET { 0, 0, 0, 0, 1 } -#define CP___ { 0, 0, 0, 0, 0 } - static SpriteLoader::CommonPixel builtin_questionmark_data[10 * 8] = { - CP___, CP___, CPSET, CPSET, CPSET, CPSET, CP___, CP___, - CP___, CPSET, CPSET, CP___, CP___, CPSET, CPSET, CP___, - CP___, CP___, CP___, CP___, CP___, CPSET, CPSET, CP___, - CP___, CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, - CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___, - CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___, - CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___, - CP___, CP___, CP___, CP___, CP___, CP___, CP___, CP___, - CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___, - CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___, - }; -#undef CPSET -#undef CP___ - static const SpriteLoader::Sprite builtin_questionmark = { - 10, // height - 8, // width - 0, // x_offs - 0, // y_offs - ST_FONT, - SCC_PAL, - builtin_questionmark_data - }; - - Sprite *spr = BlitterFactory::GetCurrentBlitter()->Encode(&builtin_questionmark, SimpleSpriteAlloc); - assert(spr != nullptr); - GlyphEntry new_glyph; - new_glyph.sprite = spr; - new_glyph.width = spr->width + (this->fs != FS_NORMAL); - this->SetGlyphPtr(key, &new_glyph, false); - return new_glyph.sprite; - } else { - /* Use '?' for missing characters. */ - this->GetGlyph(question_glyph); - glyph = this->GetGlyphPtr(question_glyph); - this->SetGlyphPtr(key, glyph, true); - return glyph->sprite; - } + if (setting->size != size) { + setting->size = size; + changed = true; } - return this->InternalGetGlyph(key, GetFontAAState(this->fs)); -} - -const void *TrueTypeFontCache::GetFontTable(uint32 tag, size_t &length) -{ - const FontTable::iterator iter = this->font_tables.Find(tag); - if (iter != this->font_tables.data() + this->font_tables.size()) { - length = iter->second.first; - return iter->second.second; + if (setting->aa != aa) { + setting->aa = aa; + changed = true; } - const void *result = this->InternalGetFontTable(tag, length); - - this->font_tables.Insert(tag, std::pair(length, result)); - return result; -} - - -#ifdef WITH_FREETYPE -#include -#include FT_FREETYPE_H -#include FT_GLYPH_H -#include FT_TRUETYPE_TABLES_H - -/** Font cache for fonts that are based on a freetype font. */ -class FreeTypeFontCache : public TrueTypeFontCache { -private: - FT_Face face; ///< The font face associated with this font. - - void SetFontSize(FontSize fs, FT_Face face, int pixels); - virtual const void *InternalGetFontTable(uint32 tag, size_t &length); - virtual const Sprite *InternalGetGlyph(GlyphID key, bool aa); - -public: - FreeTypeFontCache(FontSize fs, FT_Face face, int pixels); - ~FreeTypeFontCache(); - virtual void ClearFontCache(); - virtual GlyphID MapCharToGlyph(WChar key); - virtual const char *GetFontName() { return face->family_name; } - virtual bool IsBuiltInFont() { return false; } -}; - -FT_Library _library = nullptr; + if (!changed) return; - -/** - * Create a new FreeTypeFontCache. - * @param fs The font size that is going to be cached. - * @param face The font that has to be loaded. - * @param pixels The number of pixels this font should be high. - */ -FreeTypeFontCache::FreeTypeFontCache(FontSize fs, FT_Face face, int pixels) : TrueTypeFontCache(fs, pixels), face(face) -{ - assert(face != nullptr); - - this->SetFontSize(fs, face, pixels); -} - -void FreeTypeFontCache::SetFontSize(FontSize fs, FT_Face face, int pixels) -{ - if (pixels == 0) { - /* Try to determine a good height based on the minimal height recommended by the font. */ - int scaled_height = ScaleFontTrad(this->GetDefaultFontHeight(this->fs)); - pixels = scaled_height; - - TT_Header *head = (TT_Header *)FT_Get_Sfnt_Table(this->face, ft_sfnt_head); - if (head != nullptr) { - /* Font height is minimum height plus the difference between the default - * height for this font size and the small size. */ - int diff = scaled_height - ScaleFontTrad(this->GetDefaultFontHeight(FS_SMALL)); - pixels = Clamp(std::min(head->Lowest_Rec_PPEM, MAX_FONT_MIN_REC_SIZE) + diff, scaled_height, MAX_FONT_SIZE); + if (fontsize != FS_MONO) { + /* Try to reload only the modified font. */ + FontCacheSettings backup = _fcsettings; + for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) { + if (fs == fontsize) continue; + FontCache *fc = FontCache::Get(fs); + GetFontCacheSubSetting(fs)->font = fc->HasParent() ? fc->GetFontName() : ""; } + CheckForMissingGlyphs(); + _fcsettings = backup; } else { - pixels = ScaleFontTrad(pixels); - } - this->used_size = pixels; - - FT_Error err = FT_Set_Pixel_Sizes(this->face, 0, pixels); - if (err != FT_Err_Ok) { - - /* Find nearest size to that requested */ - FT_Bitmap_Size *bs = this->face->available_sizes; - int i = this->face->num_fixed_sizes; - if (i > 0) { // In pathetic cases one might get no fixed sizes at all. - int n = bs->height; - FT_Int chosen = 0; - for (; --i; bs++) { - if (abs(pixels - bs->height) >= abs(pixels - n)) continue; - n = bs->height; - chosen = this->face->num_fixed_sizes - i; - } - - /* Don't use FT_Set_Pixel_Sizes here - it might give us another - * error, even though the size is available (FS#5885). */ - err = FT_Select_Size(this->face, chosen); - } - } - - if (err == FT_Err_Ok) { - this->units_per_em = this->face->units_per_EM; - this->ascender = this->face->size->metrics.ascender >> 6; - this->descender = this->face->size->metrics.descender >> 6; - this->height = this->ascender - this->descender; - } else { - /* Both FT_Set_Pixel_Sizes and FT_Select_Size failed. */ - Debug(freetype, 0, "Font size selection failed. Using FontCache defaults."); - } -} - -/** - * Loads the freetype font. - * First type to load the fontname as if it were a path. If that fails, - * try to resolve the filename of the font using fontconfig, where the - * format is 'font family name' or 'font family name, font style'. - * @param fs The font size to load. - */ -static void LoadFreeTypeFont(FontSize fs) -{ - FreeTypeSubSetting *settings = nullptr; - switch (fs) { - default: NOT_REACHED(); - case FS_SMALL: settings = &_freetype.small; break; - case FS_NORMAL: settings = &_freetype.medium; break; - case FS_LARGE: settings = &_freetype.large; break; - case FS_MONO: settings = &_freetype.mono; break; - } - - if (settings->font.empty()) return; - - if (_library == nullptr) { - if (FT_Init_FreeType(&_library) != FT_Err_Ok) { - ShowInfoF("Unable to initialize FreeType, using sprite fonts instead"); - return; - } - - 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, font_name, 0, &face); - -#if defined(WITH_COCOA) - extern void MacOSRegisterExternalFont(const char *file_path); - 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, font_name); - if (!full_font.empty()) { - error = FT_New_Face(_library, full_font.c_str(), 0, &face); -#if defined(WITH_COCOA) - if (error == FT_Err_Ok) MacOSRegisterExternalFont(full_font.c_str()); -#endif - } - } - - /* Try loading based on font face name (OS-wide fonts). */ - if (error != FT_Err_Ok) error = GetFontByFaceName(font_name, &face); - - if (error == FT_Err_Ok) { - Debug(freetype, 2, "Requested '{}', using '{} {}'", font_name, face->family_name, face->style_name); - - /* Attempt to select the unicode character map */ - error = FT_Select_Charmap(face, ft_encoding_unicode); - if (error == FT_Err_Ok) goto found_face; // Success - - if (error == FT_Err_Invalid_CharMap_Handle) { - /* Try to pick a different character map instead. We default to - * the first map, but platform_id 0 encoding_id 0 should also - * be unicode (strange system...) */ - FT_CharMap found = face->charmaps[0]; - int i; - - for (i = 0; i < face->num_charmaps; i++) { - FT_CharMap charmap = face->charmaps[i]; - if (charmap->platform_id == 0 && charmap->encoding_id == 0) { - found = charmap; - } - } - - if (found != nullptr) { - error = FT_Set_Charmap(face, found); - if (error == FT_Err_Ok) goto found_face; - } - } + InitFontCache(true); } - FT_Done_Face(face); + LoadStringWidthTable(); + UpdateAllVirtCoords(); + ReInitAllWindows(true); - 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", font_name, SIZE_TO_NAME[fs], error); - return; - -found_face: - new FreeTypeFontCache(fs, face, settings->size); -} - - -/** - * Free everything that was allocated for this font cache. - */ -FreeTypeFontCache::~FreeTypeFontCache() -{ - FT_Done_Face(this->face); - this->face = nullptr; - this->ClearFontCache(); -} - -/** - * Reset cached glyphs. - */ -void FreeTypeFontCache::ClearFontCache() -{ - /* Font scaling might have changed, determine font size anew if it was automatically selected. */ - if (this->face != nullptr) this->SetFontSize(this->fs, this->face, this->req_size); - - this->TrueTypeFontCache::ClearFontCache(); + if (_save_config) SaveToConfig(); } - -const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa) -{ - FT_GlyphSlot slot = this->face->glyph; - - FT_Load_Glyph(this->face, key, aa ? FT_LOAD_TARGET_NORMAL : FT_LOAD_TARGET_MONO); - FT_Render_Glyph(this->face->glyph, aa ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO); - - /* Despite requesting a normal glyph, FreeType may have returned a bitmap */ - aa = (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY); - - /* Add 1 pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel */ - uint width = std::max(1U, (uint)slot->bitmap.width + (this->fs == FS_NORMAL)); - uint height = std::max(1U, (uint)slot->bitmap.rows + (this->fs == FS_NORMAL)); - - /* Limit glyph size to prevent overflows later on. */ - if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) usererror("Font glyph is too large"); - - /* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */ - SpriteLoader::Sprite sprite; - sprite.AllocateData(ZOOM_LVL_NORMAL, width * height); - sprite.type = ST_FONT; - sprite.colours = (aa ? SCC_PAL | SCC_ALPHA : SCC_PAL); - sprite.width = width; - sprite.height = height; - sprite.x_offs = slot->bitmap_left; - sprite.y_offs = this->ascender - slot->bitmap_top; - - /* Draw shadow for medium size */ - if (this->fs == FS_NORMAL && !aa) { - for (uint y = 0; y < (uint)slot->bitmap.rows; y++) { - for (uint x = 0; x < (uint)slot->bitmap.width; x++) { - if (HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) { - sprite.data[1 + x + (1 + y) * sprite.width].m = SHADOW_COLOUR; - sprite.data[1 + x + (1 + y) * sprite.width].a = 0xFF; - } - } - } - } - - for (uint y = 0; y < (uint)slot->bitmap.rows; y++) { - for (uint x = 0; x < (uint)slot->bitmap.width; x++) { - if (aa ? (slot->bitmap.buffer[x + y * slot->bitmap.pitch] > 0) : HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) { - sprite.data[x + y * sprite.width].m = FACE_COLOUR; - sprite.data[x + y * sprite.width].a = aa ? slot->bitmap.buffer[x + y * slot->bitmap.pitch] : 0xFF; - } - } - } - - GlyphEntry new_glyph; - new_glyph.sprite = BlitterFactory::GetCurrentBlitter()->Encode(&sprite, SimpleSpriteAlloc); - new_glyph.width = slot->advance.x >> 6; - - this->SetGlyphPtr(key, &new_glyph); - - return new_glyph.sprite; -} - - -GlyphID FreeTypeFontCache::MapCharToGlyph(WChar key) -{ - assert(IsPrintable(key)); - - if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) { - return this->parent->MapCharToGlyph(key); - } - - return FT_Get_Char_Index(this->face, key); -} - -const void *FreeTypeFontCache::InternalGetFontTable(uint32 tag, size_t &length) -{ - FT_ULong len = 0; - FT_Byte *result = nullptr; - - FT_Load_Sfnt_Table(this->face, tag, 0, nullptr, &len); - - if (len > 0) { - result = MallocT(len); - FT_Load_Sfnt_Table(this->face, tag, 0, result, &len); - } - - length = len; - return result; -} -#endif /* WITH_FREETYPE */ - +#ifdef WITH_FREETYPE +extern void LoadFreeTypeFont(FontSize fs); +extern void UninitFreeType(); +#elif defined(_WIN32) +extern void LoadWin32Font(FontSize fs); +#elif defined(WITH_COCOA) +extern void LoadCoreTextFont(FontSize fs); +#endif /** - * (Re)initialize the freetype related things, i.e. load the non-sprite fonts. + * (Re)initialize the font cache related things, i.e. load the non-sprite fonts. * @param monospace Whether to initialise the monospace or regular fonts. */ -void InitFreeType(bool monospace) +void InitFontCache(bool monospace) { for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) { if (monospace != (fs == FS_MONO)) continue; @@ -689,10 +145,8 @@ void InitFreeType(bool monospace) #ifdef WITH_FREETYPE LoadFreeTypeFont(fs); #elif defined(_WIN32) - extern void LoadWin32Font(FontSize fs); LoadWin32Font(fs); #elif defined(WITH_COCOA) - extern void LoadCoreTextFont(FontSize fs); LoadCoreTextFont(fs); #endif } @@ -701,7 +155,7 @@ void InitFreeType(bool monospace) /** * Free everything allocated w.r.t. fonts. */ -void UninitFreeType() +void UninitFontCache() { for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) { FontCache *fc = FontCache::Get(fs); @@ -709,8 +163,7 @@ void UninitFreeType() } #ifdef WITH_FREETYPE - FT_Done_FreeType(_library); - _library = nullptr; + UninitFreeType(); #endif /* WITH_FREETYPE */ } @@ -729,9 +182,5 @@ bool HasAntialiasedFonts() #if !defined(_WIN32) && !defined(__APPLE__) && !defined(WITH_FONTCONFIG) && !defined(WITH_COCOA) -#ifdef WITH_FREETYPE -FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) { return FT_Err_Cannot_Open_Resource; } -#endif /* WITH_FREETYPE */ - -bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) { return false; } +bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) { return false; } #endif /* !defined(_WIN32) && !defined(__APPLE__) && !defined(WITH_FONTCONFIG) && !defined(WITH_COCOA) */ diff --git a/src/fontcache.h b/src/fontcache.h index 2eb5634cfbbe2..efc14963047df 100644 --- a/src/fontcache.h +++ b/src/fontcache.h @@ -29,12 +29,12 @@ class FontCache { int descender; ///< The descender value of the font. int units_per_em; ///< The units per EM value of the font. - static int GetDefaultFontHeight(FontSize fs); - public: FontCache(FontSize fs); virtual ~FontCache(); + static int GetDefaultFontHeight(FontSize fs); + /** * Get the FontSize of the font. * @return The FontSize. @@ -71,13 +71,6 @@ class FontCache { */ virtual int GetFontSize() const { return this->height; } - /** - * Get the SpriteID mapped to the given key - * @param key The key to get the sprite for. - * @return The sprite. - */ - virtual SpriteID GetUnicodeGlyph(WChar key) = 0; - /** * Map a SpriteID to the key * @param key The key to map to. @@ -166,12 +159,6 @@ class FontCache { virtual bool IsBuiltInFont() = 0; }; -/** Get the SpriteID mapped to the given font size and key */ -static inline SpriteID GetUnicodeGlyph(FontSize size, WChar key) -{ - return FontCache::Get(size)->GetUnicodeGlyph(key); -} - /** Map a SpriteID to the font size and key */ static inline void SetUnicodeGlyph(FontSize size, WChar key, SpriteID sprite) { @@ -212,8 +199,8 @@ static inline bool GetDrawGlyphShadow(FontSize size) return FontCache::Get(size)->GetDrawGlyphShadow(); } -/** Settings for a single freetype font. */ -struct FreeTypeSubSetting { +/** Settings for a single font. */ +struct FontCacheSubSetting { 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. @@ -221,18 +208,37 @@ struct FreeTypeSubSetting { const void *os_handle = nullptr; ///< Optional native OS font info. Only valid during font search. }; -/** Settings for the freetype fonts. */ -struct FreeTypeSettings { - FreeTypeSubSetting small; ///< The smallest font; mostly used for zoomed out view. - FreeTypeSubSetting medium; ///< The normal font size. - FreeTypeSubSetting large; ///< The largest font; mostly used for newspapers. - FreeTypeSubSetting mono; ///< The mono space font used for license/readme viewers. +/** Settings for the four different fonts. */ +struct FontCacheSettings { + FontCacheSubSetting small; ///< The smallest font; mostly used for zoomed out view. + FontCacheSubSetting medium; ///< The normal font size. + FontCacheSubSetting large; ///< The largest font; mostly used for newspapers. + FontCacheSubSetting mono; ///< The mono space font used for license/readme viewers. }; -extern FreeTypeSettings _freetype; +extern FontCacheSettings _fcsettings; + +/** + * Get the settings of a given font size. + * @param fs The font size to look up. + * @return The settings. + */ +static inline FontCacheSubSetting *GetFontCacheSubSetting(FontSize fs) +{ + switch (fs) { + default: NOT_REACHED(); + case FS_SMALL: return &_fcsettings.small; + case FS_NORMAL: return &_fcsettings.medium; + case FS_LARGE: return &_fcsettings.large; + case FS_MONO: return &_fcsettings.mono; + } +} -void InitFreeType(bool monospace); -void UninitFreeType(); +void InitFontCache(bool monospace); +void UninitFontCache(); bool HasAntialiasedFonts(); +bool GetFontAAState(FontSize size, bool check_blitter = true); +void SetFont(FontSize fontsize, const std::string &font, uint size, bool aa); + #endif /* FONTCACHE_H */ diff --git a/src/fontcache/CMakeLists.txt b/src/fontcache/CMakeLists.txt new file mode 100644 index 0000000000000..43f4d5a301761 --- /dev/null +++ b/src/fontcache/CMakeLists.txt @@ -0,0 +1,11 @@ +add_files( + freetypefontcache.cpp + CONDITION Freetype_FOUND +) + +add_files( + spritefontcache.cpp + spritefontcache.h + truetypefontcache.cpp + truetypefontcache.h +) diff --git a/src/fontcache/freetypefontcache.cpp b/src/fontcache/freetypefontcache.cpp new file mode 100644 index 0000000000000..2ec9416bf874d --- /dev/null +++ b/src/fontcache/freetypefontcache.cpp @@ -0,0 +1,324 @@ +/* + * 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 freetypefontcache.cpp FreeType font cache implementation. */ + +#include "../stdafx.h" +#include "../debug.h" +#include "../fontcache.h" +#include "../fontdetection.h" +#include "../blitter/factory.hpp" +#include "../core/math_func.hpp" +#include "../zoom_func.h" +#include "../fileio_func.h" +#include "truetypefontcache.h" + +#include "../table/control_codes.h" + +#include "../safeguards.h" + +#ifdef WITH_FREETYPE +#include +#include FT_FREETYPE_H +#include FT_GLYPH_H +#include FT_TRUETYPE_TABLES_H + +/** Font cache for fonts that are based on a freetype font. */ +class FreeTypeFontCache : public TrueTypeFontCache { +private: + FT_Face face; ///< The font face associated with this font. + + void SetFontSize(FontSize fs, FT_Face face, int pixels); + virtual const void *InternalGetFontTable(uint32 tag, size_t &length); + virtual const Sprite *InternalGetGlyph(GlyphID key, bool aa); + +public: + FreeTypeFontCache(FontSize fs, FT_Face face, int pixels); + ~FreeTypeFontCache(); + virtual void ClearFontCache(); + virtual GlyphID MapCharToGlyph(WChar key); + virtual const char *GetFontName() { return face->family_name; } + virtual bool IsBuiltInFont() { return false; } +}; + +FT_Library _library = nullptr; + + +/** + * Create a new FreeTypeFontCache. + * @param fs The font size that is going to be cached. + * @param face The font that has to be loaded. + * @param pixels The number of pixels this font should be high. + */ +FreeTypeFontCache::FreeTypeFontCache(FontSize fs, FT_Face face, int pixels) : TrueTypeFontCache(fs, pixels), face(face) +{ + assert(face != nullptr); + + this->SetFontSize(fs, face, pixels); +} + +void FreeTypeFontCache::SetFontSize(FontSize fs, FT_Face face, int pixels) +{ + if (pixels == 0) { + /* Try to determine a good height based on the minimal height recommended by the font. */ + int scaled_height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs)); + pixels = scaled_height; + + TT_Header *head = (TT_Header *)FT_Get_Sfnt_Table(this->face, ft_sfnt_head); + if (head != nullptr) { + /* Font height is minimum height plus the difference between the default + * height for this font size and the small size. */ + int diff = scaled_height - ScaleGUITrad(FontCache::GetDefaultFontHeight(FS_SMALL)); + /* Clamp() is not used as scaled_height could be greater than MAX_FONT_SIZE, which is not permitted in Clamp(). */ + pixels = std::min(std::max(std::min(head->Lowest_Rec_PPEM, MAX_FONT_MIN_REC_SIZE) + diff, scaled_height), MAX_FONT_SIZE); + } + } else { + pixels = ScaleGUITrad(pixels); + } + this->used_size = pixels; + + FT_Error err = FT_Set_Pixel_Sizes(this->face, 0, pixels); + if (err != FT_Err_Ok) { + + /* Find nearest size to that requested */ + FT_Bitmap_Size *bs = this->face->available_sizes; + int i = this->face->num_fixed_sizes; + if (i > 0) { // In pathetic cases one might get no fixed sizes at all. + int n = bs->height; + FT_Int chosen = 0; + for (; --i; bs++) { + if (abs(pixels - bs->height) >= abs(pixels - n)) continue; + n = bs->height; + chosen = this->face->num_fixed_sizes - i; + } + + /* Don't use FT_Set_Pixel_Sizes here - it might give us another + * error, even though the size is available (FS#5885). */ + err = FT_Select_Size(this->face, chosen); + } + } + + if (err == FT_Err_Ok) { + this->units_per_em = this->face->units_per_EM; + this->ascender = this->face->size->metrics.ascender >> 6; + this->descender = this->face->size->metrics.descender >> 6; + this->height = this->ascender - this->descender; + } else { + /* Both FT_Set_Pixel_Sizes and FT_Select_Size failed. */ + Debug(fontcache, 0, "Font size selection failed. Using FontCache defaults."); + } +} + +/** + * Loads the freetype font. + * First type to load the fontname as if it were a path. If that fails, + * try to resolve the filename of the font using fontconfig, where the + * format is 'font family name' or 'font family name, font style'. + * @param fs The font size to load. + */ +void LoadFreeTypeFont(FontSize fs) +{ + FontCacheSubSetting *settings = GetFontCacheSubSetting(fs); + + if (settings->font.empty()) return; + + if (_library == nullptr) { + if (FT_Init_FreeType(&_library) != FT_Err_Ok) { + ShowInfoF("Unable to initialize FreeType, using sprite fonts instead"); + return; + } + + Debug(fontcache, 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, font_name, 0, &face); + +#if defined(WITH_COCOA) + extern void MacOSRegisterExternalFont(const char *file_path); + 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, font_name); + if (!full_font.empty()) { + error = FT_New_Face(_library, full_font.c_str(), 0, &face); +#if defined(WITH_COCOA) + if (error == FT_Err_Ok) MacOSRegisterExternalFont(full_font.c_str()); +#endif + } + } + + /* Try loading based on font face name (OS-wide fonts). */ + if (error != FT_Err_Ok) error = GetFontByFaceName(font_name, &face); + + if (error == FT_Err_Ok) { + Debug(fontcache, 2, "Requested '{}', using '{} {}'", font_name, face->family_name, face->style_name); + + /* Attempt to select the unicode character map */ + error = FT_Select_Charmap(face, ft_encoding_unicode); + if (error == FT_Err_Ok) goto found_face; // Success + + if (error == FT_Err_Invalid_CharMap_Handle) { + /* Try to pick a different character map instead. We default to + * the first map, but platform_id 0 encoding_id 0 should also + * be unicode (strange system...) */ + FT_CharMap found = face->charmaps[0]; + int i; + + for (i = 0; i < face->num_charmaps; i++) { + FT_CharMap charmap = face->charmaps[i]; + if (charmap->platform_id == 0 && charmap->encoding_id == 0) { + found = charmap; + } + } + + if (found != nullptr) { + error = FT_Set_Charmap(face, found); + if (error == FT_Err_Ok) goto found_face; + } + } + } + + FT_Done_Face(face); + + ShowInfoF("Unable to use '%s' for %s font, FreeType reported error 0x%X, using sprite font instead", font_name, FontSizeToName(fs), error); + return; + +found_face: + new FreeTypeFontCache(fs, face, settings->size); +} + + +/** + * Free everything that was allocated for this font cache. + */ +FreeTypeFontCache::~FreeTypeFontCache() +{ + FT_Done_Face(this->face); + this->face = nullptr; + this->ClearFontCache(); +} + +/** + * Reset cached glyphs. + */ +void FreeTypeFontCache::ClearFontCache() +{ + /* Font scaling might have changed, determine font size anew if it was automatically selected. */ + if (this->face != nullptr) this->SetFontSize(this->fs, this->face, this->req_size); + + this->TrueTypeFontCache::ClearFontCache(); +} + + +const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa) +{ + FT_GlyphSlot slot = this->face->glyph; + + FT_Load_Glyph(this->face, key, aa ? FT_LOAD_TARGET_NORMAL : FT_LOAD_TARGET_MONO); + FT_Render_Glyph(this->face->glyph, aa ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO); + + /* Despite requesting a normal glyph, FreeType may have returned a bitmap */ + aa = (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY); + + /* Add 1 scaled pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel */ + uint shadow = (this->fs == FS_NORMAL) ? ScaleGUITrad(1) : 0; + uint width = std::max(1U, (uint)slot->bitmap.width + shadow); + uint height = std::max(1U, (uint)slot->bitmap.rows + shadow); + + /* Limit glyph size to prevent overflows later on. */ + if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) usererror("Font glyph is too large"); + + /* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */ + SpriteLoader::Sprite sprite; + sprite.AllocateData(ZOOM_LVL_NORMAL, static_cast(width) * height); + sprite.type = ST_FONT; + sprite.colours = (aa ? SCC_PAL | SCC_ALPHA : SCC_PAL); + sprite.width = width; + sprite.height = height; + sprite.x_offs = slot->bitmap_left; + sprite.y_offs = this->ascender - slot->bitmap_top; + + /* Draw shadow for medium size */ + if (this->fs == FS_NORMAL && !aa) { + for (uint y = 0; y < (uint)slot->bitmap.rows; y++) { + for (uint x = 0; x < (uint)slot->bitmap.width; x++) { + if (HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) { + sprite.data[shadow + x + (shadow + y) * sprite.width].m = SHADOW_COLOUR; + sprite.data[shadow + x + (shadow + y) * sprite.width].a = 0xFF; + } + } + } + } + + for (uint y = 0; y < (uint)slot->bitmap.rows; y++) { + for (uint x = 0; x < (uint)slot->bitmap.width; x++) { + if (aa ? (slot->bitmap.buffer[x + y * slot->bitmap.pitch] > 0) : HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) { + sprite.data[x + y * sprite.width].m = FACE_COLOUR; + sprite.data[x + y * sprite.width].a = aa ? slot->bitmap.buffer[x + y * slot->bitmap.pitch] : 0xFF; + } + } + } + + GlyphEntry new_glyph; + new_glyph.sprite = BlitterFactory::GetCurrentBlitter()->Encode(&sprite, SimpleSpriteAlloc); + new_glyph.width = slot->advance.x >> 6; + + this->SetGlyphPtr(key, &new_glyph); + + return new_glyph.sprite; +} + + +GlyphID FreeTypeFontCache::MapCharToGlyph(WChar key) +{ + assert(IsPrintable(key)); + + if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) { + return this->parent->MapCharToGlyph(key); + } + + return FT_Get_Char_Index(this->face, key); +} + +const void *FreeTypeFontCache::InternalGetFontTable(uint32 tag, size_t &length) +{ + FT_ULong len = 0; + FT_Byte *result = nullptr; + + FT_Load_Sfnt_Table(this->face, tag, 0, nullptr, &len); + + if (len > 0) { + result = MallocT(len); + FT_Load_Sfnt_Table(this->face, tag, 0, result, &len); + } + + length = len; + return result; +} + +/** + * Free everything allocated w.r.t. freetype. + */ +void UninitFreeType() +{ + FT_Done_FreeType(_library); + _library = nullptr; +} + +#if !defined(_WIN32) && !defined(__APPLE__) && !defined(WITH_FONTCONFIG) && !defined(WITH_COCOA) + +FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) { return FT_Err_Cannot_Open_Resource; } + +#endif /* !defined(_WIN32) && !defined(__APPLE__) && !defined(WITH_FONTCONFIG) && !defined(WITH_COCOA) */ + +#endif /* WITH_FREETYPE */ diff --git a/src/fontcache/spritefontcache.cpp b/src/fontcache/spritefontcache.cpp new file mode 100644 index 0000000000000..2a2f3ed9fdaba --- /dev/null +++ b/src/fontcache/spritefontcache.cpp @@ -0,0 +1,129 @@ +/* + * 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 spritefontcache.cpp Sprite fontcache implementation. */ + +#include "../stdafx.h" +#include "../fontcache.h" +#include "../gfx_layout.h" +#include "../zoom_func.h" +#include "spritefontcache.h" + +#include "../table/sprites.h" +#include "../table/control_codes.h" +#include "../table/unicode.h" + +#include "../safeguards.h" + +static const int ASCII_LETTERSTART = 32; ///< First printable ASCII letter. + +/** + * Create a new sprite font cache. + * @param fs The font size to create the cache for. + */ +SpriteFontCache::SpriteFontCache(FontSize fs) : FontCache(fs), glyph_to_spriteid_map(nullptr) +{ + this->InitializeUnicodeGlyphMap(); + this->height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs)); + this->ascender = (this->height - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->fs))) / 2; +} + +/** + * Free everything we allocated. + */ +SpriteFontCache::~SpriteFontCache() +{ + this->ClearGlyphToSpriteMap(); +} + +SpriteID SpriteFontCache::GetUnicodeGlyph(WChar key) +{ + if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == nullptr) return 0; + return this->glyph_to_spriteid_map[GB(key, 8, 8)][GB(key, 0, 8)]; +} + +void SpriteFontCache::SetUnicodeGlyph(WChar key, SpriteID sprite) +{ + if (this->glyph_to_spriteid_map == nullptr) this->glyph_to_spriteid_map = CallocT(256); + if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == nullptr) this->glyph_to_spriteid_map[GB(key, 8, 8)] = CallocT(256); + this->glyph_to_spriteid_map[GB(key, 8, 8)][GB(key, 0, 8)] = sprite; +} + +void SpriteFontCache::InitializeUnicodeGlyphMap() +{ + /* Clear out existing glyph map if it exists */ + this->ClearGlyphToSpriteMap(); + + SpriteID base; + switch (this->fs) { + default: NOT_REACHED(); + case FS_MONO: // Use normal as default for mono spaced font + case FS_NORMAL: base = SPR_ASCII_SPACE; break; + case FS_SMALL: base = SPR_ASCII_SPACE_SMALL; break; + case FS_LARGE: base = SPR_ASCII_SPACE_BIG; break; + } + + for (uint i = ASCII_LETTERSTART; i < 256; i++) { + SpriteID sprite = base + i - ASCII_LETTERSTART; + if (!SpriteExists(sprite)) continue; + this->SetUnicodeGlyph(i, sprite); + this->SetUnicodeGlyph(i + SCC_SPRITE_START, sprite); + } + + for (uint i = 0; i < lengthof(_default_unicode_map); i++) { + byte key = _default_unicode_map[i].key; + if (key == CLRA) { + /* Clear the glyph. This happens if the glyph at this code point + * is non-standard and should be accessed by an SCC_xxx enum + * entry only. */ + this->SetUnicodeGlyph(_default_unicode_map[i].code, 0); + } else { + SpriteID sprite = base + key - ASCII_LETTERSTART; + this->SetUnicodeGlyph(_default_unicode_map[i].code, sprite); + } + } +} + +/** + * Clear the glyph to sprite mapping. + */ +void SpriteFontCache::ClearGlyphToSpriteMap() +{ + if (this->glyph_to_spriteid_map == nullptr) return; + + for (uint i = 0; i < 256; i++) { + free(this->glyph_to_spriteid_map[i]); + } + free(this->glyph_to_spriteid_map); + this->glyph_to_spriteid_map = nullptr; +} + +void SpriteFontCache::ClearFontCache() +{ + Layouter::ResetFontCache(this->fs); + this->height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs)); + this->ascender = (this->height - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->fs))) / 2; +} + +const Sprite *SpriteFontCache::GetGlyph(GlyphID key) +{ + SpriteID sprite = this->GetUnicodeGlyph(key); + if (sprite == 0) sprite = this->GetUnicodeGlyph('?'); + return GetSprite(sprite, ST_FONT); +} + +uint SpriteFontCache::GetGlyphWidth(GlyphID key) +{ + SpriteID sprite = this->GetUnicodeGlyph(key); + if (sprite == 0) sprite = this->GetUnicodeGlyph('?'); + return SpriteExists(sprite) ? GetSprite(sprite, ST_FONT)->width + ScaleSpriteTrad(this->fs != FS_NORMAL ? 1 : 0) : 0; +} + +bool SpriteFontCache::GetDrawGlyphShadow() +{ + return false; +} diff --git a/src/fontcache/spritefontcache.h b/src/fontcache/spritefontcache.h new file mode 100644 index 0000000000000..a47b4ac18f9da --- /dev/null +++ b/src/fontcache/spritefontcache.h @@ -0,0 +1,38 @@ +/* + * 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 spritefontcache.h Sprite font cache implementation definition. */ + +#ifndef SPRITEFONTCACHE_H +#define SPRITEFONTCACHE_H + +#include "../string_func.h" +#include "../fontcache.h" + +/** Font cache for fonts that are based on a freetype font. */ +class SpriteFontCache : public FontCache { +private: + SpriteID **glyph_to_spriteid_map; ///< Mapping of glyphs to sprite IDs. + SpriteID GetUnicodeGlyph(WChar key); + + void ClearGlyphToSpriteMap(); +public: + SpriteFontCache(FontSize fs); + ~SpriteFontCache(); + virtual void SetUnicodeGlyph(WChar key, SpriteID sprite); + virtual void InitializeUnicodeGlyphMap(); + virtual void ClearFontCache(); + virtual const Sprite *GetGlyph(GlyphID key); + virtual uint GetGlyphWidth(GlyphID key); + virtual bool GetDrawGlyphShadow(); + virtual GlyphID MapCharToGlyph(WChar key) { assert(IsPrintable(key)); return SPRITE_GLYPH | key; } + virtual const void *GetFontTable(uint32 tag, size_t &length) { length = 0; return nullptr; } + virtual const char *GetFontName() { return "sprite"; } + virtual bool IsBuiltInFont() { return true; } +}; + +#endif /* SPRITEFONTCACHE_H */ diff --git a/src/fontcache/truetypefontcache.cpp b/src/fontcache/truetypefontcache.cpp new file mode 100644 index 0000000000000..fa6a600edda44 --- /dev/null +++ b/src/fontcache/truetypefontcache.cpp @@ -0,0 +1,180 @@ +/* + * 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 truetypefontcache.cpp Common base implementation for font file based font caches. */ + +#include "../stdafx.h" +#include "../debug.h" +#include "../fontcache.h" +#include "../blitter/factory.hpp" +#include "../core/bitmath_func.hpp" +#include "../gfx_layout.h" +#include "truetypefontcache.h" + +#include "../safeguards.h" + +/** + * Create a new TrueTypeFontCache. + * @param fs The font size that is going to be cached. + * @param pixels The number of pixels this font should be high. + */ +TrueTypeFontCache::TrueTypeFontCache(FontSize fs, int pixels) : FontCache(fs), req_size(pixels), glyph_to_sprite(nullptr) +{ +} + +/** + * Free everything that was allocated for this font cache. + */ +TrueTypeFontCache::~TrueTypeFontCache() +{ + /* Virtual functions get called statically in destructors, so make it explicit to remove any confusion. */ + this->TrueTypeFontCache::ClearFontCache(); + + for (auto &iter : this->font_tables) { + free(iter.second.second); + } +} + +/** + * Reset cached glyphs. + */ +void TrueTypeFontCache::ClearFontCache() +{ + if (this->glyph_to_sprite == nullptr) return; + + for (int i = 0; i < 256; i++) { + if (this->glyph_to_sprite[i] == nullptr) continue; + + for (int j = 0; j < 256; j++) { + if (this->glyph_to_sprite[i][j].duplicate) continue; + free(this->glyph_to_sprite[i][j].sprite); + } + + free(this->glyph_to_sprite[i]); + } + + free(this->glyph_to_sprite); + this->glyph_to_sprite = nullptr; + + Layouter::ResetFontCache(this->fs); +} + + +TrueTypeFontCache::GlyphEntry *TrueTypeFontCache::GetGlyphPtr(GlyphID key) +{ + if (this->glyph_to_sprite == nullptr) return nullptr; + if (this->glyph_to_sprite[GB(key, 8, 8)] == nullptr) return nullptr; + return &this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)]; +} + +void TrueTypeFontCache::SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate) +{ + if (this->glyph_to_sprite == nullptr) { + Debug(fontcache, 3, "Allocating root glyph cache for size {}", this->fs); + this->glyph_to_sprite = CallocT(256); + } + + if (this->glyph_to_sprite[GB(key, 8, 8)] == nullptr) { + Debug(fontcache, 3, "Allocating glyph cache for range 0x{:02X}00, size {}", GB(key, 8, 8), this->fs); + this->glyph_to_sprite[GB(key, 8, 8)] = CallocT(256); + } + + Debug(fontcache, 4, "Set glyph for unicode character 0x{:04X}, size {}", key, this->fs); + this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].sprite = glyph->sprite; + this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].width = glyph->width; + this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)].duplicate = duplicate; +} + +bool TrueTypeFontCache::GetDrawGlyphShadow() +{ + return this->fs == FS_NORMAL && GetFontAAState(FS_NORMAL); +} + +uint TrueTypeFontCache::GetGlyphWidth(GlyphID key) +{ + if ((key & SPRITE_GLYPH) != 0) return this->parent->GetGlyphWidth(key); + + GlyphEntry *glyph = this->GetGlyphPtr(key); + if (glyph == nullptr || glyph->sprite == nullptr) { + this->GetGlyph(key); + glyph = this->GetGlyphPtr(key); + } + + return glyph->width; +} + +const Sprite *TrueTypeFontCache::GetGlyph(GlyphID key) +{ + if ((key & SPRITE_GLYPH) != 0) return this->parent->GetGlyph(key); + + /* Check for the glyph in our cache */ + GlyphEntry *glyph = this->GetGlyphPtr(key); + if (glyph != nullptr && glyph->sprite != nullptr) return glyph->sprite; + + if (key == 0) { + GlyphID question_glyph = this->MapCharToGlyph('?'); + if (question_glyph == 0) { + /* The font misses the '?' character. Use built-in sprite. + * Note: We cannot use the baseset as this also has to work in the bootstrap GUI. */ +#define CPSET { 0, 0, 0, 0, 1 } +#define CP___ { 0, 0, 0, 0, 0 } + static SpriteLoader::CommonPixel builtin_questionmark_data[10 * 8] = { + CP___, CP___, CPSET, CPSET, CPSET, CPSET, CP___, CP___, + CP___, CPSET, CPSET, CP___, CP___, CPSET, CPSET, CP___, + CP___, CP___, CP___, CP___, CP___, CPSET, CPSET, CP___, + CP___, CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, + CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___, + CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___, + CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___, + CP___, CP___, CP___, CP___, CP___, CP___, CP___, CP___, + CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___, + CP___, CP___, CP___, CPSET, CPSET, CP___, CP___, CP___, + }; +#undef CPSET +#undef CP___ + static const SpriteLoader::Sprite builtin_questionmark = { + 10, // height + 8, // width + 0, // x_offs + 0, // y_offs + ST_FONT, + SCC_PAL, + builtin_questionmark_data + }; + + Sprite *spr = BlitterFactory::GetCurrentBlitter()->Encode(&builtin_questionmark, SimpleSpriteAlloc); + assert(spr != nullptr); + GlyphEntry new_glyph; + new_glyph.sprite = spr; + new_glyph.width = spr->width + (this->fs != FS_NORMAL); + this->SetGlyphPtr(key, &new_glyph, false); + return new_glyph.sprite; + } else { + /* Use '?' for missing characters. */ + this->GetGlyph(question_glyph); + glyph = this->GetGlyphPtr(question_glyph); + this->SetGlyphPtr(key, glyph, true); + return glyph->sprite; + } + } + + return this->InternalGetGlyph(key, GetFontAAState(this->fs)); +} + +const void *TrueTypeFontCache::GetFontTable(uint32 tag, size_t &length) +{ + const FontTable::iterator iter = this->font_tables.Find(tag); + if (iter != this->font_tables.data() + this->font_tables.size()) { + length = iter->second.first; + return iter->second.second; + } + + const void *result = this->InternalGetFontTable(tag, length); + + this->font_tables.Insert(tag, std::pair(length, result)); + return result; +} diff --git a/src/fontcache_internal.h b/src/fontcache/truetypefontcache.h similarity index 90% rename from src/fontcache_internal.h rename to src/fontcache/truetypefontcache.h index acae3d71de13b..f8ef4239098bb 100644 --- a/src/fontcache_internal.h +++ b/src/fontcache/truetypefontcache.h @@ -5,13 +5,13 @@ * 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 fontcache_internal.h Support types and functions for platform-specific font support. */ +/** @file truetypefontcache.h Common base definition for font file based font caches. */ -#ifndef FONTCACHE_INTERNAL_H -#define FONTCACHE_INTERNAL_H +#ifndef TRUETYPEFONTCACHE_H +#define TRUETYPEFONTCACHE_H -#include "core/smallmap_type.hpp" -#include "fontcache.h" +#include "../core/smallmap_type.hpp" +#include "../fontcache.h" static const int MAX_FONT_SIZE = 72; ///< Maximum font size. @@ -63,7 +63,6 @@ class TrueTypeFontCache : public FontCache { TrueTypeFontCache(FontSize fs, int pixels); virtual ~TrueTypeFontCache(); int GetFontSize() const override { return this->used_size; } - SpriteID GetUnicodeGlyph(WChar key) override { return this->parent->GetUnicodeGlyph(key); } void SetUnicodeGlyph(WChar key, SpriteID sprite) override { this->parent->SetUnicodeGlyph(key, sprite); } void InitializeUnicodeGlyphMap() override { this->parent->InitializeUnicodeGlyphMap(); } const Sprite *GetGlyph(GlyphID key) override; @@ -74,4 +73,4 @@ class TrueTypeFontCache : public FontCache { bool IsBuiltInFont() override { return false; } }; -#endif /* FONTCACHE_INTERNAL_H */ +#endif /* TRUETYPEFONTCACHE_H */ diff --git a/src/fontdetection.h b/src/fontdetection.h index 9cf39d2b07313..a0242fda1f31c 100644 --- a/src/fontdetection.h +++ b/src/fontdetection.h @@ -37,6 +37,6 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face); * @param callback The function to call to check for missing glyphs. * @return true if a font has been set, false otherwise. */ -bool SetFallbackFont(struct FreeTypeSettings *settings, const char *language_isocode, int winlangid, class MissingGlyphSearcher *callback); +bool SetFallbackFont(struct FontCacheSettings *settings, const char *language_isocode, int winlangid, class MissingGlyphSearcher *callback); #endif diff --git a/src/framerate_gui.cpp b/src/framerate_gui.cpp index 10776293628d2..1a676933ee591 100644 --- a/src/framerate_gui.cpp +++ b/src/framerate_gui.cpp @@ -25,8 +25,16 @@ #include "game/game_instance.hpp" #include "widgets/framerate_widget.h" + +#include +#include +#include + #include "safeguards.h" +static std::mutex _sound_perf_lock; +static std::atomic _sound_perf_pending; +static std::vector _sound_perf_measurements; /** * Private declarations for performance measurement implementation @@ -251,6 +259,20 @@ PerformanceMeasurer::~PerformanceMeasurer() return; } } + if (this->elem == PFE_SOUND) { + /* PFE_SOUND measurements are made from the mixer thread. + * _pf_data cannot be concurrently accessed from the mixer thread + * and the main thread, so store the measurement results in a + * mutex-protected queue which is drained by the main thread. + * See: ProcessPendingPerformanceMeasurements() */ + TimingMeasurement end = GetPerformanceTimer(); + std::lock_guard lk(_sound_perf_lock); + if (_sound_perf_measurements.size() >= NUM_FRAMERATE_POINTS * 2) return; + _sound_perf_measurements.push_back(this->start_time); + _sound_perf_measurements.push_back(end); + _sound_perf_pending.store(true, std::memory_order_release); + return; + } _pf_data[this->elem].Add(this->start_time, GetPerformanceTimer()); } @@ -358,16 +380,16 @@ static const NWidgetPart _framerate_window_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_GREY), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_VERTICAL), SetPadding(6), SetPIP(0, 3, 0), - NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_GAMELOOP), SetDataTip(STR_FRAMERATE_RATE_GAMELOOP, STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP), - NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_DRAWING), SetDataTip(STR_FRAMERATE_RATE_BLITTER, STR_FRAMERATE_RATE_BLITTER_TOOLTIP), - NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_FACTOR), SetDataTip(STR_FRAMERATE_SPEED_FACTOR, STR_FRAMERATE_SPEED_FACTOR_TOOLTIP), + NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.frametext), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), + NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_GAMELOOP), SetDataTip(STR_FRAMERATE_RATE_GAMELOOP, STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_DRAWING), SetDataTip(STR_FRAMERATE_RATE_BLITTER, STR_FRAMERATE_RATE_BLITTER_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_FACTOR), SetDataTip(STR_FRAMERATE_SPEED_FACTOR, STR_FRAMERATE_SPEED_FACTOR_TOOLTIP), SetFill(1, 0), SetResize(1, 0), EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_VERTICAL), SetPadding(6), SetPIP(0, 3, 0), - NWidget(NWID_HORIZONTAL), SetPIP(0, 6, 0), + NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.frametext), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_NAMES), SetScrollbar(WID_FRW_SCROLLBAR), NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_CURRENT), SetScrollbar(WID_FRW_SCROLLBAR), NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_AVERAGE), SetScrollbar(WID_FRW_SCROLLBAR), @@ -375,7 +397,7 @@ static const NWidgetPart _framerate_window_widgets[] = { NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_ALLOCSIZE), SetScrollbar(WID_FRW_SCROLLBAR), EndContainer(), EndContainer(), - NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_INFO_DATA_POINTS), SetDataTip(STR_FRAMERATE_DATA_POINTS, 0x0), + NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_INFO_DATA_POINTS), SetDataTip(STR_FRAMERATE_DATA_POINTS, 0x0), SetFill(1, 0), SetResize(1, 0), EndContainer(), EndContainer(), NWidget(NWID_VERTICAL), @@ -425,7 +447,6 @@ struct FramerateWindow : Window { CachedDecimal times_shortterm[PFE_MAX]; ///< cached short term average times CachedDecimal times_longterm[PFE_MAX]; ///< cached long term average times - static constexpr int VSPACING = 3; ///< space between column heading and values static constexpr int MIN_ELEMENTS = 5; ///< smallest number of elements to display FramerateWindow(WindowDesc *desc, WindowNumber number) : Window(desc) @@ -545,7 +566,7 @@ struct FramerateWindow : Window { case WID_FRW_TIMES_NAMES: { size->width = 0; - size->height = FONT_HEIGHT_NORMAL + VSPACING + MIN_ELEMENTS * FONT_HEIGHT_NORMAL; + size->height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal + MIN_ELEMENTS * FONT_HEIGHT_NORMAL; resize->width = 0; resize->height = FONT_HEIGHT_NORMAL; for (PerformanceElement e : DISPLAY_ORDER_PFE) { @@ -571,7 +592,7 @@ struct FramerateWindow : Window { SetDParam(1, 2); Dimension item_size = GetStringBoundingBox(STR_FRAMERATE_MS_GOOD); size->width = std::max(size->width, item_size.width); - size->height += FONT_HEIGHT_NORMAL * MIN_ELEMENTS + VSPACING; + size->height += FONT_HEIGHT_NORMAL * MIN_ELEMENTS + WidgetDimensions::scaled.vsep_normal; resize->width = 0; resize->height = FONT_HEIGHT_NORMAL; break; @@ -587,7 +608,7 @@ struct FramerateWindow : Window { int drawable = this->num_displayed; int y = r.top; DrawString(r.left, r.right, y, heading_str, TC_FROMSTRING, SA_CENTER, true); - y += FONT_HEIGHT_NORMAL + VSPACING; + y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; for (PerformanceElement e : DISPLAY_ORDER_PFE) { if (_pf_data[e].num_valid == 0) continue; if (skip > 0) { @@ -609,7 +630,7 @@ struct FramerateWindow : Window { int drawable = this->num_displayed; int y = r.top; DrawString(r.left, r.right, y, STR_FRAMERATE_MEMORYUSE, TC_FROMSTRING, SA_CENTER, true); - y += FONT_HEIGHT_NORMAL + VSPACING; + y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; for (PerformanceElement e : DISPLAY_ORDER_PFE) { if (_pf_data[e].num_valid == 0) continue; if (skip > 0) { @@ -641,7 +662,7 @@ struct FramerateWindow : Window { const Scrollbar *sb = this->GetScrollbar(WID_FRW_SCROLLBAR); uint16 skip = sb->GetPosition(); int drawable = this->num_displayed; - int y = r.top + FONT_HEIGHT_NORMAL + VSPACING; // first line contains headings in the value columns + int y = r.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; // first line contains headings in the value columns for (PerformanceElement e : DISPLAY_ORDER_PFE) { if (_pf_data[e].num_valid == 0) continue; if (skip > 0) { @@ -683,7 +704,7 @@ struct FramerateWindow : Window { case WID_FRW_TIMES_AVERAGE: { /* Open time graph windows when clicking detail measurement lines */ const Scrollbar *sb = this->GetScrollbar(WID_FRW_SCROLLBAR); - int line = sb->GetScrolledRowFromWidget(pt.y, this, widget, VSPACING + FONT_HEIGHT_NORMAL); + int line = sb->GetScrolledRowFromWidget(pt.y, this, widget, WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL); if (line != INT_MAX) { line++; /* Find the visible line that was clicked */ @@ -703,7 +724,7 @@ struct FramerateWindow : Window { void OnResize() override { auto *wid = this->GetWidget(WID_FRW_TIMES_NAMES); - this->num_displayed = (wid->current_y - wid->min_y - VSPACING) / FONT_HEIGHT_NORMAL - 1; // subtract 1 for headings + this->num_displayed = (wid->current_y - wid->min_y - WidgetDimensions::scaled.vsep_normal) / FONT_HEIGHT_NORMAL - 1; // subtract 1 for headings this->GetScrollbar(WID_FRW_SCROLLBAR)->SetCapacity(this->num_displayed); } }; @@ -965,7 +986,7 @@ struct FrametimeGraphWindow : Window { (int)Scinterlate(x_zero, x_max, 0, (int64)draw_horz_scale, (int64)draw_horz_scale - (int64)time_sum), (int)Scinterlate(y_zero, y_max, 0, (int64)draw_vert_scale, (int64)value) }; - assert(newpoint.x <= lastpoint.x); + if (newpoint.x > lastpoint.x) continue; // don't draw backwards GfxDrawLine(lastpoint.x, lastpoint.y, newpoint.x, newpoint.y, c_lines); lastpoint = newpoint; @@ -1079,3 +1100,22 @@ void ConPrintFramerate() IConsolePrint(CC_ERROR, "No performance measurements have been taken yet."); } } + +/** + * This drains the PFE_SOUND measurement data queue into _pf_data. + * PFE_SOUND measurements are made by the mixer thread and so cannot be stored + * into _pf_data directly, because this would not be thread safe and would violate + * the invariants of the FPS and frame graph windows. + * @see PerformanceMeasurement::~PerformanceMeasurement() + */ +void ProcessPendingPerformanceMeasurements() +{ + if (_sound_perf_pending.load(std::memory_order_acquire)) { + std::lock_guard lk(_sound_perf_lock); + for (size_t i = 0; i < _sound_perf_measurements.size(); i += 2) { + _pf_data[PFE_SOUND].Add(_sound_perf_measurements[i], _sound_perf_measurements[i + 1]); + } + _sound_perf_measurements.clear(); + _sound_perf_pending.store(false, std::memory_order_relaxed); + } +} diff --git a/src/framerate_type.h b/src/framerate_type.h index 1fa6e35ac86e0..f0116d8182b44 100644 --- a/src/framerate_type.h +++ b/src/framerate_type.h @@ -121,5 +121,6 @@ class PerformanceAccumulator { }; void ShowFramerateWindow(); +void ProcessPendingPerformanceMeasurements(); #endif /* FRAMERATE_TYPE_H */ diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index aafb5a7b8d22f..3f25e9bbe5eb6 100644 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -3,6 +3,8 @@ add_files( game_config.cpp game_config.hpp game_core.cpp + game_gui.cpp + game_gui.hpp game_info.cpp game_info.hpp game_instance.cpp diff --git a/src/game/game.hpp b/src/game/game.hpp index 8381a6c148270..fffa04fa059f2 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -12,10 +12,6 @@ #include "../core/string_compare_type.hpp" #include "game_scanner.hpp" -#include - -/** A list that maps AI names to their AIInfo object. */ -typedef std::map ScriptInfoList; #include "../script/api/script_event_types.hpp" @@ -87,15 +83,10 @@ class Game { */ static void Save(); - /** - * Load data for a GameScript from a savegame. - */ - static void Load(int version); - /** Wrapper function for GameScanner::GetConsoleList */ - static char *GetConsoleList(char *p, const char *last, bool newest_only = false); + static std::string GetConsoleList(bool newest_only = false); /** Wrapper function for GameScanner::GetConsoleLibraryList */ - static char *GetConsoleLibraryList(char *p, const char *last); + static std::string GetConsoleLibraryList(); /** Wrapper function for GameScanner::GetInfoList */ static const ScriptInfoList *GetInfoList(); /** Wrapper function for GameScanner::GetUniqueInfoList */ diff --git a/src/game/game_core.cpp b/src/game/game_core.cpp index 19d8bbf54efcc..a4e1e64ddcb01 100644 --- a/src/game/game_core.cpp +++ b/src/game/game_core.cpp @@ -73,6 +73,9 @@ { if (Game::instance != nullptr) return; + /* Don't start GameScripts in intro */ + if (_game_mode == GM_MENU) return; + /* Clients shouldn't start GameScripts */ if (_networking && !_network_server) return; @@ -88,10 +91,12 @@ Game::info = info; Game::instance = new GameInstance(); Game::instance->Initialize(info); + Game::instance->LoadOnStack(config->GetToLoadData()); + config->SetToLoadData(nullptr); cur_company.Restore(); - InvalidateWindowData(WC_AI_DEBUG, 0, -1); + InvalidateWindowData(WC_SCRIPT_DEBUG, 0, -1); } /* static */ void Game::Uninitialize(bool keepConfig) @@ -196,9 +201,10 @@ Game::scanner_library->RescanDir(); ResetConfig(); - InvalidateWindowData(WC_AI_LIST, 0, 1); - SetWindowClassesDirty(WC_AI_DEBUG); - InvalidateWindowClassesData(WC_AI_SETTINGS); + InvalidateWindowData(WC_SCRIPT_LIST, 0, 1); + SetWindowClassesDirty(WC_SCRIPT_DEBUG); + InvalidateWindowClassesData(WC_SCRIPT_SETTINGS); + InvalidateWindowClassesData(WC_GAME_OPTIONS); } @@ -213,26 +219,14 @@ } } -/* static */ void Game::Load(int version) -{ - if (Game::instance != nullptr && (!_networking || _network_server)) { - Backup cur_company(_current_company, OWNER_DEITY, FILE_LINE); - Game::instance->Load(version); - cur_company.Restore(); - } else { - /* Read, but ignore, the load data */ - GameInstance::LoadEmpty(); - } -} - -/* static */ char *Game::GetConsoleList(char *p, const char *last, bool newest_only) +/* static */ std::string Game::GetConsoleList(bool newest_only) { - return Game::scanner_info->GetConsoleList(p, last, newest_only); + return Game::scanner_info->GetConsoleList(newest_only); } -/* static */ char *Game::GetConsoleLibraryList(char *p, const char *last) +/* static */ std::string Game::GetConsoleLibraryList() { - return Game::scanner_library->GetConsoleList(p, last, true); + return Game::scanner_library->GetConsoleList(true); } /* static */ const ScriptInfoList *Game::GetInfoList() diff --git a/src/game/game_gui.cpp b/src/game/game_gui.cpp new file mode 100644 index 0000000000000..566a219b20391 --- /dev/null +++ b/src/game/game_gui.cpp @@ -0,0 +1,441 @@ +/* + * 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 game_gui.cpp %Window for configuring the Game Script */ + +#include "../stdafx.h" +#include "../error.h" +#include "../settings_gui.h" +#include "../querystring_gui.h" +#include "../window_func.h" +#include "../network/network.h" +#include "../network/network_content.h" +#include "../widgets/dropdown_func.h" + +#include "game.hpp" +#include "game_gui.hpp" +#include "game_config.hpp" +#include "game_info.hpp" +#include "../script/script_gui.h" +#include "../script_config.hpp" +#include "../table/strings.h" + +#include "../safeguards.h" + + +/** Widgets for the configure GS window. */ +static const NWidgetPart _nested_gs_config_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), + NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_CAPTION_GAMESCRIPT, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_MAUVE, WID_GSC_BACKGROUND), SetFill(1, 0), SetResize(1, 0), + NWidget(NWID_SPACER), SetMinimalSize(0, 3), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_GAMESCRIPT, STR_NULL), SetFill(1, 0), SetResize(1, 0), SetPadding(0, 5, 4, 5), + NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_GSC_GSLIST), SetMinimalSize(288, 14), SetFill(1, 0), SetResize(1, 0), SetMatrixDataTip(1, 1, STR_AI_CONFIG_GAMELIST_TOOLTIP), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 6), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_GAMESCRIPT_PARAM, STR_NULL), SetFill(1, 0), SetResize(1, 0), SetPadding(0, 5, 4, 5), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_GSC_SETTINGS), SetFill(1, 0), SetResize(1, 1), SetMinimalSize(188, 182), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_GSC_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_GSC_SCROLLBAR), + EndContainer(), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GSC_CHANGE), SetFill(1, 0), SetResize(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_CONFIG_CHANGE_GAMESCRIPT, STR_AI_CONFIG_CHANGE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GSC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GSC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GSC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL), + EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GSC_CONTENT_DOWNLOAD), SetFill(1, 0), SetResize(1, 0), SetMinimalSize(279, 0), SetPadding(0, 7, 9, 7), SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GSC_ACCEPT), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GSC_RESET), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_AI_SETTINGS_RESET, STR_NULL), + EndContainer(), + NWidget(WWT_RESIZEBOX, COLOUR_MAUVE), + EndContainer(), +}; + +/** Window definition for the configure GS window. */ +static WindowDesc _gs_config_desc( + WDP_CENTER, "settings_gs_config", 500, 350, + WC_GAME_OPTIONS, WC_NONE, + 0, + _nested_gs_config_widgets, lengthof(_nested_gs_config_widgets) +); + +/** + * Window to configure which GSs will start. + */ +struct GSConfigWindow : public Window { + ScriptConfig *gs_config; ///< The configuration we're modifying. + int line_height; ///< Height of a single GS-name line. + int clicked_button; ///< The button we clicked. + bool clicked_increase; ///< Whether we clicked the increase or decrease button. + bool clicked_dropdown; ///< Whether the dropdown is open. + bool closing_dropdown; ///< True, if the dropdown list is currently closing. + GUITimer timeout; ///< Timeout for unclicking the button. + int clicked_row; ///< The clicked row of settings. + Scrollbar *vscroll; ///< Cache of the vertical scrollbar. + typedef std::vector VisibleSettingsList; ///< typdef for a vector of script settings + VisibleSettingsList visible_settings; ///< List of visible GS settings + + GSConfigWindow() : Window(&_gs_config_desc), + clicked_button(-1), + clicked_dropdown(false), + closing_dropdown(false), + timeout(0) + { + this->gs_config = GameConfig::GetConfig(); + + this->CreateNestedTree(); // Initializes 'this->line_height' as a side effect. + this->vscroll = this->GetScrollbar(WID_GSC_SCROLLBAR); + this->FinishInitNested(WN_GAME_OPTIONS_GS); + this->OnInvalidateData(0); + + this->RebuildVisibleSettings(); + } + + void Close() override + { + CloseWindowByClass(WC_SCRIPT_LIST); + this->Window::Close(); + } + + /** + * Rebuilds the list of visible settings. GS settings with the flag + * GSCONFIG_GS_DEVELOPER set will only be visible if the game setting + * gui.ai_developer_tools is enabled. + */ + void RebuildVisibleSettings() + { + visible_settings.clear(); + + for (const auto &item : *this->gs_config->GetConfigList()) { + bool no_hide = (item.flags & SCRIPTCONFIG_DEVELOPER) == 0; + if (no_hide || _settings_client.gui.ai_developer_tools) { + visible_settings.push_back(&item); + } + } + + this->vscroll->SetCount((int)this->visible_settings.size()); + } + + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override + { + switch (widget) { + case WID_GSC_SETTINGS: + this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + padding.height; + resize->width = 1; + resize->height = this->line_height; + size->height = 5 * this->line_height; + break; + + case WID_GSC_GSLIST: + this->line_height = FONT_HEIGHT_NORMAL + padding.height; + size->height = 1 * this->line_height; + break; + } + } + + /** + * Can the GS config be edited? + * @return True if the given GS Config slot can be edited, otherwise false. + */ + static bool IsEditable() + { + return _game_mode != GM_NORMAL || Game::GetInstance() != nullptr; + } + + void DrawWidget(const Rect &r, int widget) const override + { + switch (widget) { + case WID_GSC_GSLIST: { + StringID text = STR_AI_CONFIG_NONE; + + if (GameConfig::GetConfig()->GetInfo() != nullptr) { + SetDParamStr(0, GameConfig::GetConfig()->GetInfo()->GetName()); + text = STR_JUST_RAW_STRING; + } + + /* There is only one slot, unlike with the GS GUI, so it should never be white */ + DrawString(r.Shrink(WidgetDimensions::scaled.matrix), text, (IsEditable() ? TC_ORANGE : TC_SILVER)); + break; + } + case WID_GSC_SETTINGS: { + ScriptConfig *config = this->gs_config; + VisibleSettingsList::const_iterator it = this->visible_settings.begin(); + int i = 0; + for (; !this->vscroll->IsVisible(i); i++) it++; + + Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); + bool rtl = _current_text_dir == TD_RTL; + Rect br = ir.WithWidth(SETTING_BUTTON_WIDTH, rtl); + Rect tr = ir.Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide, rtl); + + int y = r.top; + int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; + int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; + for (; this->vscroll->IsVisible(i) && it != visible_settings.end(); i++, it++) { + const ScriptConfigItem &config_item = **it; + int current_value = config->GetSetting((config_item).name); + bool editable = this->IsEditableItem(config_item); + + StringID str; + TextColour colour; + uint idx = 0; + if (StrEmpty(config_item.description)) { + str = STR_JUST_STRING; + colour = TC_ORANGE; + } else { + str = STR_AI_SETTINGS_SETTING; + colour = TC_LIGHT_BLUE; + SetDParamStr(idx++, config_item.description); + } + + if ((config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0) { + DrawBoolButton(br.left, y + button_y_offset, current_value != 0, editable); + SetDParam(idx++, current_value == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON); + } else { + if (config_item.complete_labels) { + DrawDropDownButton(br.left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && clicked_dropdown, editable); + } else { + DrawArrowButtons(br.left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value); + } + if (config_item.labels != nullptr && config_item.labels->Contains(current_value)) { + SetDParam(idx++, STR_JUST_RAW_STRING); + SetDParamStr(idx++, config_item.labels->Find(current_value)->second); + } else { + SetDParam(idx++, STR_JUST_INT); + SetDParam(idx++, current_value); + } + } + + DrawString(tr.left, tr.right, y + text_y_offset, str, colour); + y += this->line_height; + } + break; + } + } + } + + void OnPaint() override + { + if (this->closing_dropdown) { + this->closing_dropdown = false; + this->clicked_dropdown = false; + } + this->DrawWidgets(); + } + + void OnClick(Point pt, int widget, int click_count) override + { + if (widget >= WID_GSC_TEXTFILE && widget < WID_GSC_TEXTFILE + TFT_END) { + if (GameConfig::GetConfig() == nullptr) return; + + ShowScriptTextfileWindow((TextfileType)(widget - WID_GSC_TEXTFILE), (CompanyID)OWNER_DEITY); + return; + } + + switch (widget) { + case WID_GSC_GSLIST: { + this->InvalidateData(); + if (click_count > 1 && _game_mode != GM_NORMAL) ShowScriptListWindow((CompanyID)OWNER_DEITY); + break; + } + + case WID_GSC_CHANGE: // choose other Game Script + ShowScriptListWindow((CompanyID)OWNER_DEITY); + break; + + case WID_GSC_CONTENT_DOWNLOAD: + if (!_network_available) { + ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR); + } else { + ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_GAME); + } + break; + + case WID_GSC_SETTINGS: { + Rect r = this->GetWidget(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix, RectPadding::zero); + int num = (pt.y - r.top) / this->line_height + this->vscroll->GetPosition(); + if (num >= (int)this->visible_settings.size()) break; + + VisibleSettingsList::const_iterator it = this->visible_settings.begin(); + for (int i = 0; i < num; i++) it++; + const ScriptConfigItem config_item = **it; + if (!this->IsEditableItem(config_item)) return; + + if (this->clicked_row != num) { + this->CloseChildWindows(WC_QUERY_STRING); + HideDropDownMenu(this); + this->clicked_row = num; + this->clicked_dropdown = false; + } + + bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0; + + int x = pt.x - r.left; + if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x; + + /* One of the arrows is clicked (or green/red rect in case of bool value) */ + int old_val = this->gs_config->GetSetting(config_item.name); + if (!bool_item && IsInsideMM(x, 0, SETTING_BUTTON_WIDTH) && config_item.complete_labels) { + if (this->clicked_dropdown) { + /* unclick the dropdown */ + HideDropDownMenu(this); + this->clicked_dropdown = false; + this->closing_dropdown = false; + } else { + int rel_y = (pt.y - r.top) % this->line_height; + + Rect wi_rect; + wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x); + wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1; + wi_rect.top = pt.y - rel_y + (this->line_height - SETTING_BUTTON_HEIGHT) / 2; + wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1; + + /* If the mouse is still held but dragged outside of the dropdown list, keep the dropdown open */ + if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) { + this->clicked_dropdown = true; + this->closing_dropdown = false; + + DropDownList list; + for (int i = config_item.min_value; i <= config_item.max_value; i++) { + list.emplace_back(new DropDownListCharStringItem(config_item.labels->Find(i)->second, i, false)); + } + + ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE, true); + } + } + } else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) { + int new_val = old_val; + if (bool_item) { + new_val = !new_val; + } else if (x >= SETTING_BUTTON_WIDTH / 2) { + /* Increase button clicked */ + new_val += config_item.step_size; + if (new_val > config_item.max_value) new_val = config_item.max_value; + this->clicked_increase = true; + } else { + /* Decrease button clicked */ + new_val -= config_item.step_size; + if (new_val < config_item.min_value) new_val = config_item.min_value; + this->clicked_increase = false; + } + + if (new_val != old_val) { + this->gs_config->SetSetting(config_item.name, new_val); + this->clicked_button = num; + this->timeout.SetInterval(150); + } + } else if (!bool_item && !config_item.complete_labels) { + /* Display a query box so users can enter a custom value. */ + SetDParam(0, old_val); + ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, INT32_DIGITS_WITH_SIGN_AND_TERMINATION, this, CS_NUMERAL_SIGNED, QSF_NONE); + } + this->SetDirty(); + break; + } + + case WID_GSC_ACCEPT: + this->Close(); + break; + + case WID_GSC_RESET: + this->gs_config->ResetEditableSettings(_game_mode == GM_MENU); + this->SetDirty(); + break; + } + } + + void OnQueryTextFinished(char *str) override + { + if (StrEmpty(str)) return; + int32 value = atoi(str); + SetValue(value); + } + + void OnDropdownSelect(int widget, int index) override + { + assert(this->clicked_dropdown); + SetValue(index); + } + + void OnDropdownClose(Point pt, int widget, int index, bool instant_close) override + { + /* We cannot raise the dropdown button just yet. OnClick needs some hint, whether + * the same dropdown button was clicked again, and then not open the dropdown again. + * So, we only remember that it was closed, and process it on the next OnPaint, which is + * after OnClick. */ + assert(this->clicked_dropdown); + this->closing_dropdown = true; + this->SetDirty(); + } + + void OnResize() override + { + this->vscroll->SetCapacityFromWidget(this, WID_GSC_SETTINGS); + } + + void OnRealtimeTick(uint delta_ms) override + { + if (this->timeout.Elapsed(delta_ms)) { + this->clicked_button = -1; + this->SetDirty(); + } + } + + /** + * Some data on this window has become invalid. + * @param data Information about the changed data. + * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. + */ + void OnInvalidateData(int data = 0, bool gui_scope = true) override + { + if (!gui_scope) return; + + this->SetWidgetDisabledState(WID_GSC_CHANGE, (_game_mode == GM_NORMAL) || !IsEditable()); + + for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) { + this->SetWidgetDisabledState(WID_GSC_TEXTFILE + tft, GameConfig::GetConfig()->GetTextfile(tft, (CompanyID)OWNER_DEITY) == nullptr); + } + this->RebuildVisibleSettings(); + HideDropDownMenu(this); + this->CloseChildWindows(WC_QUERY_STRING); + } +private: + bool IsEditableItem(const ScriptConfigItem &config_item) const + { + return _game_mode == GM_MENU + || _game_mode == GM_EDITOR + || (config_item.flags & SCRIPTCONFIG_INGAME) != 0 + || _settings_client.gui.ai_developer_tools; + } + + void SetValue(int value) + { + VisibleSettingsList::const_iterator it = this->visible_settings.begin(); + for (int i = 0; i < this->clicked_row; i++) it++; + const ScriptConfigItem config_item = **it; + if (_game_mode == GM_NORMAL && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return; + this->gs_config->SetSetting(config_item.name, value); + this->SetDirty(); + } +}; + +/** Open the GS config window. */ +void ShowGSConfigWindow() +{ + CloseWindowByClass(WC_GAME_OPTIONS); + new GSConfigWindow(); +} diff --git a/src/game/game_gui.hpp b/src/game/game_gui.hpp new file mode 100644 index 0000000000000..d0159a00d56f3 --- /dev/null +++ b/src/game/game_gui.hpp @@ -0,0 +1,15 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute itand /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 < http://www.gnu.org/licenses/>. + */ + +/** @file game_gui.hpp %Window for configuring the Games */ + +#ifndef GAME_GUI_HPP +#define GAME_GUI_HPP + +void ShowGSConfigWindow(); + +#endif /* AI_GUI_HPP */ diff --git a/src/game/game_info.cpp b/src/game/game_info.cpp index 5f7ba259b629d..4d28cf8c7a38a 100644 --- a/src/game/game_info.cpp +++ b/src/game/game_info.cpp @@ -23,7 +23,7 @@ */ static bool CheckAPIVersion(const char *api_version) { - static const std::set versions = { "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "12", "13" }; + static const std::set versions = { "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "12", "13", "14" }; return versions.find(api_version) != versions.end(); } diff --git a/src/game/game_instance.cpp b/src/game/game_instance.cpp index 09bba13345970..8fcc6252dee69 100644 --- a/src/game/game_instance.cpp +++ b/src/game/game_instance.cpp @@ -14,7 +14,7 @@ #include "../script/script_storage.hpp" #include "../script/script_cmd.h" -#include "../ai/ai_gui.hpp" +#include "../script/script_gui.h" #include "game_config.hpp" #include "game_info.hpp" #include "game_instance.hpp" @@ -67,7 +67,7 @@ void GameInstance::Died() { ScriptInstance::Died(); - ShowAIDebugWindow(OWNER_DEITY); + ShowScriptDebugWindow(OWNER_DEITY); const GameInfo *info = Game::GetInfo(); if (info != nullptr) { @@ -84,13 +84,12 @@ void GameInstance::Died() * DoCommand callback function for all commands executed by Game Scripts. * @param cmd cmd as given to DoCommandPInternal. * @param result The result of the command. - * @param tile The tile on which the command was executed. * @param data Command data as given to Command<>::Post. * @param result_data Additional returned data from the command. */ -void CcGame(Commands cmd, const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, CommandDataBuffer result_data) +void CcGame(Commands cmd, const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data) { - if (Game::GetGameInstance()->DoCommandCallback(result, tile, data, std::move(result_data), cmd)) { + if (Game::GetGameInstance()->DoCommandCallback(result, data, std::move(result_data), cmd)) { Game::GetGameInstance()->Continue(); } } diff --git a/src/game/game_text.cpp b/src/game/game_text.cpp index ca102f9120386..e3585de2e1653 100644 --- a/src/game/game_text.cpp +++ b/src/game/game_text.cpp @@ -19,6 +19,7 @@ #include "game_info.hpp" #include "table/strings.h" +#include "table/strgen_tables.h" #include #include @@ -225,6 +226,7 @@ class LanguageScanner : protected FileScanner { GameStrings *LoadTranslations() { const GameInfo *info = Game::GetInfo(); + assert(info != nullptr); std::string basename(info->GetMainScript()); auto e = basename.rfind(PATHSEPCHAR); if (e == std::string::npos) return nullptr; @@ -272,6 +274,31 @@ GameStrings *LoadTranslations() } } +static StringParam::ParamType GetParamType(const CmdStruct *cs) +{ + if (cs->value == SCC_RAW_STRING_POINTER) return StringParam::RAW_STRING; + if (cs->value == SCC_STRING || cs != TranslateCmdForCompare(cs)) return StringParam::STRING; + return StringParam::OTHER; +} + +static void ExtractStringParams(const StringData &data, StringParamsList ¶ms) +{ + for (size_t i = 0; i < data.max_strings; i++) { + const LangString *ls = data.strings[i]; + + if (ls != nullptr) { + StringParams ¶m = params.emplace_back(); + ParsedCommandStruct pcs; + ExtractCommandString(&pcs, ls->english, false); + + for (const CmdStruct *cs : pcs.cmd) { + if (cs == nullptr) break; + param.emplace_back(GetParamType(cs), cs->consumes); + } + } + } +} + /** Compile the language. */ void GameStrings::Compile() { @@ -282,6 +309,8 @@ void GameStrings::Compile() this->version = data.Version(); + ExtractStringParams(data, this->string_params); + StringNameWriter id_writer(this->string_names); id_writer.WriteHeader(data); @@ -311,6 +340,34 @@ const char *GetGameStringPtr(uint id) return _current_data->cur_language->lines[id].c_str(); } +/** + * Get the string parameters of a particular game string. + * @param id The ID of the game string. + * @return The string parameters. + */ +const StringParams &GetGameStringParams(uint id) +{ + /* An empty result for STR_UNDEFINED. */ + static StringParams empty; + + if (id >= _current_data->string_params.size()) return empty; + return _current_data->string_params[id]; +} + +/** + * Get the name of a particular game string. + * @param id The ID of the game string. + * @return The name of the string. + */ +const std::string &GetGameStringName(uint id) +{ + /* The name for STR_UNDEFINED. */ + static const std::string undefined = "STR_UNDEFINED"; + + if (id >= _current_data->string_names.size()) return undefined; + return _current_data->string_names[id]; +} + /** * Register the current translation to the Squirrel engine. * @param engine The engine to update/ diff --git a/src/game/game_text.hpp b/src/game/game_text.hpp index 91d85847df197..0f4c49698d2e1 100644 --- a/src/game/game_text.hpp +++ b/src/game/game_text.hpp @@ -12,7 +12,24 @@ #include "../core/smallvec_type.hpp" +struct StringParam { + enum ParamType { + RAW_STRING, + STRING, + OTHER + }; + + ParamType type; + uint8 consumes; + + StringParam(ParamType type, uint8 consumes) : type(type), consumes(consumes) {} +}; +using StringParams = std::vector; +using StringParamsList = std::vector; + const char *GetGameStringPtr(uint id); +const StringParams &GetGameStringParams(uint id); +const std::string &GetGameStringName(uint id); void RegisterGameTranslation(class Squirrel *engine); void ReconsiderGameScriptLanguage(); @@ -37,6 +54,7 @@ struct GameStrings { std::vector raw_strings; ///< The raw strings per language, first must be English/the master language!. std::vector compiled_strings; ///< The compiled strings per language, first must be English/the master language!. StringList string_names; ///< The names of the compiled strings. + StringParamsList string_params; ///< The parameters for the strings. void Compile(); diff --git a/src/gamelog.cpp b/src/gamelog.cpp index 7880d06e42246..0e251aae003c2 100644 --- a/src/gamelog.cpp +++ b/src/gamelog.cpp @@ -189,7 +189,7 @@ typedef SmallMap GrfIDMapping; * Prints active gamelog * @param proc the procedure to draw with */ -void GamelogPrint(GamelogPrintProc *proc) +void GamelogPrint(std::function proc) { char buffer[1024]; GrfIDMapping grf_names; @@ -212,11 +212,13 @@ void GamelogPrint(GamelogPrintProc *proc) switch (lc->ct) { default: NOT_REACHED(); case GLCT_MODE: + /* Changing landscape, or going from scenario editor to game or back. */ buf += seprintf(buf, lastof(buffer), "New game mode: %u landscape: %u", (uint)lc->mode.mode, (uint)lc->mode.landscape); break; case GLCT_REVISION: + /* The game was loaded in a diffferent version than before. */ buf += seprintf(buf, lastof(buffer), "Revision text changed to %s, savegame version %u, ", lc->revision.text, lc->revision.slver); @@ -230,6 +232,7 @@ void GamelogPrint(GamelogPrintProc *proc) break; case GLCT_OLDVER: + /* The game was loaded from before 0.7.0-beta1. */ buf += seprintf(buf, lastof(buffer), "Conversion from "); switch (lc->oldver.type) { default: NOT_REACHED(); @@ -260,10 +263,12 @@ void GamelogPrint(GamelogPrintProc *proc) break; case GLCT_SETTING: + /* A setting with the SF_NO_NETWORK flag got changed; these settings usually affect NewGRFs, such as road side or wagon speed limits. */ buf += seprintf(buf, lastof(buffer), "Setting changed: %s : %d -> %d", lc->setting.name, lc->setting.oldval, lc->setting.newval); break; case GLCT_GRFADD: { + /* A NewGRF got added to the game, either at the start of the game (never an issue), or later on when it could be an issue. */ const GRFConfig *gc = FindGRFConfig(lc->grfadd.grfid, FGCM_EXACT, lc->grfadd.md5sum); buf += seprintf(buf, lastof(buffer), "Added NewGRF: "); buf = PrintGrfInfo(buf, lastof(buffer), lc->grfadd.grfid, lc->grfadd.md5sum, gc); @@ -274,6 +279,7 @@ void GamelogPrint(GamelogPrintProc *proc) } case GLCT_GRFREM: { + /* A NewGRF got removed from the game, either manually or by it missing when loading the game. */ GrfIDMapping::Pair *gm = grf_names.Find(lc->grfrem.grfid); buf += seprintf(buf, lastof(buffer), la->at == GLAT_LOAD ? "Missing NewGRF: " : "Removed NewGRF: "); buf = PrintGrfInfo(buf, lastof(buffer), lc->grfrem.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); @@ -291,6 +297,7 @@ void GamelogPrint(GamelogPrintProc *proc) } case GLCT_GRFCOMPAT: { + /* Another version of the same NewGRF got loaded. */ const GRFConfig *gc = FindGRFConfig(lc->grfadd.grfid, FGCM_EXACT, lc->grfadd.md5sum); buf += seprintf(buf, lastof(buffer), "Compatible NewGRF loaded: "); buf = PrintGrfInfo(buf, lastof(buffer), lc->grfcompat.grfid, lc->grfcompat.md5sum, gc); @@ -300,6 +307,7 @@ void GamelogPrint(GamelogPrintProc *proc) } case GLCT_GRFPARAM: { + /* A parameter of a NewGRF got changed after the game was started. */ GrfIDMapping::Pair *gm = grf_names.Find(lc->grfrem.grfid); buf += seprintf(buf, lastof(buffer), "GRF parameter changed: "); buf = PrintGrfInfo(buf, lastof(buffer), lc->grfparam.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); @@ -308,6 +316,7 @@ void GamelogPrint(GamelogPrintProc *proc) } case GLCT_GRFMOVE: { + /* The order of NewGRFs got changed, which might cause some other NewGRFs to behave differently. */ GrfIDMapping::Pair *gm = grf_names.Find(lc->grfrem.grfid); buf += seprintf(buf, lastof(buffer), "GRF order changed: %08X moved %d places %s", BSWAP32(lc->grfmove.grfid), abs(lc->grfmove.offset), lc->grfmove.offset >= 0 ? "down" : "up" ); @@ -317,6 +326,7 @@ void GamelogPrint(GamelogPrintProc *proc) } case GLCT_GRFBUG: { + /* A specific bug in a NewGRF, that could cause wide spread problems, has been noted during the execution of the game. */ GrfIDMapping::Pair *gm = grf_names.Find(lc->grfrem.grfid); switch (lc->grfbug.bug) { default: NOT_REACHED(); @@ -330,6 +340,8 @@ void GamelogPrint(GamelogPrintProc *proc) } case GLCT_EMERGENCY: + /* At one point the savegame was made during the handling of a game crash. + * The generic code already mentioned the emergency savegame, and there is no extra information to log. */ break; } @@ -341,25 +353,14 @@ void GamelogPrint(GamelogPrintProc *proc) } -static void GamelogPrintConsoleProc(const char *s) -{ - IConsolePrint(CC_WARNING, s); -} - /** Print the gamelog data to the console. */ void GamelogPrintConsole() { - GamelogPrint(&GamelogPrintConsoleProc); -} - -static int _gamelog_print_level = 0; ///< gamelog debug level we need to print stuff - -static void GamelogPrintDebugProc(const char *s) -{ - Debug(gamelog, _gamelog_print_level, "{}", s); + GamelogPrint([](const char *s) { + IConsolePrint(CC_WARNING, s); + }); } - /** * Prints gamelog to debug output. Code is executed even when * there will be no output. It is called very seldom, so it @@ -368,8 +369,9 @@ static void GamelogPrintDebugProc(const char *s) */ void GamelogPrintDebug(int level) { - _gamelog_print_level = level; - GamelogPrint(&GamelogPrintDebugProc); + GamelogPrint([level](const char *s) { + Debug(gamelog, level, "{}", s); + }); } diff --git a/src/gamelog.h b/src/gamelog.h index cfa6c626a2713..0555ca5e77fb2 100644 --- a/src/gamelog.h +++ b/src/gamelog.h @@ -10,6 +10,7 @@ #ifndef GAMELOG_H #define GAMELOG_H +#include #include "newgrf_config.h" /** The actions we log. */ @@ -32,13 +33,7 @@ void GamelogStopAnyAction(); void GamelogFree(struct LoggedAction *gamelog_action, uint gamelog_actions); void GamelogReset(); -/** - * Callback for printing text. - * @param s The string to print. - */ -typedef void GamelogPrintProc(const char *s); -void GamelogPrint(GamelogPrintProc *proc); // needed for WIN32 crash.log - +void GamelogPrint(std::function proc); void GamelogPrintDebug(int level); void GamelogPrintConsole(); diff --git a/src/gamelog_internal.h b/src/gamelog_internal.h index ef72f280bf19f..95e4404b7b32b 100644 --- a/src/gamelog_internal.h +++ b/src/gamelog_internal.h @@ -81,7 +81,7 @@ struct LoggedAction { LoggedChange *change; ///< First logged change in this action uint32 changes; ///< Number of changes in this action GamelogActionType at; ///< Type of action - uint32 tick; ///< Tick when it happened + uint64 tick; ///< Tick when it happened }; extern LoggedAction *_gamelog_action; diff --git a/src/genworld.cpp b/src/genworld.cpp index 8ff7da064a280..4ae44b98eb063 100644 --- a/src/genworld.cpp +++ b/src/genworld.cpp @@ -96,6 +96,7 @@ static void _GenerateWorld() _random.SetSeed(_settings_game.game_creation.generation_seed); SetGeneratingWorldProgress(GWP_MAP_INIT, 2); SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0); + ScriptObject::InitializeRandomizers(); BasePersistentStorageArray::SwitchMode(PSM_ENTER_GAMELOOP); @@ -109,8 +110,8 @@ static void _GenerateWorld() /* Make sure the tiles at the north border are void tiles if needed. */ if (_settings_game.construction.freeform_edges) { - for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0)); - for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y)); + for (uint x = 0; x < Map::SizeX(); x++) MakeVoid(TileXY(x, 0)); + for (uint y = 0; y < Map::SizeY(); y++) MakeVoid(TileXY(0, y)); } /* Make the map the height of the setting */ @@ -321,9 +322,7 @@ void GenerateWorld(GenWorldMode mode, uint size_x, uint size_y, bool reset_setti ShowGenerateWorldProgress(); /* Centre the view on the map */ - if (FindWindowById(WC_MAIN_WINDOW, 0) != nullptr) { - ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2), true); - } + ScrollMainWindowToTile(TileXY(Map::SizeX() / 2, Map::SizeY() / 2), true); _GenerateWorld(); } diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 2489105c23e7b..6bb11658b7b90 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.cpp @@ -30,6 +30,9 @@ #include "newgrf_townname.h" #include "townname_type.h" #include "video/video_driver.hpp" +#include "ai/ai_gui.hpp" +#include "game/game_gui.hpp" +#include "industry.h" #include "widgets/genworld_widget.h" @@ -86,49 +89,55 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = { NWidget(NWID_SPACER), SetFill(1, 0), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 11), + /* Generation options. */ NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10), - NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), - /* Left column with labels. */ - NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_LAND_GENERATOR, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TERRAIN_TYPE, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_VARIETY, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_SEA_LAKES, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BORDER_TYPE, STR_NULL), SetFill(1, 1), - EndContainer(), - /* Widgets at the right of the labels. */ - NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), - /* Mapsize X * Y. */ - NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(1, 1), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0), + /* Left half (land generation options) */ + NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), + /* Labels on the left side (global column 1). */ + NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TERRAIN_TYPE, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_VARIETY, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SMOOTHNESS, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BORDER_TYPE, STR_NULL), SetFill(1, 1), + EndContainer(), + /* Widgets on the right side (global column 2). */ + NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), + /* Mapsize X * Y. */ + NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(1, 1), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0), + EndContainer(), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TERRAIN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_VARIETY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_SMOOTHNESS_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_BORDERS_RANDOM), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_LANDSCAPE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TERRAIN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_VARIETY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_WATER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_BORDERS_RANDOM), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), EndContainer(), - NWidget(NWID_VERTICAL), SetPIP(0, 4, 0), + /* Right half (all other options) */ + NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), + /* Labels on the left side (global column 3). */ NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_LABEL), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_COVERAGE, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DESERT_COVERAGE, STR_NULL), SetFill(1, 1), + NWidget(NWID_SPACER), EndContainer(), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SMOOTHNESS, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_GAME_OPTIONS_TOWN_NAMES_FRAME, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TOWN_NAME_LABEL, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SEA_LEVEL, STR_NULL), SetFill(1, 1), EndContainer(), + /* Widgets on the right side (global column 4). */ NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), + /* Climate selector. */ NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_SELECTOR), /* Snow coverage. */ NWidget(NWID_HORIZONTAL), @@ -142,6 +151,8 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = { NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_TEXT), SetDataTip(STR_MAPGEN_DESERT_COVERAGE_TEXT, STR_NULL), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_DESERT_COVERAGE_UP), SetFill(0, 1), EndContainer(), + /* Temperate/Toyland spacer. */ + NWidget(NWID_SPACER), EndContainer(), /* Starting date. */ NWidget(NWID_HORIZONTAL), @@ -149,12 +160,12 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = { NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1), EndContainer(), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_SMOOTHNESS_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_WATER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), EndContainer(), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 0), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetFill(1, 1), EndContainer(), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 4), @@ -183,6 +194,16 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = { NWidget(NWID_SPACER), SetFill(1, 1), EndContainer(), EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 6), SetFill(1, 1), + /* AI, GS, and NewGRF settings */ + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 0, 10), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_AI_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_AI_SETTINGS, STR_MAPGEN_AI_SETTINGS_TOOLTIP), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_GS_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_GS_SETTINGS, STR_MAPGEN_GS_SETTINGS_TOOLTIP), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_NEWGRF_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_NEWGRF_SETTINGS, STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP), SetFill(1, 0), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetFill(1, 1), + /* Generate */ + NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 36), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetPadding(0, 10, 0, 10), SetFill(1, 1), NWidget(NWID_SPACER), SetMinimalSize(0, 9), SetFill(1, 1), EndContainer(), }; @@ -209,21 +230,24 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = { NWidget(NWID_SPACER), SetFill(1, 0), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 11), SetFill(0, 1), + /* Generation options. */ NWidget(NWID_HORIZONTAL), SetPIP(10, 3, 10), - /* Labels at the left side. */ + /* Left half labels (global column 1) and heightmap name label */ NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), + /* Heightmap name label. */ NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_NAME, STR_NULL), SetFill(1, 1), + /* Land generation option labels */ NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_SIZE_LABEL, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_ROTATION, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_HEIGHT, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1), EndContainer(), - /* Widgets at the right of the labels. */ + /* All other columns. */ NWidget(NWID_VERTICAL), SetPIP(0, 4, 0), - NWidget(WWT_EMPTY, COLOUR_ORANGE, WID_GL_HEIGHTMAP_NAME_TEXT), SetFill(1, 0), + NWidget(WWT_TEXT, COLOUR_ORANGE, WID_GL_HEIGHTMAP_NAME_TEXT), SetTextColour(TC_ORANGE), SetDataTip(STR_JUST_RAW_STRING, STR_EMPTY), SetFill(1, 0), NWidget(NWID_HORIZONTAL), SetPIP(0, 5, 0), + /* Left half widgets (global column 2) */ NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), NWidget(WWT_TEXT, COLOUR_ORANGE, WID_GL_HEIGHTMAP_SIZE_TEXT), SetDataTip(STR_MAPGEN_HEIGHTMAP_SIZE, STR_NULL), SetFill(1, 0), /* Mapsize X * Y. */ @@ -233,52 +257,72 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = { NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_ROTATION_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + /* Heightmap highest peak. */ + NWidget(NWID_HORIZONTAL), + NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN), SetFill(0, 1), + NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0), + NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_HEIGHTMAP_HEIGHT_UP), SetFill(0, 1), + EndContainer(), NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), NWidget(NWID_VERTICAL), SetPIP(0, 4, 0), NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0), + /* Right half labels (global column 3) */ NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_HEIGHT, STR_NULL), SetFill(1, 1), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_LABEL), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_COVERAGE, STR_NULL), SetFill(1, 1), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DESERT_COVERAGE, STR_NULL), SetFill(1, 1), + NWidget(NWID_SPACER), EndContainer(), NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetFill(1, 1), - NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_GAME_OPTIONS_TOWN_NAMES_FRAME, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TOWN_NAME_LABEL, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1), + NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1), EndContainer(), + /* Right half widgets (global column 4) */ NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN), SetFill(0, 1), - NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0), - NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_HEIGHTMAP_HEIGHT_UP), SetFill(0, 1), - EndContainer(), + /* Climate selector. */ NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_SELECTOR), + /* Snow coverage. */ NWidget(NWID_HORIZONTAL), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_COVERAGE_DOWN), SetFill(0, 1), NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_TEXT), SetDataTip(STR_MAPGEN_SNOW_COVERAGE_TEXT, STR_NULL), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_COVERAGE_UP), SetFill(0, 1), EndContainer(), + /* Desert coverage. */ NWidget(NWID_HORIZONTAL), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_DESERT_COVERAGE_DOWN), SetFill(0, 1), NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_TEXT), SetDataTip(STR_MAPGEN_DESERT_COVERAGE_TEXT, STR_NULL), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_DESERT_COVERAGE_UP), SetFill(0, 1), EndContainer(), + /* Temperate/Toyland spacer. */ + NWidget(NWID_SPACER), EndContainer(), + /* Starting date. */ NWidget(NWID_HORIZONTAL), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD), SetFill(0, 1), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL), SetFill(1, 0), NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1), EndContainer(), - NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0), EndContainer(), EndContainer(), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 0), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetFill(1, 1), EndContainer(), EndContainer(), EndContainer(), EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 6), SetFill(1, 1), + /* AI, GS, and NewGRF settings */ + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 0, 10), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_AI_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_AI_SETTINGS, STR_MAPGEN_AI_SETTINGS_TOOLTIP), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_GS_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_GS_SETTINGS, STR_MAPGEN_GS_SETTINGS_TOOLTIP), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_NEWGRF_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_NEWGRF_SETTINGS, STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP), SetFill(1, 0), + EndContainer(), + NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetFill(1, 1), + /* Generate */ + NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 36), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetPadding(0, 10, 0, 10), SetFill(1, 1), NWidget(NWID_SPACER), SetMinimalSize(0, 9), SetFill(1, 1), EndContainer(), }; @@ -339,7 +383,7 @@ static DropDownList BuildTownNameDropDown() /* Add and sort original townnames generators */ for (uint i = 0; i < BUILTIN_TOWNNAME_GENERATOR_COUNT; i++) { - list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH + i, i, false)); + list.emplace_back(new DropDownListStringItem(STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + i, i, false)); } std::sort(list.begin() + newgrf_size, list.end(), DropDownListStringItem::NatSortFunc); @@ -352,9 +396,8 @@ static const StringID _sea_lakes[] = {STR_SEA_LEVEL_VERY_LOW, STR_SEA_LEVEL_LO static const StringID _rivers[] = {STR_RIVERS_NONE, STR_RIVERS_FEW, STR_RIVERS_MODERATE, STR_RIVERS_LOT, INVALID_STRING_ID}; static const StringID _smoothness[] = {STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_SMOOTH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_ROUGH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_ROUGH, INVALID_STRING_ID}; static const StringID _rotation[] = {STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE, STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_CLOCKWISE, INVALID_STRING_ID}; -static const StringID _landscape[] = {STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL, STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS, INVALID_STRING_ID}; static const StringID _num_towns[] = {STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, STR_NUM_CUSTOM, INVALID_STRING_ID}; -static const StringID _num_inds[] = {STR_FUNDING_ONLY, STR_MINIMAL, STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, INVALID_STRING_ID}; +static const StringID _num_inds[] = {STR_FUNDING_ONLY, STR_MINIMAL, STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, STR_NUM_CUSTOM, INVALID_STRING_ID}; static const StringID _variety[] = {STR_VARIETY_NONE, STR_VARIETY_VERY_LOW, STR_VARIETY_LOW, STR_VARIETY_MEDIUM, STR_VARIETY_HIGH, STR_VARIETY_VERY_HIGH, INVALID_STRING_ID}; static_assert(lengthof(_num_inds) == ID_END + 1); @@ -382,6 +425,11 @@ struct GenerateLandscapeWindow : public Window { _settings_newgame.game_creation.heightmap_height = Clamp(_settings_newgame.game_creation.heightmap_height, MIN_HEIGHTMAP_HEIGHT, GetMapHeightLimit()); _settings_newgame.game_creation.custom_terrain_type = Clamp(_settings_newgame.game_creation.custom_terrain_type, MIN_CUSTOM_TERRAIN_TYPE, GetMapHeightLimit()); + /* If original landgenerator is selected and alpinist terrain_type was selected, revert to mountainous. */ + if (_settings_newgame.game_creation.land_generator == LG_ORIGINAL) { + _settings_newgame.difficulty.terrain_type = Clamp(_settings_newgame.difficulty.terrain_type, 0, 3); + } + this->OnInvalidateData(); } @@ -410,14 +458,23 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_TOWNNAME_DROPDOWN: { uint gen = _settings_newgame.game_creation.town_name; StringID name = gen < BUILTIN_TOWNNAME_GENERATOR_COUNT ? - STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH + gen : + STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + gen : GetGRFTownNameName(gen - BUILTIN_TOWNNAME_GENERATOR_COUNT); SetDParam(0, name); break; } - case WID_GL_INDUSTRY_PULLDOWN: SetDParam(0, _game_mode == GM_EDITOR ? STR_CONFIG_SETTING_OFF : _num_inds[_settings_newgame.difficulty.industry_density]); break; - case WID_GL_LANDSCAPE_PULLDOWN: SetDParam(0, _landscape[_settings_newgame.game_creation.land_generator]); break; + case WID_GL_INDUSTRY_PULLDOWN: + if (_game_mode == GM_EDITOR) { + SetDParam(0, STR_CONFIG_SETTING_OFF); + } else if (_settings_newgame.difficulty.industry_density == ID_CUSTOM) { + SetDParam(0, STR_NUM_CUSTOM_NUMBER); + SetDParam(1, _settings_newgame.game_creation.custom_industry_number); + } else { + SetDParam(0, _num_inds[_settings_newgame.difficulty.industry_density]); + } + break; + case WID_GL_TERRAIN_PULLDOWN: if (_settings_newgame.difficulty.terrain_type == CUSTOM_TERRAIN_TYPE_NUMBER_DIFFICULTY) { SetDParam(0, STR_TERRAIN_TYPE_CUSTOM_VALUE); @@ -436,6 +493,7 @@ struct GenerateLandscapeWindow : public Window { } break; + case WID_GL_HEIGHTMAP_NAME_TEXT: SetDParamStr(0, this->name); break; case WID_GL_RIVER_PULLDOWN: SetDParam(0, _rivers[_settings_newgame.game_creation.amount_of_rivers]); break; case WID_GL_SMOOTHNESS_PULLDOWN: SetDParam(0, _smoothness[_settings_newgame.game_creation.tgen_smoothness]); break; case WID_GL_VARIETY_PULLDOWN: SetDParam(0, _variety[_settings_newgame.game_creation.variety]); break; @@ -499,10 +557,10 @@ struct GenerateLandscapeWindow : public Window { /* Set snow/rainforest selections */ int climate_plane = 0; switch (_settings_newgame.game_creation.landscape) { - case LT_TEMPERATE: climate_plane = SZSP_VERTICAL; break; - case LT_ARCTIC: climate_plane = 0; break; - case LT_TROPIC: climate_plane = 1; break; - case LT_TOYLAND: climate_plane = SZSP_VERTICAL; break; + case LT_TEMPERATE: climate_plane = 2; break; + case LT_ARCTIC: climate_plane = 0; break; + case LT_TROPIC: climate_plane = 1; break; + case LT_TOYLAND: climate_plane = 2; break; } this->GetWidget(WID_GL_CLIMATE_SEL_LABEL)->SetDisplayedPlane(climate_plane); this->GetWidget(WID_GL_CLIMATE_SEL_SELECTOR)->SetDisplayedPlane(climate_plane); @@ -573,8 +631,11 @@ struct GenerateLandscapeWindow : public Window { *size = maxdim(*size, GetStringBoundingBox(STR_NUM_CUSTOM_NUMBER)); break; - case WID_GL_INDUSTRY_PULLDOWN: strs = _num_inds; break; - case WID_GL_LANDSCAPE_PULLDOWN: strs = _landscape; break; + case WID_GL_INDUSTRY_PULLDOWN: + strs = _num_inds; + SetDParamMaxValue(0, IndustryPool::MAX_SIZE); + *size = maxdim(*size, GetStringBoundingBox(STR_NUM_CUSTOM_NUMBER)); + break; case WID_GL_TERRAIN_PULLDOWN: strs = _elevations; @@ -616,17 +677,7 @@ struct GenerateLandscapeWindow : public Window { } } size->width += padding.width; - size->height = std::max(size->height, (uint)(FONT_HEIGHT_NORMAL + WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM)); - } - - void DrawWidget(const Rect &r, int widget) const override - { - switch (widget) { - case WID_GL_HEIGHTMAP_NAME_TEXT: { - DrawString(r.left, r.right, r.top, this->name, TC_ORANGE); - break; - } - } + size->height = std::max(size->height, (uint)(FONT_HEIGHT_NORMAL + padding.height)); } void OnClick(Point pt, int widget, int click_count) override @@ -759,10 +810,6 @@ struct GenerateLandscapeWindow : public Window { ShowQueryString(STR_JUST_INT, STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT, 4, this, CS_NUMERAL, QSF_ENABLE_DEFAULT); break; - case WID_GL_LANDSCAPE_PULLDOWN: // Landscape generator - ShowDropDownMenu(this, _landscape, _settings_newgame.game_creation.land_generator, WID_GL_LANDSCAPE_PULLDOWN, 0, 0); - break; - case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: // Heightmap rotation ShowDropDownMenu(this, _rotation, _settings_newgame.game_creation.heightmap_rotation, WID_GL_HEIGHTMAP_ROTATION_PULLDOWN, 0, 0); break; @@ -819,6 +866,18 @@ struct GenerateLandscapeWindow : public Window { _settings_newgame.game_creation.water_borders = (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? 0 : BORDERS_RANDOM; this->InvalidateData(); break; + + case WID_GL_AI_BUTTON: ///< AI Settings + ShowAIConfigWindow(); + break; + + case WID_GL_GS_BUTTON: ///< Game Script Settings + ShowGSConfigWindow(); + break; + + case WID_GL_NEWGRF_BUTTON: ///< NewGRF Settings + ShowNewGRFSettings(true, true, false, &_grfconfig_newgame); + break; } } @@ -846,13 +905,6 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_SMOOTHNESS_PULLDOWN: _settings_newgame.game_creation.tgen_smoothness = index; break; case WID_GL_VARIETY_PULLDOWN: _settings_newgame.game_creation.variety = index; break; - case WID_GL_LANDSCAPE_PULLDOWN: _settings_newgame.game_creation.land_generator = index; - /* If original landgenerator is selected and alpinist terrain_type was selected, revert to mountainous. */ - if (_settings_newgame.game_creation.land_generator == LG_ORIGINAL) { - _settings_newgame.difficulty.terrain_type = Clamp(_settings_newgame.difficulty.terrain_type, 0, 3); - } - break; - case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: _settings_newgame.game_creation.heightmap_rotation = index; break; case WID_GL_TOWN_PULLDOWN: @@ -871,7 +923,15 @@ struct GenerateLandscapeWindow : public Window { } break; - case WID_GL_INDUSTRY_PULLDOWN: _settings_newgame.difficulty.industry_density = index; break; + case WID_GL_INDUSTRY_PULLDOWN: + if ((uint)index == ID_CUSTOM) { + this->widget_id = widget; + SetDParam(0, _settings_newgame.game_creation.custom_industry_number); + ShowQueryString(STR_JUST_INT, STR_MAPGEN_NUMBER_OF_INDUSTRIES, 5, this, CS_NUMERAL, QSF_NONE); + } + _settings_newgame.difficulty.industry_density = index; + break; + case WID_GL_TERRAIN_PULLDOWN: { if ((uint)index == CUSTOM_TERRAIN_TYPE_NUMBER_DIFFICULTY) { this->widget_id = widget; @@ -886,7 +946,7 @@ struct GenerateLandscapeWindow : public Window { if ((uint)index == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) { this->widget_id = widget; SetDParam(0, _settings_newgame.game_creation.custom_sea_level); - ShowQueryString(STR_JUST_INT, STR_MAPGEN_QUANTITY_OF_SEA_LAKES, 3, this, CS_NUMERAL, QSF_NONE); + ShowQueryString(STR_JUST_INT, STR_MAPGEN_SEA_LEVEL, 3, this, CS_NUMERAL, QSF_NONE); } _settings_newgame.difficulty.quantity_sea_lakes = index; break; @@ -911,6 +971,7 @@ struct GenerateLandscapeWindow : public Window { case WID_GL_SNOW_COVERAGE_TEXT: value = DEF_SNOW_COVERAGE; break; case WID_GL_DESERT_COVERAGE_TEXT: value = DEF_DESERT_COVERAGE; break; case WID_GL_TOWN_PULLDOWN: value = 1; break; + case WID_GL_INDUSTRY_PULLDOWN: value = 1; break; case WID_GL_TERRAIN_PULLDOWN: value = MIN_MAP_HEIGHT_LIMIT; break; case WID_GL_WATER_PULLDOWN: value = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE; break; default: NOT_REACHED(); @@ -942,6 +1003,10 @@ struct GenerateLandscapeWindow : public Window { _settings_newgame.game_creation.custom_town_number = Clamp(value, 1, CUSTOM_TOWN_MAX_NUMBER); break; + case WID_GL_INDUSTRY_PULLDOWN: + _settings_newgame.game_creation.custom_industry_number = Clamp(value, 1, IndustryPool::MAX_SIZE); + break; + case WID_GL_TERRAIN_PULLDOWN: _settings_newgame.game_creation.custom_terrain_type = Clamp(value, MIN_CUSTOM_TERRAIN_TYPE, GetMapHeightLimit()); break; @@ -1274,12 +1339,10 @@ void ShowCreateScenario() static const NWidgetPart _nested_generate_progress_widgets[] = { NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GENERATION_WORLD, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_HORIZONTAL), SetPIP(20, 0, 20), - NWidget(NWID_VERTICAL), SetPIP(11, 8, 11), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_BAR), SetFill(1, 0), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_TEXT), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_WHITE, WID_GP_ABORT), SetDataTip(STR_GENERATION_ABORT, STR_NULL), SetFill(1, 0), - EndContainer(), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_BAR), SetFill(1, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_TEXT), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_WHITE, WID_GP_ABORT), SetDataTip(STR_GENERATION_ABORT, STR_NULL), SetFill(1, 0), EndContainer(), EndContainer(), }; @@ -1357,8 +1420,8 @@ struct GenerateProgressWindow : public Window { SetDParamMaxValue(0, 100); *size = GetStringBoundingBox(STR_GENERATION_PROGRESS); /* We need some spacing for the 'border' */ - size->height += 8; - size->width += 8; + size->height += WidgetDimensions::scaled.frametext.Horizontal(); + size->width += WidgetDimensions::scaled.frametext.Vertical(); break; } @@ -1366,7 +1429,7 @@ struct GenerateProgressWindow : public Window { for (uint i = 0; i < GWP_CLASS_COUNT; i++) { size->width = std::max(size->width, GetStringBoundingBox(_generation_class_table[i]).width); } - size->height = FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL; + size->height = FONT_HEIGHT_NORMAL * 2 + WidgetDimensions::scaled.vsep_normal; break; } } @@ -1374,13 +1437,15 @@ struct GenerateProgressWindow : public Window { void DrawWidget(const Rect &r, int widget) const override { switch (widget) { - case WID_GP_PROGRESS_BAR: + case WID_GP_PROGRESS_BAR: { /* Draw the % complete with a bar and a text */ - DrawFrameRect(r.left, r.top, r.right, r.bottom, COLOUR_GREY, FR_BORDERONLY); - DrawFrameRect(r.left + 1, r.top + 1, (int)((r.right - r.left - 2) * _gws.percent / 100) + r.left + 1, r.bottom - 1, COLOUR_MAUVE, FR_NONE); + DrawFrameRect(r, COLOUR_GREY, FR_BORDERONLY | FR_LOWERED); + Rect br = r.Shrink(WidgetDimensions::scaled.bevel); + DrawFrameRect(br.WithWidth(br.Width() * _gws.percent / 100, false), COLOUR_MAUVE, FR_NONE); SetDParam(0, _gws.percent); - DrawString(r.left, r.right, r.top + 5, STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(br.left, br.right, CenterBounds(br.top, br.bottom, FONT_HEIGHT_NORMAL), STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER); break; + } case WID_GP_PROGRESS_TEXT: /* Tell which class we are generating */ @@ -1389,7 +1454,7 @@ struct GenerateProgressWindow : public Window { /* And say where we are in that class */ SetDParam(0, _gws.current); SetDParam(1, _gws.total); - DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL, STR_GENERATION_PROGRESS_NUM, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal, STR_GENERATION_PROGRESS_NUM, TC_FROMSTRING, SA_HOR_CENTER); } } }; diff --git a/src/gfx.cpp b/src/gfx.cpp index 5e2614bc7bbef..ec9e28f88c55f 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -17,10 +17,12 @@ #include "settings_type.h" #include "network/network.h" #include "network/network_func.h" +#include "window_gui.h" #include "window_func.h" #include "newgrf_debug.h" #include "thread.h" #include "core/backup_type.hpp" +#include "viewport_func.h" #include "table/palettes.h" #include "table/string_colours.h" @@ -59,12 +61,9 @@ static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, static ReusableBuffer _cursor_backup; -ZoomLevel _gui_zoom; ///< GUI Zoom level -ZoomLevel _font_zoom; ///< Font Zoom level - -int8 _gui_zoom_cfg; ///< GUI zoom level in config. -int8 _font_zoom_cfg; ///< Font zoom level in config. - +ZoomLevel _gui_zoom = ZOOM_LVL_OUT_4X; ///< GUI Zoom level +int _gui_scale = MIN_INTERFACE_SCALE; ///< GUI scale, 100 is 100%. +int _gui_scale_cfg; ///< GUI scale in config. /** * The rect for repaint. @@ -562,6 +561,8 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left, NOT_REACHED(); } + const uint shadow_offset = ScaleGUITrad(1); + TextColour colour = TC_BLACK; bool draw_shadow = false; for (int run_index = 0; run_index < line.CountRuns(); run_index++) { @@ -597,7 +598,7 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left, if (draw_shadow && (glyph & SPRITE_GLYPH) == 0) { SetColourRemap(TC_BLACK); - GfxMainBlitter(sprite, begin_x + 1, top + 1, BM_COLOUR_REMAP); + GfxMainBlitter(sprite, begin_x + shadow_offset, top + shadow_offset, BM_COLOUR_REMAP); SetColourRemap(colour); } GfxMainBlitter(sprite, begin_x, top, BM_COLOUR_REMAP); @@ -609,7 +610,7 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left, for (int i = 0; i < 3; i++, x += dot_width) { if (draw_shadow) { SetColourRemap(TC_BLACK); - GfxMainBlitter(dot_sprite, x + 1, y + 1, BM_COLOUR_REMAP); + GfxMainBlitter(dot_sprite, x + shadow_offset, y + shadow_offset, BM_COLOUR_REMAP); SetColourRemap(colour); } GfxMainBlitter(dot_sprite, x, y, BM_COLOUR_REMAP); @@ -819,7 +820,7 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, const char *st for (const auto &line : layout) { int line_height = line->GetLeading(); - if (y >= top && y < bottom) { + if (y >= top && y + line_height - 1 <= bottom) { last_line = y + line_height; if (first_line > y) first_line = y; @@ -913,12 +914,27 @@ Dimension GetStringBoundingBox(const std::string &str, FontSize start_fontsize) * @param strid String to examine. * @return Width and height of the bounding box for the string in pixels. */ -Dimension GetStringBoundingBox(StringID strid) +Dimension GetStringBoundingBox(StringID strid, FontSize start_fontsize) { char buffer[DRAW_STRING_BUFFER]; GetString(buffer, strid, lastof(buffer)); - return GetStringBoundingBox(buffer); + return GetStringBoundingBox(buffer, start_fontsize); +} + +/** + * Get maximum width of a list of strings. + * @param list List of strings, terminated with INVALID_STRING_ID. + * @param fontsize Font size to use. + * @return Width of longest string within the list. + */ +uint GetStringListWidth(const StringID *list, FontSize fontsize) +{ + uint width = 0; + for (const StringID *str = list; *str != INVALID_STRING_ID; str++) { + width = std::max(width, GetStringBoundingBox(*str, fontsize).width); + } + return width; } /** @@ -1206,9 +1222,10 @@ std::unique_ptr DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zo const SpriteID real_sprite = GB(spriteId, 0, SPRITE_WIDTH); const Sprite *sprite = GetSprite(real_sprite, ST_NORMAL); Dimension dim = GetSpriteSize(real_sprite, nullptr, zoom); - std::unique_ptr result(new uint32[dim.width * dim.height]); + size_t dim_size = static_cast(dim.width) * dim.height; + std::unique_ptr result(new uint32[dim_size]); /* Set buffer to fully transparent. */ - MemSetT(result.get(), 0, dim.width * dim.height); + MemSetT(result.get(), 0, dim_size); /* Prepare new DrawPixelInfo - Normally this would be the screen but we want to draw to another buffer here. * Normally, pitch would be scaled screen width, but in our case our "screen" is only the sprite width wide. */ @@ -1221,11 +1238,13 @@ std::unique_ptr DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zo dpi.height = dim.height; dpi.zoom = zoom; + dim_size = static_cast(dim.width) * dim.height; + /* If the current blitter is a paletted blitter, we have to render to an extra buffer and resolve the palette later. */ std::unique_ptr pal_buffer{}; if (blitter->GetScreenDepth() == 8) { - pal_buffer.reset(new byte[dim.width * dim.height]); - MemSetT(pal_buffer.get(), 0, dim.width * dim.height); + pal_buffer.reset(new byte[dim_size]); + MemSetT(pal_buffer.get(), 0, dim_size); dpi.dst_ptr = pal_buffer.get(); } @@ -1239,7 +1258,7 @@ std::unique_ptr DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zo /* Resolve palette. */ uint32 *dst = result.get(); const byte *src = pal_buffer.get(); - for (size_t i = 0; i < dim.height * dim.width; ++i) { + for (size_t i = 0; i < dim_size; ++i) { *dst++ = _cur_palette.palette[*src++].data; } } @@ -1308,7 +1327,6 @@ void DoPaletteAnimations() const ExtraPaletteValues *ev = &_extra_palette_values; Colour old_val[PALETTE_ANIM_SIZE]; const uint old_tc = palette_animation_counter; - uint i; uint j; if (blitter != nullptr && blitter->UsePaletteAnimation() == Blitter::PALETTE_ANIMATION_NONE) { @@ -1323,7 +1341,7 @@ void DoPaletteAnimations() /* Fizzy Drink bubbles animation */ s = ev->fizzy_drink; j = EXTR2(512, EPV_CYCLES_FIZZY_DRINK); - for (i = 0; i != EPV_CYCLES_FIZZY_DRINK; i++) { + for (uint i = 0; i != EPV_CYCLES_FIZZY_DRINK; i++) { *palette_pos++ = s[j]; j++; if (j == EPV_CYCLES_FIZZY_DRINK) j = 0; @@ -1332,7 +1350,7 @@ void DoPaletteAnimations() /* Oil refinery fire animation */ s = ev->oil_refinery; j = EXTR2(512, EPV_CYCLES_OIL_REFINERY); - for (i = 0; i != EPV_CYCLES_OIL_REFINERY; i++) { + for (uint i = 0; i != EPV_CYCLES_OIL_REFINERY; i++) { *palette_pos++ = s[j]; j++; if (j == EPV_CYCLES_OIL_REFINERY) j = 0; @@ -1372,7 +1390,7 @@ void DoPaletteAnimations() /* Handle lighthouse and stadium animation */ s = ev->lighthouse; j = EXTR(256, EPV_CYCLES_LIGHTHOUSE); - for (i = 0; i != EPV_CYCLES_LIGHTHOUSE; i++) { + for (uint i = 0; i != EPV_CYCLES_LIGHTHOUSE; i++) { *palette_pos++ = s[j]; j++; if (j == EPV_CYCLES_LIGHTHOUSE) j = 0; @@ -1381,7 +1399,7 @@ void DoPaletteAnimations() /* Dark blue water */ s = (_settings_game.game_creation.landscape == LT_TOYLAND) ? ev->dark_water_toyland : ev->dark_water; j = EXTR(320, EPV_CYCLES_DARK_WATER); - for (i = 0; i != EPV_CYCLES_DARK_WATER; i++) { + for (uint i = 0; i != EPV_CYCLES_DARK_WATER; i++) { *palette_pos++ = s[j]; j++; if (j == EPV_CYCLES_DARK_WATER) j = 0; @@ -1390,7 +1408,7 @@ void DoPaletteAnimations() /* Glittery water */ s = (_settings_game.game_creation.landscape == LT_TOYLAND) ? ev->glitter_water_toyland : ev->glitter_water; j = EXTR(128, EPV_CYCLES_GLITTER_WATER); - for (i = 0; i != EPV_CYCLES_GLITTER_WATER / 3; i++) { + for (uint i = 0; i != EPV_CYCLES_GLITTER_WATER / 3; i++) { *palette_pos++ = s[j]; j += 3; if (j >= EPV_CYCLES_GLITTER_WATER) j -= EPV_CYCLES_GLITTER_WATER; @@ -1490,7 +1508,7 @@ void GetBroadestDigit(uint *front, uint *next, FontSize size) void ScreenSizeChanged() { _dirty_bytes_per_line = CeilDiv(_screen.width, DIRTY_BLOCK_WIDTH); - _dirty_blocks = ReallocT(_dirty_blocks, _dirty_bytes_per_line * CeilDiv(_screen.height, DIRTY_BLOCK_HEIGHT)); + _dirty_blocks = ReallocT(_dirty_blocks, static_cast(_dirty_bytes_per_line) * CeilDiv(_screen.height, DIRTY_BLOCK_HEIGHT)); /* check the dirty rect */ if (_invalid_rect.right >= _screen.width) _invalid_rect.right = _screen.width; @@ -1650,23 +1668,23 @@ void DrawDirtyBlocks() while (right != w) { byte *p2 = ++p; - int h = h2; + int i = h2; /* Check if a full line of dirty flags is set. */ do { if (!*p2) goto no_more_coalesc; p2 += _dirty_bytes_per_line; - } while (--h != 0); + } while (--i != 0); /* Wohoo, can combine it one step to the right! * Do that, and clear the bits. */ right += DIRTY_BLOCK_WIDTH; - h = h2; + i = h2; p2 = p; do { *p2 = 0; p2 += _dirty_bytes_per_line; - } while (--h != 0); + } while (--i != 0); } no_more_coalesc: @@ -2024,22 +2042,58 @@ void SortResolutions() void UpdateGUIZoom() { /* Determine real GUI zoom to use. */ - if (_gui_zoom_cfg == ZOOM_LVL_CFG_AUTO) { - _gui_zoom = static_cast(Clamp(VideoDriver::GetInstance()->GetSuggestedUIZoom(), _settings_client.gui.zoom_min, _settings_client.gui.zoom_max)); + if (_gui_scale_cfg == -1) { + _gui_scale = VideoDriver::GetInstance()->GetSuggestedUIScale(); } else { - /* Ensure the gui_zoom is clamped between min/max. Change the - * _gui_zoom_cfg if it isn't, as this is used to visually show the - * selection in the Game Options. */ - _gui_zoom_cfg = Clamp(_gui_zoom_cfg, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max); - _gui_zoom = static_cast(_gui_zoom_cfg); + _gui_scale = Clamp(_gui_scale_cfg, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE); } - /* Determine real font zoom to use. */ - if (_font_zoom_cfg == ZOOM_LVL_CFG_AUTO) { - _font_zoom = static_cast(VideoDriver::GetInstance()->GetSuggestedUIZoom()); - } else { - _font_zoom = static_cast(_font_zoom_cfg); + int8 new_zoom = ScaleGUITrad(1) <= 1 ? ZOOM_LVL_OUT_4X : ScaleGUITrad(1) >= 4 ? ZOOM_LVL_MIN : ZOOM_LVL_OUT_2X; + /* Ensure the gui_zoom is clamped between min/max. */ + new_zoom = Clamp(new_zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max); + _gui_zoom = static_cast(new_zoom); +} + +/** + * Resolve GUI zoom level and adjust GUI to new zoom, if auto-suggestion is requested. + * @param automatic Set if the change is occuring due to OS DPI scaling being changed. + * @returns true when the zoom level has changed, caller must call ReInitAllWindows(true) + * after resizing the application's window/buffer. + */ +bool AdjustGUIZoom(bool automatic) +{ + ZoomLevel old_zoom = _gui_zoom; + int old_scale = _gui_scale; + UpdateGUIZoom(); + if (old_scale == _gui_scale) return false; + + /* Reload sprites if sprite zoom level has changed. */ + if (old_zoom != _gui_zoom) { + GfxClearSpriteCache(); + VideoDriver::GetInstance()->ClearSystemSprites(); + UpdateCursorSize(); } + + ClearFontCache(); + LoadStringWidthTable(); + UpdateAllVirtCoords(); + + /* Adjust all window sizes to match the new zoom level, so that they don't appear + to move around when the application is moved to a screen with different DPI. */ + auto zoom_shift = old_zoom - _gui_zoom; + for (Window *w : Window::Iterate()) { + if (automatic) { + w->left = (w->left * _gui_scale) / old_scale; + w->top = (w->top * _gui_scale) / old_scale; + w->width = (w->width * _gui_scale) / old_scale; + w->height = (w->height * _gui_scale) / old_scale; + } + if (w->viewport != nullptr) { + w->viewport->zoom = Clamp(ZoomLevel(w->viewport->zoom - zoom_shift), _settings_client.gui.zoom_min, _settings_client.gui.zoom_max); + } + } + + return true; } void ChangeGameSpeed(bool enable_fast_forward) diff --git a/src/gfx_func.h b/src/gfx_func.h index b811c089fe57d..78891e1dc7487 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -79,7 +79,7 @@ void ChangeGameSpeed(bool enable_fast_forward); void DrawMouseCursor(); void ScreenSizeChanged(); void GameSizeChanged(); -void UpdateGUIZoom(); +bool AdjustGUIZoom(bool automatic); void UndrawMouseCursor(); /** Size of the buffer used for drawing strings. */ @@ -89,8 +89,10 @@ void RedrawScreenRect(int left, int top, int right, int bottom); void GfxScroll(int left, int top, int width, int height, int xo, int yo); Dimension GetSpriteSize(SpriteID sprid, Point *offset = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI); +Dimension GetScaledSpriteSize(SpriteID sprid); /* widget.cpp */ void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr); void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI); +void DrawSpriteIgnorePadding(SpriteID img, PaletteID pal, const Rect &r, bool clicked, StringAlignment align); /* widget.cpp */ std::unique_ptr DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zoom = ZOOM_LVL_GUI); int DrawString(int left, int right, int top, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL); @@ -107,9 +109,46 @@ void GfxFillPolygon(const std::vector &shape, int colour, FillRectMode mo void GfxDrawLine(int left, int top, int right, int bottom, int colour, int width = 1, int dash = 0); void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3); +/* Versions of DrawString/DrawStringMultiLine that accept a Rect instead of separate left, right, top and bottom parameters. */ +static inline int DrawString(const Rect &r, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL) +{ + return DrawString(r.left, r.right, r.top, str, colour, align, underline, fontsize); +} + +static inline int DrawString(const Rect &r, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL) +{ + return DrawString(r.left, r.right, r.top, str, colour, align, underline, fontsize); +} + +static inline int DrawString(const Rect &r, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL) +{ + return DrawString(r.left, r.right, r.top, str, colour, align, underline, fontsize); +} + +static inline int DrawStringMultiLine(const Rect &r, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL) +{ + return DrawStringMultiLine(r.left, r.right, r.top, r.bottom, str, colour, align, underline, fontsize); +} + +static inline int DrawStringMultiLine(const Rect &r, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL) +{ + return DrawStringMultiLine(r.left, r.right, r.top, r.bottom, str, colour, align, underline, fontsize); +} + +static inline int DrawStringMultiLine(const Rect &r, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL) +{ + return DrawStringMultiLine(r.left, r.right, r.top, r.bottom, str, colour, align, underline, fontsize); +} + +static inline void GfxFillRect(const Rect &r, int colour, FillRectMode mode = FILLRECT_OPAQUE) +{ + GfxFillRect(r.left, r.top, r.right, r.bottom, colour, mode); +} + Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize = FS_NORMAL); Dimension GetStringBoundingBox(const std::string &str, FontSize start_fontsize = FS_NORMAL); -Dimension GetStringBoundingBox(StringID strid); +Dimension GetStringBoundingBox(StringID strid, FontSize start_fontsize = FS_NORMAL); +uint GetStringListWidth(const StringID *list, FontSize fontsize = FS_NORMAL); int GetStringHeight(const char *str, int maxw, FontSize fontsize = FS_NORMAL); int GetStringHeight(StringID str, int maxw); int GetStringLineCount(StringID str, int maxw); @@ -138,7 +177,7 @@ bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int heigh */ static inline int CenterBounds(int min, int max, int size) { - return min + (max - min - size + 1) / 2; + return (min + max - size + 1) / 2; } /* window.cpp */ diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index 38f6d62e59af8..1a163330d2226 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.cpp @@ -11,6 +11,7 @@ #include "gfx_layout.h" #include "string_func.h" #include "strings_func.h" +#include "zoom_func.h" #include "debug.h" #include "table/control_codes.h" @@ -333,18 +334,25 @@ class FallbackParagraphLayoutFactory { FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(Font *font, const WChar *chars, int char_count, int x) : font(font), glyph_count(char_count) { + const bool isbuiltin = font->fc->IsBuiltInFont(); + this->glyphs = MallocT(this->glyph_count); this->glyph_to_char = MallocT(this->glyph_count); /* Positions contains the location of the begin of each of the glyphs, and the end of the last one. */ this->positions = MallocT(this->glyph_count * 2 + 2); this->positions[0] = x; - this->positions[1] = 0; for (int i = 0; i < this->glyph_count; i++) { this->glyphs[i] = font->fc->MapCharToGlyph(chars[i]); + if (isbuiltin) { + this->positions[2 * i + 1] = font->fc->GetAscender(); // Apply sprite font's ascender. + } else if (chars[i] >= SCC_SPRITE_START && chars[i] <= SCC_SPRITE_END) { + this->positions[2 * i + 1] = (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2; // Align sprite font to centre + } else { + this->positions[2 * i + 1] = 0; // No ascender adjustment. + } this->positions[2 * i + 2] = this->positions[2 * i] + font->fc->GetGlyphWidth(this->glyphs[i]); - this->positions[2 * i + 3] = 0; this->glyph_to_char[i] = i; } } @@ -544,8 +552,6 @@ std::unique_ptr FallbackParagraphLayout::NextLine next_run = this->buffer_begin + iter->first; begin = this->buffer; - - last_space = nullptr; } if (IsWhitespace(c)) last_space = this->buffer; @@ -583,7 +589,7 @@ std::unique_ptr FallbackParagraphLayout::NextLine this->buffer++; } - if (l->size() == 0 || last_char - begin != 0) { + if (l->size() == 0 || last_char - begin > 0) { int w = l->GetWidth(); l->emplace_back(iter->second, begin, last_char - begin, w); } diff --git a/src/gfx_type.h b/src/gfx_type.h index 932a6cb87d253..8a3fc64dfdd26 100644 --- a/src/gfx_type.h +++ b/src/gfx_type.h @@ -214,6 +214,13 @@ enum FontSize { }; DECLARE_POSTFIX_INCREMENT(FontSize) +static inline const char *FontSizeToName(FontSize fs) +{ + static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" }; + assert(fs < FS_END); + return SIZE_TO_NAME[fs]; +} + /** * Used to only draw a part of the sprite. * Draw the subsprite in the rect (sprite_x_offset + left, sprite_y_offset + top) to (sprite_x_offset + right, sprite_y_offset + bottom). diff --git a/src/goal.cpp b/src/goal.cpp index 447763866b9e9..208678678d555 100644 --- a/src/goal.cpp +++ b/src/goal.cpp @@ -224,9 +224,11 @@ CommandCost CmdSetGoalCompleted(DoCommandFlag flags, GoalID goal, bool completed * @param text Text of the question. * @return the cost of this operation or an error */ -CommandCost CmdGoalQuestion(DoCommandFlag flags, uint16 uniqueid, uint16 target, bool is_client, uint32 button_mask, GoalQuestionType type, const std::string &text) +CommandCost CmdGoalQuestion(DoCommandFlag flags, uint16 uniqueid, uint32 target, bool is_client, uint32 button_mask, GoalQuestionType type, const std::string &text) { + static_assert(sizeof(uint32) >= sizeof(CompanyID)); CompanyID company = (CompanyID)target; + static_assert(sizeof(uint32) >= sizeof(ClientID)); ClientID client = (ClientID)target; static_assert(GOAL_QUESTION_BUTTON_COUNT < 29); diff --git a/src/goal_cmd.h b/src/goal_cmd.h index 5be2044e21fa2..3f5eac7d8cd9a 100644 --- a/src/goal_cmd.h +++ b/src/goal_cmd.h @@ -10,7 +10,6 @@ #ifndef GOAL_CMD_H #define GOAL_CMD_H -#include "command_type.h" #include "command_type.h" #include "goal_type.h" @@ -19,7 +18,7 @@ CommandCost CmdRemoveGoal(DoCommandFlag flags, GoalID goal); CommandCost CmdSetGoalText(DoCommandFlag flags, GoalID goal, const std::string &text); CommandCost CmdSetGoalProgress(DoCommandFlag flags, GoalID goal, const std::string &text); CommandCost CmdSetGoalCompleted(DoCommandFlag flags, GoalID goal, bool completed); -CommandCost CmdGoalQuestion(DoCommandFlag flags, uint16 uniqueid, uint16 target, bool is_client, uint32 button_mask, GoalQuestionType type, const std::string &text); +CommandCost CmdGoalQuestion(DoCommandFlag flags, uint16 uniqueid, uint32 target, bool is_client, uint32 button_mask, GoalQuestionType type, const std::string &text); CommandCost CmdGoalQuestionAnswer(DoCommandFlag flags, uint16 uniqueid, uint8 button); DEF_CMD_TRAIT(CMD_CREATE_GOAL, CmdCreateGoal, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index 639901ee5b0ac..1d8113132166d 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.cpp @@ -76,7 +76,7 @@ struct GoalListWindow : public Window { break; case WID_GOAL_LIST: { - int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GOAL_LIST, WD_FRAMERECT_TOP); + int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GOAL_LIST, WidgetDimensions::scaled.framerect.top); for (const Goal *s : Goal::Iterate()) { if (s->company == this->window_number) { if (y == 0) { @@ -174,11 +174,12 @@ struct GoalListWindow : public Window { if (widget != WID_GOAL_LIST) return; Dimension d = GetStringBoundingBox(STR_GOALS_NONE); + resize->width = 1; resize->height = d.height; d.height *= 5; - d.width += padding.width + WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT; - d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += WidgetDimensions::scaled.framerect.Horizontal(); + d.height += WidgetDimensions::scaled.framerect.Vertical(); *size = maxdim(*size, d); } @@ -192,9 +193,7 @@ struct GoalListWindow : public Window { void DrawListColumn(GoalColumn column, NWidgetBase *wid, uint progress_col_width) const { /* Get column draw area. */ - int y = wid->pos_y + WD_FRAMERECT_TOP; - int x = wid->pos_x + WD_FRAMERECT_LEFT; - int right = x + wid->current_x - WD_FRAMERECT_RIGHT; + Rect r = wid->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); bool rtl = _current_text_dir == TD_RTL; int pos = -this->vscroll->GetPosition(); @@ -208,8 +207,8 @@ struct GoalListWindow : public Window { case GC_GOAL: { /* Display the goal. */ SetDParamStr(0, s->text); - uint width_reduction = progress_col_width > 0 ? progress_col_width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT : 0; - DrawString(x + (rtl ? width_reduction : 0), right - (rtl ? 0 : width_reduction), y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_TEXT); + uint width_reduction = progress_col_width > 0 ? progress_col_width + WidgetDimensions::scaled.framerect.Horizontal() : 0; + DrawString(r.Indent(width_reduction, !rtl), STR_GOALS_TEXT); break; } @@ -217,12 +216,11 @@ struct GoalListWindow : public Window { if (s->progress != nullptr) { SetDParamStr(0, s->progress); StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS; - int progress_x = x; - int progress_right = rtl ? x + progress_col_width : right; - DrawString(progress_x, progress_right, y + pos * FONT_HEIGHT_NORMAL, str, TC_FROMSTRING, SA_RIGHT | SA_FORCE); + DrawString(r.WithWidth(progress_col_width, !rtl), str, TC_FROMSTRING, SA_RIGHT | SA_FORCE); } break; } + r.top += FONT_HEIGHT_NORMAL; } pos++; num++; @@ -231,9 +229,8 @@ struct GoalListWindow : public Window { if (num == 0) { if (column == GC_GOAL && IsInsideMM(pos, 0, cap)) { - DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_NONE); + DrawString(r, STR_GOALS_NONE); } - pos++; } } @@ -265,7 +262,7 @@ struct GoalListWindow : public Window { void OnResize() override { - this->vscroll->SetCapacityFromWidget(this, WID_GOAL_LIST); + this->vscroll->SetCapacityFromWidget(this, WID_GOAL_LIST, WidgetDimensions::scaled.framerect.Vertical()); } /** @@ -289,16 +286,15 @@ static const NWidgetPart _nested_goals_list_widgets[] = { NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_GOAL_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GOAL_SELECT_BUTTONS), - NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GOAL_GLOBAL_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GOALS_GLOBAL_BUTTON, STR_GOALS_GLOBAL_BUTTON_HELPTEXT), - NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GOAL_COMPANY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GOALS_COMPANY_BUTTON, STR_GOALS_COMPANY_BUTTON_HELPTEXT), + NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GOAL_GLOBAL_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.captiontext.Vertical()), SetDataTip(STR_GOALS_GLOBAL_BUTTON, STR_GOALS_GLOBAL_BUTTON_HELPTEXT), + NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GOAL_COMPANY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.captiontext.Vertical()), SetDataTip(STR_GOALS_COMPANY_BUTTON, STR_GOALS_COMPANY_BUTTON_HELPTEXT), EndContainer(), NWidget(WWT_SHADEBOX, COLOUR_BROWN), NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN), NWidget(WWT_STICKYBOX, COLOUR_BROWN), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_PANEL, COLOUR_BROWN), SetDataTip(0x0, STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER), SetScrollbar(WID_GOAL_SCROLLBAR), - NWidget(WWT_EMPTY, COLOUR_GREY, WID_GOAL_LIST), SetResize(1, 1), SetMinimalTextLines(2, 0), SetFill(1, 1), SetPadding(WD_FRAMERECT_TOP, 2, WD_FRAMETEXT_BOTTOM, 2), + NWidget(WWT_PANEL, COLOUR_BROWN, WID_GOAL_LIST), SetDataTip(0x0, STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER), SetScrollbar(WID_GOAL_SCROLLBAR), SetResize(1, 1), SetMinimalTextLines(2, 0), EndContainer(), NWidget(NWID_VERTICAL), NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_GOAL_SCROLLBAR), @@ -404,7 +400,7 @@ struct GoalQuestionWindow : public Window { if (widget != WID_GQ_QUESTION) return; SetDParamStr(0, this->question); - size->height = GetStringHeight(STR_JUST_RAW_STRING, size->width) + WD_PAR_VSEP_WIDE; + size->height = GetStringHeight(STR_JUST_RAW_STRING, size->width) + WidgetDimensions::scaled.vsep_wide; } void DrawWidget(const Rect &r, int widget) const override @@ -412,7 +408,7 @@ struct GoalQuestionWindow : public Window { if (widget != WID_GQ_QUESTION) return; SetDParamStr(0, this->question); - DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, this->colour, SA_TOP | SA_HOR_CENTER); + DrawStringMultiLine(r, STR_JUST_RAW_STRING, this->colour, SA_TOP | SA_HOR_CENTER); } }; diff --git a/src/goal_type.h b/src/goal_type.h index 27ec758a9d6d6..2db04b9f0a109 100644 --- a/src/goal_type.h +++ b/src/goal_type.h @@ -32,8 +32,7 @@ enum GoalType : byte { GT_STORY_PAGE, ///< Destination is a story page }; -typedef uint32 GoalTypeID; ///< Contains either tile, industry ID, town ID or company ID (or INVALID_GOALTYPE) -static const GoalTypeID INVALID_GOALTYPE = 0xFFFFFFFF; ///< Invalid/unknown index of GoalType +typedef uint32 GoalTypeID; ///< Contains either tile, industry ID, town ID, company ID, or story page ID typedef uint16 GoalID; ///< ID of a goal struct Goal; diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index 92b1808c151d1..4fdc66ee9b9f3 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -18,7 +18,6 @@ #include "window_func.h" #include "date_func.h" #include "gfx_func.h" -#include "sortlist_type.h" #include "core/geometry_func.hpp" #include "currency.h" #include "zoom_func.h" @@ -65,12 +64,14 @@ struct GraphLegendWindow : Window { bool rtl = _current_text_dir == TD_RTL; + const Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); Dimension d = GetSpriteSize(SPR_COMPANY_ICON); - DrawCompanyIcon(cid, rtl ? r.right - d.width - ScaleGUITrad(2) : r.left + ScaleGUITrad(2), CenterBounds(r.top, r.bottom, d.height)); + DrawCompanyIcon(cid, rtl ? ir.right - d.width : ir.left, CenterBounds(ir.top, ir.bottom, d.height)); + const Rect tr = ir.Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl); SetDParam(0, cid); SetDParam(1, cid); - DrawString(r.left + (rtl ? (uint)WD_FRAMERECT_LEFT : (d.width + ScaleGUITrad(4))), r.right - (rtl ? (d.width + ScaleGUITrad(4)) : (uint)WD_FRAMERECT_RIGHT), CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), STR_COMPANY_NAME_COMPANY_NUM, HasBit(_legend_excluded_companies, cid) ? TC_BLACK : TC_WHITE); + DrawString(tr.left, tr.right, CenterBounds(tr.top, tr.bottom, FONT_HEIGHT_NORMAL), STR_COMPANY_NAME_COMPANY_NUM, HasBit(_legend_excluded_companies, cid) ? TC_BLACK : TC_WHITE); } void OnClick(Point pt, int widget, int click_count) override @@ -110,14 +111,15 @@ struct GraphLegendWindow : Window { */ static NWidgetBase *MakeNWidgetCompanyLines(int *biggest_index) { - NWidgetVertical *vert = new NWidgetVertical(); + NWidgetVertical *vert = new NWidgetVertical(NC_EQUALSIZE); + vert->SetPadding(2, 2, 2, 2); uint sprite_height = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_OUT_4X).height; for (int widnum = WID_GL_FIRST_COMPANY; widnum <= WID_GL_LAST_COMPANY; widnum++) { NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_BROWN, widnum); - panel->SetMinimalSize(246, sprite_height); - panel->SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM, FS_NORMAL); - panel->SetFill(1, 0); + panel->SetMinimalSize(246, sprite_height + WidgetDimensions::unscaled.framerect.Vertical()); + panel->SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical(), FS_NORMAL); + panel->SetFill(1, 1); panel->SetDataTip(0x0, STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP); vert->Add(panel); } @@ -133,13 +135,7 @@ static const NWidgetPart _nested_graph_legend_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_BROWN), EndContainer(), NWidget(WWT_PANEL, COLOUR_BROWN, WID_GL_BACKGROUND), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(NWID_HORIZONTAL), - NWidget(NWID_SPACER), SetMinimalSize(2, 0), - NWidgetFunction(MakeNWidgetCompanyLines), - NWidget(NWID_SPACER), SetMinimalSize(2, 0), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), + NWidgetFunction(MakeNWidgetCompanyLines), EndContainer(), }; @@ -302,15 +298,15 @@ struct BaseGraphWindow : Window { /* Rect r will be adjusted to contain just the graph, with labels being * placed outside the area. */ - r.top += 5 + GetCharacterHeight(FS_SMALL) / 2; - r.bottom -= (this->month == 0xFF ? 1 : 2) * GetCharacterHeight(FS_SMALL) + 4; - r.left += 9; - r.right -= 5; + r.top += ScaleGUITrad(5) + GetCharacterHeight(FS_SMALL) / 2; + r.bottom -= (this->month == 0xFF ? 1 : 2) * GetCharacterHeight(FS_SMALL) + ScaleGUITrad(4); + r.left += ScaleGUITrad(9); + r.right -= ScaleGUITrad(5); /* Initial number of horizontal lines. */ - int num_hori_lines = 160 / MIN_GRID_PIXEL_SIZE; + int num_hori_lines = 160 / ScaleGUITrad(MIN_GRID_PIXEL_SIZE); /* For the rest of the height, the number of horizontal lines will increase more slowly. */ - int resize = (r.bottom - r.top - 160) / (2 * MIN_GRID_PIXEL_SIZE); + int resize = (r.bottom - r.top - 160) / (2 * ScaleGUITrad(MIN_GRID_PIXEL_SIZE)); if (resize > 0) num_hori_lines += resize; interval = GetValuesInterval(num_hori_lines); @@ -348,7 +344,7 @@ struct BaseGraphWindow : Window { y = r.bottom; for (int i = 0; i < (num_hori_lines + 1); i++) { - GfxFillRect(r.left - 3, y, r.left - 1, y, GRAPH_AXIS_LINE_COLOUR); + GfxFillRect(r.left - ScaleGUITrad(3), y, r.left - 1, y, GRAPH_AXIS_LINE_COLOUR); GfxFillRect(r.left, y, r.right, y, GRAPH_GRID_COLOUR); y -= y_sep; } @@ -375,7 +371,7 @@ struct BaseGraphWindow : Window { for (int i = 0; i < (num_hori_lines + 1); i++) { SetDParam(0, this->format_str_y_axis); SetDParam(1, y_label); - DrawString(r.left - label_width - 4, r.left - 4, y, STR_GRAPH_Y_LABEL, GRAPH_AXIS_LABEL_COLOUR, SA_RIGHT); + DrawString(r.left - label_width - ScaleGUITrad(4), r.left - ScaleGUITrad(4), y, STR_GRAPH_Y_LABEL, GRAPH_AXIS_LABEL_COLOUR, SA_RIGHT); y_label -= y_label_separation; y += y_sep; @@ -384,7 +380,7 @@ struct BaseGraphWindow : Window { /* Draw x-axis labels and markings for graphs based on financial quarters and years. */ if (this->month != 0xFF) { x = r.left; - y = r.bottom + 2; + y = r.bottom + ScaleGUITrad(2); byte month = this->month; Year year = this->year; for (int i = 0; i < this->num_on_x_axis; i++) { @@ -405,7 +401,7 @@ struct BaseGraphWindow : Window { } else { /* Draw x-axis labels for graphs not based on quarterly performance (cargo payment rates). */ x = r.left; - y = r.bottom + 2; + y = r.bottom + ScaleGUITrad(2); uint16 label = this->x_values_start; for (int i = 0; i < this->num_on_x_axis; i++) { @@ -525,8 +521,8 @@ struct BaseGraphWindow : Window { SetDParam(1, INT64_MAX); uint y_label_width = GetStringBoundingBox(STR_GRAPH_Y_LABEL).width; - size->width = std::max(size->width, 5 + y_label_width + this->num_on_x_axis * (x_label_width + 5) + 9); - size->height = std::max(size->height, 5 + (1 + MIN_GRAPH_NUM_LINES_Y * 2 + (this->month != 0xFF ? 3 : 1)) * FONT_HEIGHT_SMALL + 4); + size->width = std::max(size->width, ScaleGUITrad(5) + y_label_width + this->num_on_x_axis * (x_label_width + ScaleGUITrad(5)) + ScaleGUITrad(9)); + size->height = std::max(size->height, ScaleGUITrad(5) + (1 + MIN_GRAPH_NUM_LINES_Y * 2 + (this->month != 0xFF ? 3 : 1)) * FONT_HEIGHT_SMALL + ScaleGUITrad(4)); size->height = std::max(size->height, size->width / 3); } @@ -639,7 +635,7 @@ static const NWidgetPart _nested_operating_profit_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_OPERATING_PROFIT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), NWidget(WWT_SHADEBOX, COLOUR_BROWN), NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN), NWidget(WWT_STICKYBOX, COLOUR_BROWN), @@ -690,7 +686,7 @@ static const NWidgetPart _nested_income_graph_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_INCOME_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), NWidget(WWT_SHADEBOX, COLOUR_BROWN), NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN), NWidget(WWT_STICKYBOX, COLOUR_BROWN), @@ -739,7 +735,7 @@ static const NWidgetPart _nested_delivered_cargo_graph_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_CARGO_DELIVERED_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), NWidget(WWT_SHADEBOX, COLOUR_BROWN), NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN), NWidget(WWT_STICKYBOX, COLOUR_BROWN), @@ -794,8 +790,8 @@ static const NWidgetPart _nested_performance_history_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_PHG_DETAILED_PERFORMANCE), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_PERFORMANCE_DETAIL_KEY, STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP), - NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_PHG_KEY), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_PHG_DETAILED_PERFORMANCE), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_PERFORMANCE_DETAIL_KEY, STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_PHG_KEY), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), NWidget(WWT_SHADEBOX, COLOUR_BROWN), NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN), NWidget(WWT_STICKYBOX, COLOUR_BROWN), @@ -844,7 +840,7 @@ static const NWidgetPart _nested_company_value_graph_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_COMPANY_VALUES_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP), NWidget(WWT_SHADEBOX, COLOUR_BROWN), NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN), NWidget(WWT_STICKYBOX, COLOUR_BROWN), @@ -933,7 +929,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { void OnInit() override { /* Width of the legend blob. */ - this->legend_width = (FONT_HEIGHT_SMALL - ScaleFontTrad(1)) * 8 / 5; + this->legend_width = (FONT_HEIGHT_SMALL - ScaleGUITrad(1)) * 8 / 5; } void UpdateExcludedData() @@ -957,9 +953,9 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { for (const CargoSpec *cs : _sorted_standard_cargo_specs) { SetDParam(0, cs->name); Dimension d = GetStringBoundingBox(STR_GRAPH_CARGO_PAYMENT_CARGO); - d.width += this->legend_width + 4; // colour field - d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += this->legend_width + WidgetDimensions::scaled.hsep_normal; // colour field + d.width += WidgetDimensions::scaled.framerect.Horizontal(); + d.height += WidgetDimensions::scaled.framerect.Vertical(); *size = maxdim(d, *size); } @@ -978,32 +974,31 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { bool rtl = _current_text_dir == TD_RTL; - int x = r.left + WD_FRAMERECT_LEFT; - int y = r.top; - uint row_height = FONT_HEIGHT_SMALL; - int padding = ScaleFontTrad(1); - int pos = this->vscroll->GetPosition(); int max = pos + this->vscroll->GetCapacity(); + Rect line = r.WithHeight(this->line_height); for (const CargoSpec *cs : _sorted_standard_cargo_specs) { if (pos-- > 0) continue; if (--max < 0) break; bool lowered = !HasBit(_legend_excluded_cargo, cs->Index()); - /* Redraw box if lowered */ - if (lowered) DrawFrameRect(r.left, y, r.right, y + this->line_height - 1, COLOUR_BROWN, FR_LOWERED); + /* Redraw frame if lowered */ + if (lowered) DrawFrameRect(line, COLOUR_BROWN, FR_LOWERED); + + const Rect text = line.Shrink(WidgetDimensions::scaled.framerect).Translate(lowered ? WidgetDimensions::scaled.pressed : 0, lowered ? WidgetDimensions::scaled.pressed : 0); - byte clk_dif = lowered ? 1 : 0; - int rect_x = clk_dif + (rtl ? r.right - this->legend_width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT); + /* Cargo-colour box with outline */ + const Rect cargo = text.WithWidth(this->legend_width, rtl); + GfxFillRect(cargo, PC_BLACK); + GfxFillRect(cargo.Shrink(WidgetDimensions::scaled.bevel), cs->legend_colour); - GfxFillRect(rect_x, y + padding + clk_dif, rect_x + this->legend_width, y + row_height - 1 + clk_dif, PC_BLACK); - GfxFillRect(rect_x + 1, y + padding + 1 + clk_dif, rect_x + this->legend_width - 1, y + row_height - 2 + clk_dif, cs->legend_colour); + /* Cargo name */ SetDParam(0, cs->name); - DrawString(rtl ? r.left : x + this->legend_width + 4 + clk_dif, (rtl ? r.right - this->legend_width - 4 + clk_dif : r.right), y + clk_dif, STR_GRAPH_CARGO_PAYMENT_CARGO); + DrawString(text.Indent(this->legend_width + WidgetDimensions::scaled.hsep_normal, rtl), STR_GRAPH_CARGO_PAYMENT_CARGO); - y += this->line_height; + line = line.Translate(0, this->line_height); } } @@ -1145,7 +1140,7 @@ static const NWidgetPart _nested_cargo_payment_rates_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(5, 0), SetFill(0, 1), SetResize(0, 1), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(NWID_SPACER), SetMinimalSize(WD_RESIZEBOX_WIDTH, 0), SetFill(1, 0), SetResize(1, 0), + NWidget(NWID_SPACER), SetMinimalSize(12, 0), SetFill(1, 0), SetResize(1, 0), NWidget(WWT_TEXT, COLOUR_BROWN, WID_CPR_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), @@ -1172,192 +1167,6 @@ void ShowCargoPaymentRates() AllocateWindowDescFront(&_cargo_payment_rates_desc, 0); } -/************************/ -/* COMPANY LEAGUE TABLE */ -/************************/ - -static const StringID _performance_titles[] = { - STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ENGINEER, - STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ENGINEER, - STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRAFFIC_MANAGER, - STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRAFFIC_MANAGER, - STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRANSPORT_COORDINATOR, - STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRANSPORT_COORDINATOR, - STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ROUTE_SUPERVISOR, - STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ROUTE_SUPERVISOR, - STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_DIRECTOR, - STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_DIRECTOR, - STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_CHIEF_EXECUTIVE, - 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, -}; - -static inline StringID GetPerformanceTitleFromValue(uint value) -{ - return _performance_titles[std::min(value, 1000u) >> 6]; -} - -class CompanyLeagueWindow : public Window { -private: - GUIList companies; - uint ordinal_width; ///< The width of the ordinal number - uint text_width; ///< The width of the actual text - uint icon_width; ///< The width of the company icon - int line_height; ///< Height of the text lines - - /** - * (Re)Build the company league list - */ - void BuildCompanyList() - { - if (!this->companies.NeedRebuild()) return; - - this->companies.clear(); - - for (const Company *c : Company::Iterate()) { - this->companies.push_back(c); - } - - this->companies.shrink_to_fit(); - this->companies.RebuildDone(); - } - - /** Sort the company league by performance history */ - static bool PerformanceSorter(const Company * const &c1, const Company * const &c2) - { - return c2->old_economy[0].performance_history < c1->old_economy[0].performance_history; - } - -public: - CompanyLeagueWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc) - { - this->InitNested(window_number); - this->companies.ForceRebuild(); - this->companies.NeedResort(); - } - - void OnPaint() override - { - this->BuildCompanyList(); - this->companies.Sort(&PerformanceSorter); - - this->DrawWidgets(); - } - - void DrawWidget(const Rect &r, int widget) const override - { - if (widget != WID_CL_BACKGROUND) return; - - int icon_y_offset = 1 + (FONT_HEIGHT_NORMAL - this->line_height) / 2; - uint y = r.top + WD_FRAMERECT_TOP - icon_y_offset; - - bool rtl = _current_text_dir == TD_RTL; - uint ordinal_left = rtl ? r.right - WD_FRAMERECT_LEFT - this->ordinal_width : r.left + WD_FRAMERECT_LEFT; - uint ordinal_right = rtl ? r.right - WD_FRAMERECT_LEFT : r.left + WD_FRAMERECT_LEFT + this->ordinal_width; - uint icon_left = r.left + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT + (rtl ? this->text_width : this->ordinal_width); - uint text_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.right - WD_FRAMERECT_LEFT - this->text_width; - uint text_right = rtl ? r.left + WD_FRAMERECT_LEFT + this->text_width : r.right - WD_FRAMERECT_LEFT; - - for (uint i = 0; i != this->companies.size(); i++) { - const Company *c = this->companies[i]; - DrawString(ordinal_left, ordinal_right, y, i + STR_ORDINAL_NUMBER_1ST, i == 0 ? TC_WHITE : TC_YELLOW); - - DrawCompanyIcon(c->index, icon_left, y + icon_y_offset); - - SetDParam(0, c->index); - SetDParam(1, c->index); - SetDParam(2, GetPerformanceTitleFromValue(c->old_economy[0].performance_history)); - DrawString(text_left, text_right, y, STR_COMPANY_LEAGUE_COMPANY_NAME); - y += this->line_height; - } - } - - void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override - { - if (widget != WID_CL_BACKGROUND) return; - - this->ordinal_width = 0; - for (uint i = 0; i < MAX_COMPANIES; i++) { - this->ordinal_width = std::max(this->ordinal_width, GetStringBoundingBox(STR_ORDINAL_NUMBER_1ST + i).width); - } - this->ordinal_width += 5; // Keep some extra spacing - - uint widest_width = 0; - uint widest_title = 0; - for (uint i = 0; i < lengthof(_performance_titles); i++) { - uint width = GetStringBoundingBox(_performance_titles[i]).width; - if (width > widest_width) { - widest_title = i; - widest_width = width; - } - } - - Dimension d = GetSpriteSize(SPR_COMPANY_ICON); - this->icon_width = d.width + 2; - this->line_height = std::max(d.height + 2, FONT_HEIGHT_NORMAL); - - for (const Company *c : Company::Iterate()) { - SetDParam(0, c->index); - SetDParam(1, c->index); - SetDParam(2, _performance_titles[widest_title]); - widest_width = std::max(widest_width, GetStringBoundingBox(STR_COMPANY_LEAGUE_COMPANY_NAME).width); - } - - this->text_width = widest_width + 30; // Keep some extra spacing - - size->width = WD_FRAMERECT_LEFT + this->ordinal_width + WD_FRAMERECT_RIGHT + this->icon_width + WD_FRAMERECT_LEFT + this->text_width + WD_FRAMERECT_RIGHT; - size->height = WD_FRAMERECT_TOP + this->line_height * MAX_COMPANIES + WD_FRAMERECT_BOTTOM; - } - - - void OnGameTick() override - { - if (this->companies.NeedResort()) { - this->SetDirty(); - } - } - - /** - * Some data on this window has become invalid. - * @param data Information about the changed data. - * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. - */ - void OnInvalidateData(int data = 0, bool gui_scope = true) override - { - if (data == 0) { - /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */ - this->companies.ForceRebuild(); - } else { - this->companies.ForceResort(); - } - } -}; - -static const NWidgetPart _nested_company_league_widgets[] = { - NWidget(NWID_HORIZONTAL), - NWidget(WWT_CLOSEBOX, COLOUR_BROWN), - NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_COMPANY_LEAGUE_TABLE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_SHADEBOX, COLOUR_BROWN), - NWidget(WWT_STICKYBOX, COLOUR_BROWN), - EndContainer(), - NWidget(WWT_PANEL, COLOUR_BROWN, WID_CL_BACKGROUND), SetMinimalSize(400, 0), SetMinimalTextLines(15, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM), -}; - -static WindowDesc _company_league_desc( - WDP_AUTO, "league", 0, 0, - WC_COMPANY_LEAGUE, WC_NONE, - 0, - _nested_company_league_widgets, lengthof(_nested_company_league_widgets) -); - -void ShowCompanyLeagueTable() -{ - AllocateWindowDescFront(&_company_league_desc, 0); -} - /*****************************/ /* PERFORMANCE RATING DETAIL */ /*****************************/ @@ -1398,18 +1207,18 @@ struct PerformanceRatingDetailWindow : Window { { switch (widget) { case WID_PRD_SCORE_FIRST: - this->bar_height = FONT_HEIGHT_NORMAL + 4; - size->height = this->bar_height + 2 * WD_MATRIX_TOP; + this->bar_height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.fullbevel.Vertical(); + size->height = this->bar_height + WidgetDimensions::scaled.matrix.Vertical(); uint score_info_width = 0; for (uint i = SCORE_BEGIN; i < SCORE_END; i++) { score_info_width = std::max(score_info_width, GetStringBoundingBox(STR_PERFORMANCE_DETAIL_VEHICLES + i).width); } SetDParamMaxValue(0, 1000); - score_info_width += GetStringBoundingBox(STR_BLACK_COMMA).width + WD_FRAMERECT_LEFT; + score_info_width += GetStringBoundingBox(STR_BLACK_COMMA).width + WidgetDimensions::scaled.hsep_wide; SetDParamMaxValue(0, 100); - this->bar_width = GetStringBoundingBox(STR_PERFORMANCE_DETAIL_PERCENT).width + 20; // Wide bars! + this->bar_width = GetStringBoundingBox(STR_PERFORMANCE_DETAIL_PERCENT).width + WidgetDimensions::scaled.hsep_indent * 2; // Wide bars! /* At this number we are roughly at the max; it can become wider, * but then you need at 1000 times more money. At that time you're @@ -1435,9 +1244,9 @@ struct PerformanceRatingDetailWindow : Window { SetDParam(1, max); uint score_detail_width = GetStringBoundingBox(STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY).width; - size->width = 7 + score_info_width + 5 + this->bar_width + 5 + score_detail_width + 7; - uint left = 7; - uint right = size->width - 7; + size->width = WidgetDimensions::scaled.frametext.Horizontal() + score_info_width + WidgetDimensions::scaled.hsep_wide + this->bar_width + WidgetDimensions::scaled.hsep_wide + score_detail_width; + uint left = WidgetDimensions::scaled.frametext.left; + uint right = size->width - WidgetDimensions::scaled.frametext.right; bool rtl = _current_text_dir == TD_RTL; this->score_info_left = rtl ? right - score_info_width : left; @@ -1446,8 +1255,8 @@ struct PerformanceRatingDetailWindow : Window { this->score_detail_left = rtl ? left : right - score_detail_width; this->score_detail_right = rtl ? left + score_detail_width : right; - this->bar_left = left + (rtl ? score_detail_width : score_info_width) + 5; - this->bar_right = this->bar_left + this->bar_width; + this->bar_left = left + (rtl ? score_detail_width : score_info_width) + WidgetDimensions::scaled.hsep_wide; + this->bar_right = this->bar_left + this->bar_width - 1; break; } } @@ -1460,9 +1269,9 @@ struct PerformanceRatingDetailWindow : Window { if (IsInsideMM(widget, WID_PRD_COMPANY_FIRST, WID_PRD_COMPANY_LAST + 1)) { if (this->IsWidgetDisabled(widget)) return; CompanyID cid = (CompanyID)(widget - WID_PRD_COMPANY_FIRST); - int offset = (cid == this->company) ? 1 : 0; + int offset = (cid == this->company) ? WidgetDimensions::scaled.pressed : 0; Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON); - DrawCompanyIcon(cid, (r.left + r.right - sprite_size.width) / 2 + offset, (r.top + r.bottom - sprite_size.height) / 2 + offset); + DrawCompanyIcon(cid, CenterBounds(r.left, r.right, sprite_size.width) + offset, CenterBounds(r.top, r.bottom, sprite_size.height) + offset); return; } @@ -1485,8 +1294,8 @@ struct PerformanceRatingDetailWindow : Window { needed = SCORE_MAX; } - uint bar_top = r.top + WD_MATRIX_TOP; - uint text_top = bar_top + 2; + uint bar_top = CenterBounds(r.top, r.bottom, this->bar_height); + uint text_top = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL); DrawString(this->score_info_left, this->score_info_right, text_top, STR_PERFORMANCE_DETAIL_VEHICLES + score_type); @@ -1504,8 +1313,8 @@ struct PerformanceRatingDetailWindow : Window { } /* Draw the bar */ - if (x != this->bar_left) GfxFillRect(this->bar_left, bar_top, x, bar_top + this->bar_height, rtl ? colour_notdone : colour_done); - if (x != this->bar_right) GfxFillRect(x, bar_top, this->bar_right, bar_top + this->bar_height, rtl ? colour_done : colour_notdone); + if (x != this->bar_left) GfxFillRect(this->bar_left, bar_top, x, bar_top + this->bar_height - 1, rtl ? colour_notdone : colour_done); + if (x != this->bar_right) GfxFillRect(x, bar_top, this->bar_right, bar_top + this->bar_height - 1, rtl ? colour_done : colour_notdone); /* Draw it */ SetDParam(0, Clamp(val, 0, needed) * 100 / needed); @@ -1636,7 +1445,7 @@ static const NWidgetPart _nested_performance_rating_detail_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_BROWN), EndContainer(), NWidget(WWT_PANEL, COLOUR_BROWN), - NWidgetFunction(MakeCompanyButtonRowsGraphGUI), SetPadding(0, 1, 1, 2), + NWidgetFunction(MakeCompanyButtonRowsGraphGUI), SetPadding(2), EndContainer(), NWidgetFunction(MakePerformanceDetailPanels), }; diff --git a/src/graph_gui.h b/src/graph_gui.h index 8338878c017df..32c777645696e 100644 --- a/src/graph_gui.h +++ b/src/graph_gui.h @@ -16,7 +16,6 @@ void ShowDeliveredCargoGraph(); void ShowPerformanceHistoryGraph(); void ShowCompanyValueGraph(); void ShowCargoPaymentRates(); -void ShowCompanyLeagueTable(); void ShowPerformanceRatingDetail(); #endif /* GRAPH_GUI_H */ diff --git a/src/ground_vehicle.cpp b/src/ground_vehicle.cpp index f6e44c2e29f01..d627e0f80b925 100644 --- a/src/ground_vehicle.cpp +++ b/src/ground_vehicle.cpp @@ -141,7 +141,7 @@ int GroundVehicle::GetAcceleration() const } /* Air drag; the air drag coefficient is in an arbitrary NewGRF-unit, * so we need some magic conversion factor. */ - resistance += (area * this->gcache.cached_air_drag * speed * speed) / 1000; + resistance += static_cast(area) * this->gcache.cached_air_drag * speed * speed / 1000; resistance += this->GetSlopeResistance(); diff --git a/src/group.h b/src/group.h index 6d55c938538cc..7cba5ac538991 100644 --- a/src/group.h +++ b/src/group.h @@ -23,15 +23,14 @@ extern GroupPool _group_pool; ///< Pool of groups. /** Statistics and caches on the vehicles in a group. */ struct GroupStatistics { - uint16 num_vehicle; ///< Number of vehicles. + Money profit_last_year; ///< Sum of profits for all vehicles. + Money profit_last_year_min_age; ///< Sum of profits for vehicles considered for profit statistics. uint16 *num_engines; ///< Caches the number of engines of each type the company owns. - + uint16 num_vehicle; ///< Number of vehicles. + uint16 num_vehicle_min_age; ///< Number of vehicles considered for profit statistics; bool autoreplace_defined; ///< Are any autoreplace rules set? bool autoreplace_finished; ///< Have all autoreplacement finished? - uint16 num_profit_vehicle; ///< Number of vehicles considered for profit statistics; - Money profit_last_year; ///< Sum of profits for all vehicles. - GroupStatistics(); ~GroupStatistics(); @@ -39,8 +38,10 @@ struct GroupStatistics { void ClearProfits() { - this->num_profit_vehicle = 0; this->profit_last_year = 0; + + this->num_vehicle_min_age = 0; + this->profit_last_year_min_age = 0; } void ClearAutoreplace() @@ -55,7 +56,8 @@ struct GroupStatistics { static void CountVehicle(const Vehicle *v, int delta); static void CountEngine(const Vehicle *v, int delta); - static void VehicleReachedProfitAge(const Vehicle *v); + static void AddProfitLastYear(const Vehicle *v); + static void VehicleReachedMinAge(const Vehicle *v); static void UpdateProfits(); static void UpdateAfterLoad(); @@ -104,8 +106,8 @@ static inline bool IsAllGroupID(GroupID id_g) uint GetGroupNumEngines(CompanyID company, GroupID id_g, EngineID id_e); uint GetGroupNumVehicle(CompanyID company, GroupID id_g, VehicleType type); -uint GetGroupNumProfitVehicle(CompanyID company, GroupID id_g, VehicleType type); -Money GetGroupProfitLastYear(CompanyID company, GroupID id_g, VehicleType type); +uint GetGroupNumVehicleMinAge(CompanyID company, GroupID id_g, VehicleType type); +Money GetGroupProfitLastYearMinAge(CompanyID company, GroupID id_g, VehicleType type); void SetTrainGroupID(Train *v, GroupID grp); void UpdateTrainGroupID(Train *v); diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index b6d1927097dfe..00c7c82b066f2 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -43,8 +43,9 @@ GroupStatistics::~GroupStatistics() void GroupStatistics::Clear() { this->num_vehicle = 0; - this->num_profit_vehicle = 0; this->profit_last_year = 0; + this->num_vehicle_min_age = 0; + this->profit_last_year_min_age = 0; /* This is also called when NewGRF change. So the number of engines might have changed. Reallocate. */ free(this->num_engines); @@ -136,13 +137,15 @@ void GroupStatistics::Clear() GroupStatistics &stats = GroupStatistics::Get(v); stats_all.num_vehicle += delta; + stats_all.profit_last_year += v->GetDisplayProfitLastYear() * delta; stats.num_vehicle += delta; + stats.profit_last_year += v->GetDisplayProfitLastYear() * delta; if (v->age > VEHICLE_PROFIT_MIN_AGE) { - stats_all.num_profit_vehicle += delta; - stats_all.profit_last_year += v->GetDisplayProfitLastYear() * delta; - stats.num_profit_vehicle += delta; - stats.profit_last_year += v->GetDisplayProfitLastYear() * delta; + stats_all.num_vehicle_min_age += delta; + stats_all.profit_last_year_min_age += v->GetDisplayProfitLastYear() * delta; + stats.num_vehicle_min_age += delta; + stats.profit_last_year_min_age += v->GetDisplayProfitLastYear() * delta; } } @@ -159,19 +162,31 @@ void GroupStatistics::Clear() } /** - * Add a vehicle to the profit sum of its group. + * Add a vehicle's last year profit to the profit sum of its group. */ -/* static */ void GroupStatistics::VehicleReachedProfitAge(const Vehicle *v) +/* static */ void GroupStatistics::AddProfitLastYear(const Vehicle *v) { GroupStatistics &stats_all = GroupStatistics::GetAllGroup(v); GroupStatistics &stats = GroupStatistics::Get(v); - stats_all.num_profit_vehicle++; stats_all.profit_last_year += v->GetDisplayProfitLastYear(); - stats.num_profit_vehicle++; stats.profit_last_year += v->GetDisplayProfitLastYear(); } +/** + * Add a vehicle to the profit sum of its group. + */ +/* static */ void GroupStatistics::VehicleReachedMinAge(const Vehicle *v) +{ + GroupStatistics &stats_all = GroupStatistics::GetAllGroup(v); + GroupStatistics &stats = GroupStatistics::Get(v); + + stats_all.num_vehicle_min_age++; + stats_all.profit_last_year_min_age += v->GetDisplayProfitLastYear(); + stats.num_vehicle_min_age++; + stats.profit_last_year_min_age += v->GetDisplayProfitLastYear(); +} + /** * Recompute the profits for all groups. */ @@ -191,7 +206,10 @@ void GroupStatistics::Clear() } for (const Vehicle *v : Vehicle::Iterate()) { - if (v->IsPrimaryVehicle() && v->age > VEHICLE_PROFIT_MIN_AGE) GroupStatistics::VehicleReachedProfitAge(v); + if (v->IsPrimaryVehicle()) { + GroupStatistics::AddProfitLastYear(v); + if (v->age > VEHICLE_PROFIT_MIN_AGE) GroupStatistics::VehicleReachedMinAge(v); + } } } @@ -510,10 +528,10 @@ std::tuple CmdAddVehicleGroup(DoCommandFlag flags, GroupID if (new_g == NEW_GROUP) { /* Create new group. */ - auto [ret, group_id] = CmdCreateGroup(flags, v->type, INVALID_GROUP); - if (ret.Failed()) return { ret, group_id }; + auto [ret, new_group_id] = CmdCreateGroup(flags, v->type, INVALID_GROUP); + if (ret.Failed()) return { ret, new_group_id }; - new_g = group_id; + new_g = new_group_id; } if (flags & DC_EXEC) { @@ -789,30 +807,30 @@ uint GetGroupNumVehicle(CompanyID company, GroupID id_g, VehicleType type) * @param type The vehicle type of the group * @return The number of vehicles above profit minimum age in the group */ -uint GetGroupNumProfitVehicle(CompanyID company, GroupID id_g, VehicleType type) +uint GetGroupNumVehicleMinAge(CompanyID company, GroupID id_g, VehicleType type) { uint count = 0; for (const Group *g : Group::Iterate()) { - if (g->parent == id_g) count += GetGroupNumProfitVehicle(company, g->index, type); + if (g->parent == id_g) count += GetGroupNumVehicleMinAge(company, g->index, type); } - return count + GroupStatistics::Get(company, id_g, type).num_profit_vehicle; + return count + GroupStatistics::Get(company, id_g, type).num_vehicle_min_age; } /** - * Get last year's profit for the group with GroupID - * id_g and its sub-groups. + * Get last year's profit of vehicles above minimum age + * for the group with GroupID id_g and its sub-groups. * @param company The company the group belongs to * @param id_g The GroupID of the group used * @param type The vehicle type of the group - * @return Last year's profit for the group + * @return Last year's profit of vehicles above minimum age for the group */ -Money GetGroupProfitLastYear(CompanyID company, GroupID id_g, VehicleType type) +Money GetGroupProfitLastYearMinAge(CompanyID company, GroupID id_g, VehicleType type) { Money sum = 0; for (const Group *g : Group::Iterate()) { - if (g->parent == id_g) sum += GetGroupProfitLastYear(company, g->index, type); + if (g->parent == id_g) sum += GetGroupProfitLastYearMinAge(company, g->index, type); } - return sum + GroupStatistics::Get(company, id_g, type).profit_last_year; + return sum + GroupStatistics::Get(company, id_g, type).profit_last_year_min_age; } void RemoveAllGroupsForCompany(const CompanyID company) diff --git a/src/group_gui.cpp b/src/group_gui.cpp index 503ddddd9e555..5766ce0380928 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -27,6 +27,7 @@ #include "gui.h" #include "group_cmd.h" #include "vehicle_cmd.h" +#include "gfx_func.h" #include "widgets/group_widget.h" @@ -34,8 +35,6 @@ #include "safeguards.h" -static const int LEVEL_WIDTH = 10; ///< Indenting width of a sub-group in pixels - typedef GUIList GUIGroupList; static const NWidgetPart _nested_group_widgets[] = { @@ -48,7 +47,7 @@ static const NWidgetPart _nested_group_widgets[] = { EndContainer(), NWidget(NWID_HORIZONTAL), /* left part */ - NWidget(NWID_VERTICAL), + NWidget(NWID_VERTICAL, NC_BIGFIRST), NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_ALL_VEHICLES), SetFill(1, 0), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_DEFAULT_VEHICLES), SetFill(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -56,7 +55,7 @@ static const NWidgetPart _nested_group_widgets[] = { SetFill(1, 0), SetResize(0, 1), SetScrollbar(WID_GL_LIST_GROUP_SCROLLBAR), NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_GL_LIST_GROUP_SCROLLBAR), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_INFO), SetFill(1, 1), SetMinimalTextLines(3, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_INFO), SetFill(1, 1), SetMinimalTextLines(3, WidgetDimensions::unscaled.framerect.Vertical()), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GL_CREATE_GROUP), SetDataTip(SPR_GROUP_CREATE_TRAIN, STR_GROUP_CREATE_TOOLTIP), @@ -74,14 +73,21 @@ static const NWidgetPart _nested_group_widgets[] = { /* right part */ NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GL_GROUP_BY_ORDER), SetMinimalSize(81, 12), SetDataTip(STR_STATION_VIEW_GROUP, STR_TOOLTIP_GROUP_ORDER), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_GROUP_BY_DROPDOWN), SetMinimalSize(167, 12), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER), - NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetResize(1, 0), EndContainer(), - EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_SORT_BY_ORDER), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_SORT_BY_DROPDOWN), SetMinimalSize(167, 12), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA), - NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetResize(1, 0), EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GL_GROUP_BY_ORDER), SetFill(1, 0), SetMinimalSize(0, 12), SetDataTip(STR_STATION_VIEW_GROUP, STR_TOOLTIP_GROUP_ORDER), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_SORT_BY_ORDER), SetFill(1, 0), SetMinimalSize(0, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), + EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_GROUP_BY_DROPDOWN), SetFill(1, 0), SetMinimalSize(0, 12), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_SORT_BY_DROPDOWN), SetFill(1, 0), SetMinimalSize(0, 12), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA), + EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetResize(1, 0), EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_FILTER_BY_CARGO), SetMinimalSize(0, 12), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_FILTER_CRITERIA), + NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetResize(1, 0), EndContainer(), + EndContainer(), + EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_MATRIX, COLOUR_GREY, WID_GL_LIST_VEHICLE), SetMinimalSize(248, 0), SetMatrixDataTip(1, 0, STR_NULL), SetResize(1, 1), SetFill(1, 0), SetScrollbar(WID_GL_LIST_VEHICLE_SCROLLBAR), @@ -118,7 +124,6 @@ class VehicleGroupWindow : public BaseVehicleListWindow { VGC_END }; - VehicleID vehicle_sel; ///< Selected vehicle GroupID group_sel; ///< Selected group (for drag/drop) GroupID group_rename; ///< Group being renamed, INVALID_GROUP if none GroupID group_over; ///< Group over which a vehicle is dragged, INVALID_GROUP if none @@ -207,7 +212,7 @@ class VehicleGroupWindow : public BaseVehicleListWindow { this->tiny_step_height = this->column_size[VGC_FOLD].height; this->column_size[VGC_NAME] = maxdim(GetStringBoundingBox(STR_GROUP_DEFAULT_TRAINS + this->vli.vtype), GetStringBoundingBox(STR_GROUP_ALL_TRAINS + this->vli.vtype)); - this->column_size[VGC_NAME].width = std::max(170u, this->column_size[VGC_NAME].width); + this->column_size[VGC_NAME].width = std::max(170u, this->column_size[VGC_NAME].width) + WidgetDimensions::scaled.hsep_indent; this->tiny_step_height = std::max(this->tiny_step_height, this->column_size[VGC_NAME].height); this->column_size[VGC_PROTECT] = GetSpriteSize(SPR_GROUP_REPLACE_PROTECT); @@ -231,16 +236,16 @@ class VehicleGroupWindow : public BaseVehicleListWindow { this->column_size[VGC_NUMBER] = GetStringBoundingBox(STR_GROUP_COUNT_WITH_SUBGROUP); this->tiny_step_height = std::max(this->tiny_step_height, this->column_size[VGC_NUMBER].height); - this->tiny_step_height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + this->tiny_step_height += WidgetDimensions::scaled.framerect.Vertical(); - return WD_FRAMERECT_LEFT + 8 + - this->column_size[VGC_FOLD].width + 2 + - this->column_size[VGC_NAME].width + 8 + - this->column_size[VGC_PROTECT].width + 2 + - this->column_size[VGC_AUTOREPLACE].width + 2 + - this->column_size[VGC_PROFIT].width + 2 + - this->column_size[VGC_NUMBER].width + 2 + - WD_FRAMERECT_RIGHT; + return WidgetDimensions::scaled.framerect.left + + this->column_size[VGC_FOLD].width + WidgetDimensions::scaled.hsep_normal + + this->column_size[VGC_NAME].width + WidgetDimensions::scaled.hsep_wide + + this->column_size[VGC_PROTECT].width + WidgetDimensions::scaled.hsep_normal + + this->column_size[VGC_AUTOREPLACE].width + WidgetDimensions::scaled.hsep_normal + + this->column_size[VGC_PROFIT].width + WidgetDimensions::scaled.hsep_normal + + this->column_size[VGC_NUMBER].width + + WidgetDimensions::scaled.framerect.right; } /** @@ -257,7 +262,7 @@ class VehicleGroupWindow : public BaseVehicleListWindow { { /* Highlight the group if a vehicle is dragged over it */ if (g_id == this->group_over) { - GfxFillRect(left + WD_FRAMERECT_LEFT, y + WD_FRAMERECT_TOP + 1, right - WD_FRAMERECT_RIGHT, y + this->tiny_step_height - WD_FRAMERECT_BOTTOM - 1, _colour_gradient[COLOUR_GREY][7]); + GfxFillRect(left + WidgetDimensions::scaled.bevel.left, y + WidgetDimensions::scaled.framerect.top, right - WidgetDimensions::scaled.bevel.right, y + this->tiny_step_height - 1 - WidgetDimensions::scaled.framerect.bottom, _colour_gradient[COLOUR_GREY][7]); } if (g_id == NEW_GROUP) return; @@ -268,7 +273,7 @@ class VehicleGroupWindow : public BaseVehicleListWindow { bool rtl = _current_text_dir == TD_RTL; /* draw fold / unfold button */ - int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_FOLD].width + 1 : left + WD_FRAMERECT_LEFT + 8; + int x = rtl ? right - WidgetDimensions::scaled.framerect.right - this->column_size[VGC_FOLD].width + 1 : left + WidgetDimensions::scaled.framerect.left; if (has_children) { DrawSprite(Group::Get(g_id)->folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED, PAL_NONE, rtl ? x - indent : x + indent, y + (this->tiny_step_height - this->column_size[VGC_FOLD].height) / 2); } @@ -283,27 +288,27 @@ class VehicleGroupWindow : public BaseVehicleListWindow { SetDParam(0, g_id); str = STR_GROUP_NAME; } - x = rtl ? x - 2 - this->column_size[VGC_NAME].width : x + 2 + this->column_size[VGC_FOLD].width; + x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_NAME].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_FOLD].width; DrawString(x + (rtl ? 0 : indent), x + this->column_size[VGC_NAME].width - 1 - (rtl ? indent : 0), y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour); /* draw autoreplace protection */ - x = rtl ? x - 8 - this->column_size[VGC_PROTECT].width : x + 8 + this->column_size[VGC_NAME].width; + x = rtl ? x - WidgetDimensions::scaled.hsep_wide - this->column_size[VGC_PROTECT].width : x + WidgetDimensions::scaled.hsep_wide + this->column_size[VGC_NAME].width; if (protection) DrawSprite(SPR_GROUP_REPLACE_PROTECT, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROTECT].height) / 2); /* draw autoreplace status */ - x = rtl ? x - 2 - this->column_size[VGC_AUTOREPLACE].width : x + 2 + this->column_size[VGC_PROTECT].width; + x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_AUTOREPLACE].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_PROTECT].width; if (stats.autoreplace_defined) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, stats.autoreplace_finished ? PALETTE_CRASH : PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_AUTOREPLACE].height) / 2); /* draw the profit icon */ - x = rtl ? x - 2 - this->column_size[VGC_PROFIT].width : x + 2 + this->column_size[VGC_AUTOREPLACE].width; + x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_PROFIT].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_AUTOREPLACE].width; SpriteID spr; - uint num_profit_vehicle = GetGroupNumProfitVehicle(this->vli.company, g_id, this->vli.vtype); - Money profit_last_year = GetGroupProfitLastYear(this->vli.company, g_id, this->vli.vtype); - if (num_profit_vehicle == 0) { + uint num_vehicle_min_age = GetGroupNumVehicleMinAge(this->vli.company, g_id, this->vli.vtype); + Money profit_last_year_min_age = GetGroupProfitLastYearMinAge(this->vli.company, g_id, this->vli.vtype); + if (num_vehicle_min_age == 0) { spr = SPR_PROFIT_NA; - } else if (profit_last_year < 0) { + } else if (profit_last_year_min_age < 0) { spr = SPR_PROFIT_NEGATIVE; - } else if (profit_last_year < VEHICLE_PROFIT_THRESHOLD * num_profit_vehicle) { + } else if (profit_last_year_min_age < VEHICLE_PROFIT_THRESHOLD * num_vehicle_min_age) { spr = SPR_PROFIT_SOME; } else { spr = SPR_PROFIT_LOT; @@ -311,7 +316,7 @@ class VehicleGroupWindow : public BaseVehicleListWindow { DrawSprite(spr, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROFIT].height) / 2); /* draw the number of vehicles of the group */ - x = rtl ? x - 2 - this->column_size[VGC_NUMBER].width : x + 2 + this->column_size[VGC_PROFIT].width; + x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_NUMBER].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_PROFIT].width; int num_vehicle_with_subgroups = GetGroupNumVehicle(this->vli.company, g_id, this->vli.vtype); int num_vehicle = GroupStatistics::Get(this->vli.company, g_id, this->vli.vtype).num_vehicle; if (IsAllGroupID(g_id) || IsDefaultGroupID(g_id) || num_vehicle_with_subgroups == num_vehicle) { @@ -349,7 +354,6 @@ class VehicleGroupWindow : public BaseVehicleListWindow { this->group_sb = this->GetScrollbar(WID_GL_LIST_GROUP_SCROLLBAR); this->vli.index = ALL_GROUP; - this->vehicle_sel = INVALID_VEHICLE; this->group_sel = INVALID_GROUP; this->group_rename = INVALID_GROUP; this->group_over = INVALID_GROUP; @@ -383,26 +387,11 @@ class VehicleGroupWindow : public BaseVehicleListWindow { void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { - case WID_GL_LIST_GROUP: { + case WID_GL_LIST_GROUP: size->width = this->ComputeGroupInfoSize(); resize->height = this->tiny_step_height; - - /* Minimum height is the height of the list widget minus all and default vehicles... */ - size->height = 4 * GetVehicleListHeight(this->vli.vtype, this->tiny_step_height); - - /* ... minus the buttons at the bottom ... */ - uint max_icon_height = GetSpriteSize(this->GetWidget(WID_GL_CREATE_GROUP)->widget_data).height; - max_icon_height = std::max(max_icon_height, GetSpriteSize(this->GetWidget(WID_GL_RENAME_GROUP)->widget_data).height); - max_icon_height = std::max(max_icon_height, GetSpriteSize(this->GetWidget(WID_GL_DELETE_GROUP)->widget_data).height); - max_icon_height = std::max(max_icon_height, GetSpriteSize(this->GetWidget(WID_GL_REPLACE_PROTECTION)->widget_data).height); - - /* ... minus the height of the group info ... */ - max_icon_height += (FONT_HEIGHT_NORMAL * 3) + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; - - /* Get a multiple of tiny_step_height of that amount */ - size->height = Ceil(size->height - max_icon_height, tiny_step_height); + fill->height = this->tiny_step_height; break; - } case WID_GL_ALL_VEHICLES: case WID_GL_DEFAULT_VEHICLES: @@ -424,6 +413,20 @@ class VehicleGroupWindow : public BaseVehicleListWindow { size->height = 4 * resize->height; break; + case WID_GL_GROUP_BY_DROPDOWN: + size->width = GetStringListWidth(this->vehicle_group_by_names) + padding.width; + break; + + case WID_GL_SORT_BY_DROPDOWN: + size->width = GetStringListWidth(this->vehicle_group_none_sorter_names); + size->width = std::max(size->width, GetStringListWidth(this->vehicle_group_shared_orders_sorter_names)); + size->width += padding.width; + break; + + case WID_GL_FILTER_BY_CARGO: + size->width = GetStringListWidth(this->cargo_filter_texts) + padding.width; + break; + case WID_GL_MANAGE_VEHICLES_DROPDOWN: { Dimension d = this->GetActionDropdownSize(true, true); d.height += padding.height; @@ -466,6 +469,10 @@ class VehicleGroupWindow : public BaseVehicleListWindow { void SetStringParameters(int widget) const override { switch (widget) { + case WID_GL_FILTER_BY_CARGO: + SetDParam(0, this->cargo_filter_texts[this->cargo_filter_criteria]); + break; + case WID_GL_AVAILABLE_VEHICLES: SetDParam(0, STR_VEHICLE_LIST_AVAILABLE_TRAINS + this->vli.vtype); break; @@ -545,6 +552,9 @@ class VehicleGroupWindow : public BaseVehicleListWindow { /* Set text of "sort by" dropdown widget. */ this->GetWidget(WID_GL_SORT_BY_DROPDOWN)->widget_data = this->GetVehicleSorterNames()[this->vehgroups.SortType()]; + /* Set text of filter by cargo dropdown */ + this->GetWidget(WID_GL_FILTER_BY_CARGO)->widget_data = this->cargo_filter_texts[this->cargo_filter_criteria]; + this->DrawWidgets(); } @@ -572,25 +582,23 @@ class VehicleGroupWindow : public BaseVehicleListWindow { occupancy += v->trip_occupancy; } - const int left = r.left + WD_FRAMERECT_LEFT + 8; - const int right = r.right - WD_FRAMERECT_RIGHT - 8; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); - int y = r.top + WD_FRAMERECT_TOP; - DrawString(left, right, y, STR_GROUP_PROFIT_THIS_YEAR, TC_BLACK); + DrawString(tr, STR_GROUP_PROFIT_THIS_YEAR, TC_BLACK); SetDParam(0, this_year); - DrawString(left, right, y, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT); + DrawString(tr, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT); - y += FONT_HEIGHT_NORMAL; - DrawString(left, right, y, STR_GROUP_PROFIT_LAST_YEAR, TC_BLACK); + tr.top += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_GROUP_PROFIT_LAST_YEAR, TC_BLACK); SetDParam(0, last_year); - DrawString(left, right, y, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT); + DrawString(tr, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT); - y += FONT_HEIGHT_NORMAL; - DrawString(left, right, y, STR_GROUP_OCCUPANCY, TC_BLACK); + tr.top += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_GROUP_OCCUPANCY, TC_BLACK); const size_t vehicle_count = this->vehicles.size(); if (vehicle_count > 0) { SetDParam(0, occupancy / vehicle_count); - DrawString(left, right, y, STR_GROUP_OCCUPANCY_VALUE, TC_BLACK, SA_RIGHT); + DrawString(tr, STR_GROUP_OCCUPANCY_VALUE, TC_BLACK, SA_RIGHT); } break; @@ -604,7 +612,7 @@ class VehicleGroupWindow : public BaseVehicleListWindow { assert(g->owner == this->owner); - DrawGroupInfo(y1, r.left, r.right, g->index, this->indents[i] * LEVEL_WIDTH, HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION), g->folded || (i + 1 < (int)this->groups.size() && indents[i + 1] > this->indents[i])); + DrawGroupInfo(y1, r.left, r.right, g->index, this->indents[i] * WidgetDimensions::scaled.hsep_indent, HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION), g->folded || (i + 1 < (int)this->groups.size() && indents[i + 1] > this->indents[i])); y1 += this->tiny_step_height; } @@ -621,14 +629,14 @@ class VehicleGroupWindow : public BaseVehicleListWindow { case WID_GL_LIST_VEHICLE: if (this->vli.index != ALL_GROUP && this->grouping == GB_NONE) { /* Mark vehicles which are in sub-groups (only if we are not using shared order coalescing) */ - int y = r.top; + Rect mr = r.WithHeight(this->resize.step_height); uint max = static_cast(std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size())); for (uint i = this->vscroll->GetPosition(); i < max; ++i) { const Vehicle *v = this->vehgroups[i].GetSingleVehicle(); if (v->group_id != this->vli.index) { - GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 2, _colour_gradient[COLOUR_GREY][3], FILLRECT_CHECKER); + GfxFillRect(mr.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[COLOUR_GREY][3], FILLRECT_CHECKER); } - y += this->resize.step_height; + mr = mr.Translate(0, this->resize.step_height); } } @@ -662,6 +670,10 @@ class VehicleGroupWindow : public BaseVehicleListWindow { ShowDropDownMenu(this, this->GetVehicleSorterNames(), this->vehgroups.SortType(), WID_GL_SORT_BY_DROPDOWN, 0, (this->vli.vtype == VEH_TRAIN || this->vli.vtype == VEH_ROAD) ? 0 : (1 << 10)); return; + case WID_GL_FILTER_BY_CARGO: // Select filtering criteria dropdown menu + ShowDropDownMenu(this, this->cargo_filter_texts, this->cargo_filter_criteria, WID_GL_FILTER_BY_CARGO, 0, 0); + break; + case WID_GL_ALL_VEHICLES: // All vehicles button if (!IsAllGroupID(this->vli.index)) { this->vli.index = ALL_GROUP; @@ -686,8 +698,8 @@ class VehicleGroupWindow : public BaseVehicleListWindow { /* The group has children, check if the user clicked the fold / unfold button. */ NWidgetCore *group_display = this->GetWidget(widget); int x = _current_text_dir == TD_RTL ? - group_display->pos_x + group_display->current_x - WD_FRAMERECT_RIGHT - 8 - this->indents[id_g] * LEVEL_WIDTH - this->column_size[VGC_FOLD].width : - group_display->pos_x + WD_FRAMERECT_LEFT + 8 + this->indents[id_g] * LEVEL_WIDTH; + group_display->pos_x + group_display->current_x - WidgetDimensions::scaled.framerect.right - this->indents[id_g] * WidgetDimensions::scaled.hsep_indent - this->column_size[VGC_FOLD].width : + group_display->pos_x + WidgetDimensions::scaled.framerect.left + this->indents[id_g] * WidgetDimensions::scaled.hsep_indent; if (click_count > 1 || (pt.x >= x && pt.x < (int)(x + this->column_size[VGC_FOLD].width))) { GroupID g = this->vli.index; @@ -869,7 +881,7 @@ class VehicleGroupWindow : public BaseVehicleListWindow { uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP); GroupID new_g = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index; - Command::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, 0, new_g, vindex, _ctrl_pressed || this->grouping == GB_SHARED_ORDERS); + Command::Post(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE, new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr, new_g, vindex, _ctrl_pressed || this->grouping == GB_SHARED_ORDERS); break; } @@ -893,14 +905,14 @@ class VehicleGroupWindow : public BaseVehicleListWindow { } case GB_SHARED_ORDERS: { - const Vehicle *v = vehgroup.vehicles_begin[0]; - /* We do not support VehicleClicked() here since the contextual action may only make sense for individual vehicles */ - - if (vindex == v->index) { - if (vehgroup.NumVehicles() == 1) { - ShowVehicleViewWindow(v); - } else { - ShowVehicleListWindow(v); + if (!VehicleClicked(vehgroup)) { + const Vehicle* v = vehgroup.vehicles_begin[0]; + if (vindex == v->index) { + if (vehgroup.NumVehicles() == 1) { + ShowVehicleViewWindow(v); + } else { + ShowVehicleListWindow(v); + } } } break; @@ -945,6 +957,10 @@ class VehicleGroupWindow : public BaseVehicleListWindow { this->vehgroups.SetSortType(index); break; + case WID_GL_FILTER_BY_CARGO: // Select a cargo filter criteria + this->SetCargoFilterIndex(index); + break; + case WID_GL_MANAGE_VEHICLES_DROPDOWN: assert(this->vehicles.size() != 0); diff --git a/src/heightmap.cpp b/src/heightmap.cpp index 0c726371ce362..2964a5c1299d9 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.cpp @@ -188,7 +188,7 @@ static bool ReadHeightmapPNG(const char *filename, uint *x, uint *y, byte **map) } if (map != nullptr) { - *map = MallocT(width * height); + *map = MallocT(static_cast(width) * height); ReadHeightmapPNGImageData(*map, png_ptr, info_ptr); } @@ -303,7 +303,7 @@ static bool ReadHeightmapBMP(const char *filename, uint *x, uint *y, byte **map) return false; } - *map = MallocT(info.width * info.height); + *map = MallocT(static_cast(info.width) * info.height); ReadHeightmapBMPImageData(*map, &info, &data); } @@ -341,12 +341,12 @@ static void GrayscaleToMapHeights(uint img_width, uint img_height, byte *map) switch (_settings_game.game_creation.heightmap_rotation) { default: NOT_REACHED(); case HM_COUNTER_CLOCKWISE: - width = MapSizeX(); - height = MapSizeY(); + width = Map::SizeX(); + height = Map::SizeY(); break; case HM_CLOCKWISE: - width = MapSizeY(); - height = MapSizeX(); + width = Map::SizeY(); + height = Map::SizeX(); break; } @@ -361,8 +361,8 @@ static void GrayscaleToMapHeights(uint img_width, uint img_height, byte *map) } if (_settings_game.construction.freeform_edges) { - for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0)); - for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y)); + for (uint x = 0; x < Map::SizeX(); x++) MakeVoid(TileXY(x, 0)); + for (uint y = 0; y < Map::SizeY(); y++) MakeVoid(TileXY(0, y)); } /* Form the landscape */ @@ -426,8 +426,8 @@ void FixSlopes() byte current_tile; /* Adjust height difference to maximum one horizontal/vertical change. */ - width = MapSizeX(); - height = MapSizeY(); + width = Map::SizeX(); + height = Map::SizeY(); /* Top and left edge */ for (row = 0; (uint)row < height; row++) { @@ -544,8 +544,8 @@ void LoadHeightmap(DetailedFileType dft, const char *filename) void FlatEmptyWorld(byte tile_height) { int edge_distance = _settings_game.construction.freeform_edges ? 0 : 2; - for (uint row = edge_distance; row < MapSizeY() - edge_distance; row++) { - for (uint col = edge_distance; col < MapSizeX() - edge_distance; col++) { + for (uint row = edge_distance; row < Map::SizeY() - edge_distance; row++) { + for (uint col = edge_distance; col < Map::SizeX() - edge_distance; col++) { SetTileHeight(TileXY(col, row), tile_height); } } diff --git a/src/highscore_gui.cpp b/src/highscore_gui.cpp index 0ccc288f05dee..f61bf46f37daa 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.cpp @@ -126,14 +126,14 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { void Close() override { if (!_networking) Command::Post(PM_PAUSED_NORMAL, false); // unpause - ShowHighscoreTable(this->window_number, this->rank); + if (_game_mode != GM_MENU) ShowHighscoreTable(this->window_number, this->rank); this->EndGameHighScoreBaseWindow::Close(); } void OnPaint() override { this->SetupHighScoreEndWindow(); - Point pt = this->GetTopLeft(ScaleGUITrad(640), ScaleGUITrad(480)); + Point pt = this->GetTopLeft(ScaleSpriteTrad(640), ScaleSpriteTrad(480)); const Company *c = Company::GetIfValid(_local_company); if (c == nullptr) return; @@ -144,11 +144,11 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { SetDParam(0, c->index); SetDParam(1, c->index); SetDParam(2, EndGameGetPerformanceTitleFromValue(c->old_economy[0].performance_history)); - DrawStringMultiLine(pt.x + ScaleGUITrad(15), pt.x + ScaleGUITrad(640) - ScaleGUITrad(25), pt.y + ScaleGUITrad(90), pt.y + ScaleGUITrad(160), STR_HIGHSCORE_PRESIDENT_OF_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(pt.x + ScaleSpriteTrad(15), pt.x + ScaleSpriteTrad(640) - ScaleSpriteTrad(25), pt.y + ScaleSpriteTrad(90), pt.y + ScaleSpriteTrad(160), STR_HIGHSCORE_PRESIDENT_OF_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER); } else { SetDParam(0, c->index); SetDParam(1, EndGameGetPerformanceTitleFromValue(c->old_economy[0].performance_history)); - DrawStringMultiLine(pt.x + ScaleGUITrad(36), pt.x + ScaleGUITrad(640), pt.y + ScaleGUITrad(140), pt.y + ScaleGUITrad(206), STR_HIGHSCORE_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(pt.x + ScaleSpriteTrad(36), pt.x + ScaleSpriteTrad(640), pt.y + ScaleSpriteTrad(140), pt.y + ScaleSpriteTrad(206), STR_HIGHSCORE_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER); } } }; @@ -185,24 +185,24 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { const HighScore *hs = _highscore_table[this->window_number]; this->SetupHighScoreEndWindow(); - Point pt = this->GetTopLeft(ScaleGUITrad(640), ScaleGUITrad(480)); + Point pt = this->GetTopLeft(ScaleSpriteTrad(640), ScaleSpriteTrad(480)); SetDParam(0, _settings_game.game_creation.ending_year); - DrawStringMultiLine(pt.x + ScaleGUITrad(70), pt.x + ScaleGUITrad(570), pt.y, pt.y + ScaleGUITrad(140), !_networking ? STR_HIGHSCORE_TOP_COMPANIES_WHO_REACHED : STR_HIGHSCORE_TOP_COMPANIES_NETWORK_GAME, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(pt.x + ScaleSpriteTrad(70), pt.x + ScaleSpriteTrad(570), pt.y, pt.y + ScaleSpriteTrad(140), !_networking ? STR_HIGHSCORE_TOP_COMPANIES_WHO_REACHED : STR_HIGHSCORE_TOP_COMPANIES_NETWORK_GAME, TC_FROMSTRING, SA_CENTER); /* Draw Highscore peepz */ for (uint8 i = 0; i < lengthof(_highscore_table[0]); i++) { SetDParam(0, i + 1); - DrawString(pt.x + ScaleGUITrad(40), pt.x + ScaleGUITrad(600), pt.y + ScaleGUITrad(140 + i * 55), STR_HIGHSCORE_POSITION); + DrawString(pt.x + ScaleSpriteTrad(40), pt.x + ScaleSpriteTrad(600), pt.y + ScaleSpriteTrad(140 + i * 55), STR_HIGHSCORE_POSITION); if (hs[i].company[0] != '\0') { TextColour colour = (this->rank == i) ? TC_RED : TC_BLACK; // draw new highscore in red SetDParamStr(0, hs[i].company); - DrawString(pt.x + ScaleGUITrad(71), pt.x + ScaleGUITrad(569), pt.y + ScaleGUITrad(140 + i * 55), STR_JUST_BIG_RAW_STRING, colour); + DrawString(pt.x + ScaleSpriteTrad(71), pt.x + ScaleSpriteTrad(569), pt.y + ScaleSpriteTrad(140 + i * 55), STR_JUST_BIG_RAW_STRING, colour); SetDParam(0, hs[i].title); SetDParam(1, hs[i].score); - DrawString(pt.x + ScaleGUITrad(71), pt.x + ScaleGUITrad(569), pt.y + ScaleGUITrad(140) + FONT_HEIGHT_LARGE + ScaleGUITrad(i * 55), STR_HIGHSCORE_STATS, colour); + DrawString(pt.x + ScaleSpriteTrad(71), pt.x + ScaleSpriteTrad(569), pt.y + ScaleSpriteTrad(140) + FONT_HEIGHT_LARGE + ScaleSpriteTrad(i * 55), STR_HIGHSCORE_STATS, colour); } } } diff --git a/src/industry.h b/src/industry.h index 81cbd0f2de71c..f04824795b9ff 100644 --- a/src/industry.h +++ b/src/industry.h @@ -33,13 +33,6 @@ enum ProductionLevels { PRODLEVEL_MAXIMUM = 0x80, ///< the industry is running at full speed }; -enum class IndustryAction : byte { - SetControlFlags = 0, ///< Set IndustryControlFlags - SetExclusiveSupplier = 1, ///< Set exclusive supplier - SetExclusiveConsumer = 2, ///< Set exclusive consumer - SetText = 3, ///< Set additional text -}; - /** * Flags to control/override the behaviour of an industry. * These flags are controlled by game scripts. diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 9ab9e4e427c3c..0ffdc789ec8a8 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -103,7 +103,7 @@ void ResetIndustries() * @pre IsTileType(tile, MP_INDUSTRY) * @return general type for this industry, as defined in industry.h */ -IndustryType GetIndustryType(TileIndex tile) +IndustryType GetIndustryType(Tile tile) { assert(IsTileType(tile, MP_INDUSTRY)); @@ -554,175 +554,194 @@ static bool TransportIndustryGoods(TileIndex tile) return moved_cargo; } +static void AnimateSugarSieve(TileIndex tile) +{ + byte m = GetAnimationFrame(tile) + 1; -static void AnimateTile_Industry(TileIndex tile) + if (_settings_client.sound.ambient) { + switch (m & 7) { + case 2: SndPlayTileFx(SND_2D_SUGAR_MINE_1, tile); break; + case 6: SndPlayTileFx(SND_29_SUGAR_MINE_2, tile); break; + } + } + + if (m >= 96) { + m = 0; + DeleteAnimatedTile(tile); + } + SetAnimationFrame(tile, m); + + MarkTileDirtyByTile(tile); +} + +static void AnimateToffeeQuarry(TileIndex tile) { - IndustryGfx gfx = GetIndustryGfx(tile); + byte m = GetAnimationFrame(tile); - if (GetIndustryTileSpec(gfx)->animation.status != ANIM_STATUS_NO_ANIMATION) { - AnimateNewIndustryTile(tile); - return; + if (_industry_anim_offs_toffee[m] == 0xFF && _settings_client.sound.ambient) { + SndPlayTileFx(SND_30_TOFFEE_QUARRY, tile); } - switch (gfx) { - case GFX_SUGAR_MINE_SIEVE: - if ((_tick_counter & 1) == 0) { - byte m = GetAnimationFrame(tile) + 1; + if (++m >= 70) { + m = 0; + DeleteAnimatedTile(tile); + } + SetAnimationFrame(tile, m); - if (_settings_client.sound.ambient) { - switch (m & 7) { - case 2: SndPlayTileFx(SND_2D_SUGAR_MINE_1, tile); break; - case 6: SndPlayTileFx(SND_29_SUGAR_MINE_2, tile); break; - } - } + MarkTileDirtyByTile(tile); +} - if (m >= 96) { - m = 0; - DeleteAnimatedTile(tile); - } - SetAnimationFrame(tile, m); +static void AnimateBubbleCatcher(TileIndex tile) +{ + byte m = GetAnimationFrame(tile); - MarkTileDirtyByTile(tile); - } - break; + if (++m >= 40) { + m = 0; + DeleteAnimatedTile(tile); + } + SetAnimationFrame(tile, m); - case GFX_TOFFEE_QUARY: - if ((_tick_counter & 3) == 0) { - byte m = GetAnimationFrame(tile); + MarkTileDirtyByTile(tile); +} - if (_industry_anim_offs_toffee[m] == 0xFF && _settings_client.sound.ambient) { - SndPlayTileFx(SND_30_TOFFEE_QUARRY, tile); - } +static void AnimatePowerPlantSparks(TileIndex tile) +{ + byte m = GetAnimationFrame(tile); + if (m == 6) { + SetAnimationFrame(tile, 0); + DeleteAnimatedTile(tile); + } else { + SetAnimationFrame(tile, m + 1); + MarkTileDirtyByTile(tile); + } +} + +static void AnimateToyFactory(TileIndex tile) +{ + byte m = GetAnimationFrame(tile) + 1; - if (++m >= 70) { + switch (m) { + case 1: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2C_TOY_FACTORY_1, tile); break; + case 23: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2B_TOY_FACTORY_2, tile); break; + case 28: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2A_TOY_FACTORY_3, tile); break; + default: + if (m >= 50) { + int n = GetIndustryAnimationLoop(tile) + 1; m = 0; - DeleteAnimatedTile(tile); + if (n >= 8) { + n = 0; + DeleteAnimatedTile(tile); + } + SetIndustryAnimationLoop(tile, n); } - SetAnimationFrame(tile, m); + } - MarkTileDirtyByTile(tile); - } - break; + SetAnimationFrame(tile, m); + MarkTileDirtyByTile(tile); +} - case GFX_BUBBLE_CATCHER: - if ((_tick_counter & 1) == 0) { - byte m = GetAnimationFrame(tile); +static void AnimatePlasticFountain(TileIndex tile, IndustryGfx gfx) +{ + gfx = (gfx < GFX_PLASTIC_FOUNTAIN_ANIMATED_8) ? gfx + 1 : GFX_PLASTIC_FOUNTAIN_ANIMATED_1; + SetIndustryGfx(tile, gfx); + MarkTileDirtyByTile(tile); +} - if (++m >= 40) { - m = 0; - DeleteAnimatedTile(tile); - } - SetAnimationFrame(tile, m); +static void AnimateOilWell(TileIndex tile, IndustryGfx gfx) +{ + bool b = Chance16(1, 7); + byte m = GetAnimationFrame(tile) + 1; + if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) { + SetIndustryGfx(tile, GFX_OILWELL_NOT_ANIMATED); + SetIndustryConstructionStage(tile, 3); + DeleteAnimatedTile(tile); + } else { + SetAnimationFrame(tile, m); + SetIndustryGfx(tile, gfx); + MarkTileDirtyByTile(tile); + } +} - MarkTileDirtyByTile(tile); - } - break; +static void AnimateMineTower(TileIndex tile) +{ + int state = _tick_counter & 0x7FF; - /* Sparks on a coal plant */ - case GFX_POWERPLANT_SPARKS: - if ((_tick_counter & 3) == 0) { + if ((state -= 0x400) < 0) return; + + if (state < 0x1A0) { + if (state < 0x20 || state >= 0x180) { byte m = GetAnimationFrame(tile); - if (m == 6) { - SetAnimationFrame(tile, 0); - DeleteAnimatedTile(tile); - } else { - SetAnimationFrame(tile, m + 1); - MarkTileDirtyByTile(tile); + if (!(m & 0x40)) { + SetAnimationFrame(tile, m | 0x40); + if (_settings_client.sound.ambient) SndPlayTileFx(SND_0B_MINE, tile); } + if (state & 7) return; + } else { + if (state & 3) return; } + byte m = (GetAnimationFrame(tile) + 1) | 0x40; + if (m > 0xC2) m = 0xC0; + SetAnimationFrame(tile, m); + MarkTileDirtyByTile(tile); + } else if (state >= 0x200 && state < 0x3A0) { + int i = (state < 0x220 || state >= 0x380) ? 7 : 3; + if (state & i) return; + + byte m = (GetAnimationFrame(tile) & 0xBF) - 1; + if (m < 0x80) m = 0x82; + SetAnimationFrame(tile, m); + MarkTileDirtyByTile(tile); + } +} + +static void AnimateTile_Industry(TileIndex tile) +{ + IndustryGfx gfx = GetIndustryGfx(tile); + + if (GetIndustryTileSpec(gfx)->animation.status != ANIM_STATUS_NO_ANIMATION) { + AnimateNewIndustryTile(tile); + return; + } + + switch (gfx) { + case GFX_SUGAR_MINE_SIEVE: + if ((_tick_counter & 1) == 0) AnimateSugarSieve(tile); break; - case GFX_TOY_FACTORY: - if ((_tick_counter & 1) == 0) { - byte m = GetAnimationFrame(tile) + 1; - - switch (m) { - case 1: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2C_TOY_FACTORY_1, tile); break; - case 23: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2B_TOY_FACTORY_2, tile); break; - case 28: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2A_TOY_FACTORY_3, tile); break; - default: - if (m >= 50) { - int n = GetIndustryAnimationLoop(tile) + 1; - m = 0; - if (n >= 8) { - n = 0; - DeleteAnimatedTile(tile); - } - SetIndustryAnimationLoop(tile, n); - } - } + case GFX_TOFFEE_QUARY: + if ((_tick_counter & 3) == 0) AnimateToffeeQuarry(tile); + break; - SetAnimationFrame(tile, m); - MarkTileDirtyByTile(tile); - } + case GFX_BUBBLE_CATCHER: + if ((_tick_counter & 1) == 0) AnimateBubbleCatcher(tile); + break; + + case GFX_POWERPLANT_SPARKS: + if ((_tick_counter & 3) == 0) AnimatePowerPlantSparks(tile); + break; + + case GFX_TOY_FACTORY: + if ((_tick_counter & 1) == 0) AnimateToyFactory(tile); break; case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2: case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4: case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6: case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8: - if ((_tick_counter & 3) == 0) { - IndustryGfx gfx = GetIndustryGfx(tile); - - gfx = (gfx < 155) ? gfx + 1 : 148; - SetIndustryGfx(tile, gfx); - MarkTileDirtyByTile(tile); - } + if ((_tick_counter & 3) == 0) AnimatePlasticFountain(tile, gfx); break; case GFX_OILWELL_ANIMATED_1: case GFX_OILWELL_ANIMATED_2: case GFX_OILWELL_ANIMATED_3: - if ((_tick_counter & 7) == 0) { - bool b = Chance16(1, 7); - IndustryGfx gfx = GetIndustryGfx(tile); - - byte m = GetAnimationFrame(tile) + 1; - if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) { - SetIndustryGfx(tile, GFX_OILWELL_NOT_ANIMATED); - SetIndustryConstructionStage(tile, 3); - DeleteAnimatedTile(tile); - } else { - SetAnimationFrame(tile, m); - SetIndustryGfx(tile, gfx); - MarkTileDirtyByTile(tile); - } - } + if ((_tick_counter & 7) == 0) AnimateOilWell(tile, gfx); break; case GFX_COAL_MINE_TOWER_ANIMATED: case GFX_COPPER_MINE_TOWER_ANIMATED: - case GFX_GOLD_MINE_TOWER_ANIMATED: { - int state = _tick_counter & 0x7FF; - - if ((state -= 0x400) < 0) return; - - if (state < 0x1A0) { - if (state < 0x20 || state >= 0x180) { - byte m = GetAnimationFrame(tile); - if (!(m & 0x40)) { - SetAnimationFrame(tile, m | 0x40); - if (_settings_client.sound.ambient) SndPlayTileFx(SND_0B_MINE, tile); - } - if (state & 7) return; - } else { - if (state & 3) return; - } - byte m = (GetAnimationFrame(tile) + 1) | 0x40; - if (m > 0xC2) m = 0xC0; - SetAnimationFrame(tile, m); - MarkTileDirtyByTile(tile); - } else if (state >= 0x200 && state < 0x3A0) { - int i = (state < 0x220 || state >= 0x380) ? 7 : 3; - if (state & i) return; - - byte m = (GetAnimationFrame(tile) & 0xBF) - 1; - if (m < 0x80) m = 0x82; - SetAnimationFrame(tile, m); - MarkTileDirtyByTile(tile); - } - break; - } + case GFX_GOLD_MINE_TOWER_ANIMATED: + AnimateMineTower(tile); + break; } } @@ -1010,7 +1029,7 @@ static void SetupFarmFieldFence(TileIndex tile, int size, byte type, DiagDirecti TileIndexDiff diff = (DiagDirToAxis(side) == AXIS_Y ? TileDiffXY(1, 0) : TileDiffXY(0, 1)); do { - tile = TILE_MASK(tile); + tile = Map::WrapToMap(tile); if (IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS)) { byte or_ = type; @@ -1044,7 +1063,7 @@ static void PlantFarmField(TileIndex tile, IndustryID industry) /* check the amount of bad tiles */ int count = 0; for (TileIndex cur_tile : ta) { - assert(cur_tile < MapSize()); + assert(cur_tile < Map::Size()); count += IsSuitableForFarmField(cur_tile, false); } if (count * 2 < ta.w * ta.h) return; @@ -1056,7 +1075,7 @@ static void PlantFarmField(TileIndex tile, IndustryID industry) /* make field */ for (TileIndex cur_tile : ta) { - assert(cur_tile < MapSize()); + assert(cur_tile < Map::Size()); if (IsSuitableForFarmField(cur_tile, true)) { MakeField(cur_tile, field_type, industry); SetClearCounter(cur_tile, counter); @@ -1259,8 +1278,8 @@ static bool CheckScaledDistanceFromEdge(TileIndex tile, uint maxdist) uint maxdist_x = maxdist; uint maxdist_y = maxdist; - if (MapSizeX() > 256) maxdist_x *= MapSizeX() / 256; - if (MapSizeY() > 256) maxdist_y *= MapSizeY() / 256; + if (Map::SizeX() > 256) maxdist_x *= Map::SizeX() / 256; + if (Map::SizeY() > 256) maxdist_y *= Map::SizeY() / 256; if (DistanceFromEdgeDir(tile, DIAGDIR_NE) < maxdist_x) return true; if (DistanceFromEdgeDir(tile, DIAGDIR_NW) < maxdist_y) return true; @@ -1435,18 +1454,12 @@ bool IsSlopeRefused(Slope current, Slope refused) * Are the tiles of the industry free? * @param tile Position to check. * @param layout Industry tiles table. - * @param layout_index The index of the layout to build/fund * @param type Type of the industry. - * @param initial_random_bits The random bits the industry is going to have after construction. - * @param founder Industry founder - * @param creation_type The circumstances the industry is created under. - * @param[out] custom_shape_check Perform custom check for the site. * @return Failed or succeeded command. */ -static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileLayout &layout, size_t layout_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check = nullptr) +static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileLayout &layout, IndustryType type) { - bool refused_slope = false; - bool custom_shape = false; + IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour; for (const IndustryTileLayoutTile &it : layout) { IndustryGfx gfx = GetTranslatedIndustryTileID(it.gfx); @@ -1468,20 +1481,9 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil const IndustryTileSpec *its = GetIndustryTileSpec(gfx); - IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour; - /* Perform land/water check if not disabled */ if (!HasBit(its->slopes_refused, 5) && ((HasTileWaterClass(cur_tile) && IsTileOnWater(cur_tile)) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return_cmd_error(STR_ERROR_SITE_UNSUITABLE); - if (HasBit(its->callback_mask, CBM_INDT_SHAPE_CHECK)) { - custom_shape = true; - CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, layout_index, initial_random_bits, founder, creation_type); - if (ret.Failed()) return ret; - } else { - Slope tileh = GetTileSlope(cur_tile); - refused_slope |= IsSlopeRefused(tileh, its->slopes_refused); - } - if ((ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) || // Tile must be a house ((ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) && IsTileType(cur_tile, MP_HOUSE))) { // Tile is allowed to be a house (and it is a house) if (!IsTileType(cur_tile, MP_HOUSE)) { @@ -1490,15 +1492,53 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil /* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */ Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); - CommandCost ret = Command::Do(DC_NONE, cur_tile); + ret = Command::Do(DC_NONE, cur_tile); cur_company.Restore(); if (ret.Failed()) return ret; } else { /* Clear the tiles, but do not affect town ratings */ - CommandCost ret = Command::Do(DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, cur_tile); + ret = Command::Do(DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, cur_tile); + if (ret.Failed()) return ret; + } + } + } + + return CommandCost(); +} + +/** + * Check slope requirements for industry tiles. + * @param tile Position to check. + * @param layout Industry tiles table. + * @param layout_index The index of the layout to build/fund + * @param type Type of the industry. + * @param initial_random_bits The random bits the industry is going to have after construction. + * @param founder Industry founder + * @param creation_type The circumstances the industry is created under. + * @param[out] custom_shape_check Perform custom check for the site. + * @return Failed or succeeded command. + */ +static CommandCost CheckIfIndustryTileSlopes(TileIndex tile, const IndustryTileLayout &layout, size_t layout_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check = nullptr) +{ + bool refused_slope = false; + bool custom_shape = false; + for (const IndustryTileLayoutTile &it : layout) { + IndustryGfx gfx = GetTranslatedIndustryTileID(it.gfx); + TileIndex cur_tile = TileAddWrap(tile, it.ti.x, it.ti.y); + assert(IsValidTile(cur_tile)); // checked before in CheckIfIndustryTilesAreFree + + if (gfx != GFX_WATERTILE_SPECIALCHECK) { + const IndustryTileSpec *its = GetIndustryTileSpec(gfx); + + if (HasBit(its->callback_mask, CBM_INDT_SHAPE_CHECK)) { + custom_shape = true; + CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, layout_index, initial_random_bits, founder, creation_type); if (ret.Failed()) return ret; + } else { + Slope tileh = GetTileSlope(cur_tile); + refused_slope |= IsSlopeRefused(tileh, its->slopes_refused); } } } @@ -1589,7 +1629,7 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, TileArea ta(tile + TileDiffXY(-_settings_game.construction.industry_platform, -_settings_game.construction.industry_platform), max_x + 2 + 2 * _settings_game.construction.industry_platform, max_y + 2 + 2 * _settings_game.construction.industry_platform); - if (TileX(ta.tile) + ta.w >= MapMaxX() || TileY(ta.tile) + ta.h >= MapMaxY()) return false; + if (TileX(ta.tile) + ta.w >= Map::MaxX() || TileY(ta.tile) + ta.h >= Map::MaxY()) return false; /* _current_company is OWNER_NONE for randomly generated industries and in editor, or the company who funded or prospected the industry. * Perform terraforming as OWNER_TOWN to disable autoslope and town ratings. */ @@ -1935,15 +1975,28 @@ static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, Do { assert(layout_index < indspec->layouts.size()); const IndustryTileLayout &layout = indspec->layouts[layout_index]; - bool custom_shape_check = false; *ip = nullptr; + /* 1. Cheap: Built-in checks on industry level. */ + CommandCost ret = CheckIfFarEnoughFromConflictingIndustry(tile, type); + if (ret.Failed()) return ret; + + Town *t = nullptr; + ret = FindTownForIndustry(tile, type, &t); + if (ret.Failed()) return ret; + assert(t != nullptr); + + ret = CheckIfIndustryIsAllowed(tile, type, t); + if (ret.Failed()) return ret; + + /* 2. Built-in checks on industry tiles. */ std::vector object_areas(_cleared_object_areas); - CommandCost ret = CheckIfIndustryTilesAreFree(tile, layout, layout_index, type, random_initial_bits, founder, creation_type, &custom_shape_check); + ret = CheckIfIndustryTilesAreFree(tile, layout, type); _cleared_object_areas = object_areas; if (ret.Failed()) return ret; + /* 3. NewGRF-defined checks on industry level. */ if (HasBit(GetIndustrySpec(type)->callback_mask, CBM_IND_LOCATION)) { ret = CheckIfCallBackAllowsCreation(tile, type, layout_index, random_var8f, random_initial_bits, founder, creation_type); } else { @@ -1951,22 +2004,16 @@ static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, Do } if (ret.Failed()) return ret; + /* 4. Expensive: NewGRF-defined checks on industry tiles. */ + bool custom_shape_check = false; + ret = CheckIfIndustryTileSlopes(tile, layout, layout_index, type, random_initial_bits, founder, creation_type, &custom_shape_check); + if (ret.Failed()) return ret; + if (!custom_shape_check && _settings_game.game_creation.land_generator == LG_TERRAGENESIS && _generating_world && !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER, layout, type)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } - ret = CheckIfFarEnoughFromConflictingIndustry(tile, type); - if (ret.Failed()) return ret; - - Town *t = nullptr; - ret = FindTownForIndustry(tile, type, &t); - if (ret.Failed()) return ret; - assert(t != nullptr); - - ret = CheckIfIndustryIsAllowed(tile, type, t); - if (ret.Failed()) return ret; - if (!Industry::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_INDUSTRIES); if (flags & DC_EXEC) { @@ -2018,12 +2065,14 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType i Industry *ind = nullptr; if (deity_prospect || (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry())) { if (flags & DC_EXEC) { - /* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */ - Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); /* Prospecting has a chance to fail, however we cannot guarantee that something can * be built on the map, so the chance gets lower when the map is fuller, but there * is nothing we can really do about that. */ - if (deity_prospect || Random() <= indspec->prospecting_chance) { + bool prospect_success = deity_prospect || Random() <= indspec->prospecting_chance; + if (prospect_success) { + /* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */ + IndustryAvailabilityCallType calltype = _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_PROSPECTCREATION; + Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); for (int i = 0; i < 5000; i++) { /* We should not have more than one Random() in a function call * because parameter evaluation order is not guaranteed in the c++ standard @@ -2034,13 +2083,20 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType i /* Check now each layout, starting with the random one */ for (size_t j = 0; j < num_layouts; j++) { layout = (layout + 1) % num_layouts; - ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, cur_company.GetOriginalValue(), _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_PROSPECTCREATION, &ind); + ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, cur_company.GetOriginalValue(), calltype, &ind); if (ret.Succeeded()) break; } if (ret.Succeeded()) break; } + cur_company.Restore(); + } + if (ret.Failed() && IsLocalCompany()) { + if (prospect_success) { + ShowErrorMessage(STR_ERROR_CAN_T_PROSPECT_INDUSTRY, STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING, WL_INFO); + } else { + ShowErrorMessage(STR_ERROR_CAN_T_PROSPECT_INDUSTRY, STR_ERROR_PROSPECTING_WAS_UNLUCKY, WL_INFO); + } } - cur_company.Restore(); } } else { size_t layout = first_layout; @@ -2065,56 +2121,73 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType i } /** - * Change industry properties + * Set industry control flags. + * @param flags Type of operation. + * @param ind_id IndustryID + * @param ctlflags IndustryControlFlags + * @return Empty cost or an error. + */ +CommandCost CmdIndustrySetFlags(DoCommandFlag flags, IndustryID ind_id, IndustryControlFlags ctlflags) +{ + if (_current_company != OWNER_DEITY) return CMD_ERROR; + + Industry *ind = Industry::GetIfValid(ind_id); + if (ind == nullptr) return CMD_ERROR; + + if (flags & DC_EXEC) ind->ctlflags = ctlflags & INDCTL_MASK; + + return CommandCost(); +} + +/** + * Change exclusive consumer or supplier for the industry. * @param flags Type of operation. * @param ind_id IndustryID - * @param action IndustryAction to perform - * @param ctlflags IndustryControlFlags (only used with set control flags) * @param company_id CompanyID to set or INVALID_OWNER (available to everyone) or * OWNER_NONE (neutral stations only) or OWNER_DEITY (no one) - * (only used with set exclusive supplier / consumer) - * @param text - Additional industry text (only used with set text action) + * @param consumer Set exclusive consumer if true, supplier if false. * @return Empty cost or an error. */ -CommandCost CmdIndustryCtrl(DoCommandFlag flags, IndustryID ind_id, IndustryAction action, IndustryControlFlags ctlflags, Owner company_id, const std::string &text) +CommandCost CmdIndustrySetExclusivity(DoCommandFlag flags, IndustryID ind_id, Owner company_id, bool consumer) { if (_current_company != OWNER_DEITY) return CMD_ERROR; Industry *ind = Industry::GetIfValid(ind_id); if (ind == nullptr) return CMD_ERROR; - switch (action) { - case IndustryAction::SetControlFlags: { - if (flags & DC_EXEC) ind->ctlflags = ctlflags & INDCTL_MASK; + if (company_id != OWNER_NONE && company_id != INVALID_OWNER && company_id != OWNER_DEITY + && !Company::IsValidID(company_id)) return CMD_ERROR; - break; + if (flags & DC_EXEC) { + if (consumer) { + ind->exclusive_consumer = company_id; + } else { + ind->exclusive_supplier = company_id; } + } - case IndustryAction::SetExclusiveSupplier: - case IndustryAction::SetExclusiveConsumer: { - if (company_id != OWNER_NONE && company_id != INVALID_OWNER && company_id != OWNER_DEITY - && !Company::IsValidID(company_id)) return CMD_ERROR; - if (flags & DC_EXEC) { - if (action == IndustryAction::SetExclusiveSupplier) { - ind->exclusive_supplier = company_id; - } else { - ind->exclusive_consumer = company_id; - } - } + return CommandCost(); +} - break; - } +/** + * Change additional industry text. + * @param flags Type of operation. + * @param ind_id IndustryID + * @param text - Additional industry text. + * @return Empty cost or an error. + */ +CommandCost CmdIndustrySetText(DoCommandFlag flags, IndustryID ind_id, const std::string &text) +{ + if (_current_company != OWNER_DEITY) return CMD_ERROR; - case IndustryAction::SetText: { - ind->text.clear(); - if (!text.empty()) ind->text = text; - InvalidateWindowData(WC_INDUSTRY_VIEW, ind->index); - break; - } + Industry *ind = Industry::GetIfValid(ind_id); + if (ind == nullptr) return CMD_ERROR; - default: - return CMD_ERROR; + if (flags & DC_EXEC) { + ind->text.clear(); + if (!text.empty()) ind->text = text; + InvalidateWindowData(WC_INDUSTRY_VIEW, ind->index); } return CommandCost(); @@ -2159,7 +2232,7 @@ static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *forc chance *= 16; // to increase precision /* We want industries appearing at coast to appear less often on bigger maps, as length of coast increases slower than map area. * For simplicity we scale in both cases, though scaling the probabilities of all industries has no effect. */ - chance = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(chance) : ScaleByMapSize(chance); + chance = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? Map::ScaleBySize1D(chance) : Map::ScaleBySize(chance); *force_at_least_one = (chance > 0) && !(ind_spc->behaviour & INDUSTRYBEH_NOBUILT_MAPCREATION) && (_game_mode != GM_EDITOR); return chance; @@ -2206,11 +2279,15 @@ static uint GetNumberOfIndustries() 25, // low 55, // normal 80, // high + 0, // custom }; assert(lengthof(numof_industry_table) == ID_END); uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.industry_density : (uint)ID_VERY_LOW; - return std::min(IndustryPool::MAX_SIZE, ScaleByMapSize(numof_industry_table[difficulty])); + + if (difficulty == ID_CUSTOM) return std::min(IndustryPool::MAX_SIZE, _settings_game.game_creation.custom_industry_number); + + return std::min(IndustryPool::MAX_SIZE, Map::ScaleBySize(numof_industry_table[difficulty])); } /** @@ -2286,9 +2363,9 @@ void IndustryBuildData::MonthlyLoop() /* To prevent running out of unused industries for the player to connect, * add a fraction of new industries each month, but only if the manager can keep up. */ - uint max_behind = 1 + std::min(99u, ScaleByMapSize(3)); // At most 2 industries for small maps, and 100 at the biggest map (about 6 months industry build attempts). + uint max_behind = 1 + std::min(99u, Map::ScaleBySize(3)); // At most 2 industries for small maps, and 100 at the biggest map (about 6 months industry build attempts). if (GetCurrentTotalNumberOfIndustries() + max_behind >= (this->wanted_inds >> 16)) { - this->wanted_inds += ScaleByMapSize(NEWINDS_PER_MONTH); + this->wanted_inds += Map::ScaleBySize(NEWINDS_PER_MONTH); } } diff --git a/src/industry_cmd.h b/src/industry_cmd.h index 21d9200a3049c..16de6b833170b 100644 --- a/src/industry_cmd.h +++ b/src/industry_cmd.h @@ -14,14 +14,17 @@ #include "company_type.h" #include "industry_type.h" -enum class IndustryAction : byte; enum IndustryControlFlags : byte; CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType it, uint32 first_layout, bool fund, uint32 seed); -CommandCost CmdIndustryCtrl(DoCommandFlag flags, IndustryID ind_id, IndustryAction action, IndustryControlFlags ctlflags, Owner company_id, const std::string &text); - -DEF_CMD_TRAIT(CMD_BUILD_INDUSTRY, CmdBuildIndustry, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_INDUSTRY_CTRL, CmdIndustryCtrl, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +CommandCost CmdIndustrySetFlags(DoCommandFlag flags, IndustryID ind_id, IndustryControlFlags ctlflags); +CommandCost CmdIndustrySetExclusivity(DoCommandFlag flags, IndustryID ind_id, Owner company_id, bool consumer); +CommandCost CmdIndustrySetText(DoCommandFlag flags, IndustryID ind_id, const std::string &text); + +DEF_CMD_TRAIT(CMD_BUILD_INDUSTRY, CmdBuildIndustry, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_INDUSTRY_SET_FLAGS, CmdIndustrySetFlags, CMD_DEITY, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_INDUSTRY_SET_EXCLUSIVITY, CmdIndustrySetExclusivity, CMD_DEITY, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_INDUSTRY_SET_TEXT, CmdIndustrySetText, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) void CcBuildIndustry(Commands cmd, const CommandCost &result, TileIndex tile, IndustryType indtype, uint32, bool, uint32); diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 6f279613e5b6a..c8cd28470004f 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -40,6 +40,8 @@ #include "clear_map.h" #include "zoom_func.h" #include "industry_cmd.h" +#include "querystring_gui.h" +#include "stringfilter_type.h" #include "table/strings.h" @@ -71,6 +73,7 @@ struct CargoSuffix { char text[512]; ///< Cargo suffix text. }; +extern void GenerateIndustries(); static void ShowIndustryCargoesWindow(IndustryType id); /** @@ -422,8 +425,8 @@ class BuildIndustryWindow : public Window { if (this->index[i] == INVALID_INDUSTRYTYPE) continue; d = maxdim(d, GetStringBoundingBox(GetIndustrySpec(this->index[i])->name)); } - resize->height = std::max(this->legend.height, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; - d.width += this->legend.width + ScaleFontTrad(7) + padding.width; + resize->height = std::max(this->legend.height, FONT_HEIGHT_NORMAL) + padding.height; + d.width += this->legend.width + WidgetDimensions::scaled.hsep_wide + padding.width; d.height = 5 * resize->height; *size = maxdim(*size, d); break; @@ -471,8 +474,8 @@ class BuildIndustryWindow : public Window { /* Set it to something more sane :) */ height += extra_lines_prd + extra_lines_req + extra_lines_newgrf; - size->height = height * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; - size->width = d.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + size->height = height * FONT_HEIGHT_NORMAL + padding.height; + size->width = d.width + padding.width; break; } @@ -513,52 +516,40 @@ class BuildIndustryWindow : public Window { { switch (widget) { case WID_DPI_MATRIX_WIDGET: { - uint text_left, text_right, icon_left, icon_right; - if (_current_text_dir == TD_RTL) { - icon_right = r.right - WD_MATRIX_RIGHT; - icon_left = icon_right - this->legend.width; - text_right = icon_left - ScaleFontTrad(7); - text_left = r.left + WD_MATRIX_LEFT; - } else { - icon_left = r.left + WD_MATRIX_LEFT; - icon_right = icon_left + this->legend.width; - text_left = icon_right + ScaleFontTrad(7); - text_right = r.right - WD_MATRIX_RIGHT; - } + bool rtl = _current_text_dir == TD_RTL; + Rect text = r.WithHeight(this->resize.step_height).Shrink(WidgetDimensions::scaled.matrix); + Rect icon = text.WithWidth(this->legend.width, rtl); + text = text.Indent(this->legend.width + WidgetDimensions::scaled.hsep_wide, rtl); /* Vertical offset for legend icon. */ - int icon_top = (this->resize.step_height - this->legend.height + 1) / 2; - int icon_bottom = icon_top + this->legend.height; + icon.top = r.top + (this->resize.step_height - this->legend.height + 1) / 2; + icon.bottom = icon.top + this->legend.height - 1; - int y = r.top; 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) { - DrawString(text_left, text_right, y + WD_MATRIX_TOP, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES, selected ? TC_WHITE : TC_ORANGE); - y += this->resize.step_height; - continue; - } - const IndustrySpec *indsp = GetIndustrySpec(this->index[i + this->vscroll->GetPosition()]); + DrawString(text, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES, selected ? TC_WHITE : TC_ORANGE); + } else { + const IndustrySpec *indsp = GetIndustrySpec(this->index[i + this->vscroll->GetPosition()]); - /* Draw the name of the industry in white is selected, otherwise, in orange */ - DrawString(text_left, text_right, y + WD_MATRIX_TOP, indsp->name, selected ? TC_WHITE : TC_ORANGE); - GfxFillRect(icon_left, y + icon_top, icon_right, y + icon_bottom, selected ? PC_WHITE : PC_BLACK); - GfxFillRect(icon_left + 1, y + icon_top + 1, icon_right - 1, y + icon_bottom - 1, indsp->map_colour); + /* Draw the name of the industry in white is selected, otherwise, in orange */ + DrawString(text, indsp->name, selected ? TC_WHITE : TC_ORANGE); + GfxFillRect(icon, selected ? PC_WHITE : PC_BLACK); + GfxFillRect(icon.Shrink(WidgetDimensions::scaled.bevel), indsp->map_colour); + } - y += this->resize.step_height; + text = text.Translate(0, this->resize.step_height); + icon = icon.Translate(0, this->resize.step_height); } break; } case WID_DPI_INFOPANEL: { - int y = r.top + WD_FRAMERECT_TOP; - int bottom = r.bottom - WD_FRAMERECT_BOTTOM; - int left = r.left + WD_FRAMERECT_LEFT; - int right = r.right - WD_FRAMERECT_RIGHT; + Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); if (this->selected_type == INVALID_INDUSTRYTYPE) { - DrawStringMultiLine(left, right, y, bottom, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP); + DrawStringMultiLine(ir, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP); break; } @@ -566,8 +557,8 @@ class BuildIndustryWindow : public Window { if (_game_mode != GM_EDITOR) { SetDParam(0, indsp->GetConstructionCost()); - DrawString(left, right, y, STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST); - y += FONT_HEIGHT_NORMAL; + DrawString(ir, STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST); + ir.top += FONT_HEIGHT_NORMAL; } CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)]; @@ -575,12 +566,12 @@ class BuildIndustryWindow : public Window { /* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */ GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, nullptr, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix); std::string cargostring = this->MakeCargoListString(indsp->accepts_cargo, cargo_suffix, lengthof(indsp->accepts_cargo), STR_INDUSTRY_VIEW_REQUIRES_N_CARGO); - y = DrawStringMultiLine(left, right, y, bottom, cargostring); + ir.top = DrawStringMultiLine(ir, cargostring); /* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */ GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, nullptr, this->selected_type, indsp, indsp->produced_cargo, cargo_suffix); cargostring = this->MakeCargoListString(indsp->produced_cargo, cargo_suffix, lengthof(indsp->produced_cargo), STR_INDUSTRY_VIEW_PRODUCES_N_CARGO); - y = DrawStringMultiLine(left, right, y, bottom, cargostring); + ir.top = DrawStringMultiLine(ir, cargostring); /* Get the additional purchase info text, if it has not already been queried. */ if (HasBit(indsp->callback_mask, CBM_IND_FUND_MORE_TEXT)) { @@ -592,7 +583,7 @@ class BuildIndustryWindow : public Window { StringID str = GetGRFStringID(indsp->grf_prop.grffile->grfid, 0xD000 + callback_res); // No. here's the new string if (str != STR_UNDEFINED) { StartTextRefStackUsage(indsp->grf_prop.grffile, 6); - DrawStringMultiLine(left, right, y, bottom, str, TC_YELLOW); + DrawStringMultiLine(ir, str, TC_YELLOW); StopTextRefStackUsage(); } } @@ -610,7 +601,6 @@ class BuildIndustryWindow : public Window { if (Town::GetNumItems() == 0) { ShowErrorMessage(STR_ERROR_CAN_T_GENERATE_INDUSTRIES, STR_ERROR_MUST_FOUND_TOWN_FIRST, WL_INFO); } else { - extern void GenerateIndustries(); Backup old_generating_world(_generating_world, true, FILE_LINE); BasePersistentStorageArray::SwitchMode(PSM_ENTER_GAMELOOP); GenerateIndustries(); @@ -626,7 +616,7 @@ class BuildIndustryWindow : public Window { for (Industry *industry : Industry::Iterate()) delete industry; /* Clear farmland. */ - for (TileIndex tile = 0; tile < MapSize(); tile++) { + for (TileIndex tile = 0; tile < Map::Size(); tile++) { if (IsTileType(tile, MP_CLEAR) && GetRawClearGround(tile) == CLEAR_FIELDS) { MakeClear(tile, CLEAR_GRASS, 3); } @@ -825,6 +815,7 @@ class IndustryViewWindow : public Window byte clicked_button; ///< The button that has been clicked (to raise) int production_offset_y; ///< The offset of the production texts/buttons int info_height; ///< Height needed for the #WID_IV_INFO panel + int cheat_line_height; ///< Height of each line for the #WID_IV_INFO panel public: IndustryViewWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc) @@ -833,25 +824,31 @@ class IndustryViewWindow : public Window this->editbox_line = IL_NONE; this->clicked_line = IL_NONE; this->clicked_button = 0; - this->info_height = WD_FRAMERECT_TOP + 2 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM + 1; // Info panel has at least two lines text. + this->info_height = WidgetDimensions::scaled.framerect.Vertical() + 2 * FONT_HEIGHT_NORMAL; // Info panel has at least two lines text. this->InitNested(window_number); NWidgetViewport *nvp = this->GetWidget(WID_IV_VIEWPORT); - nvp->InitializeViewport(this, Industry::Get(window_number)->location.GetCenterTile(), ZOOM_LVL_INDUSTRY); + nvp->InitializeViewport(this, Industry::Get(window_number)->location.GetCenterTile(), ScaleZoomGUI(ZOOM_LVL_INDUSTRY)); this->InvalidateData(); } + void OnInit() override + { + /* This only used when the cheat to alter industry production is enabled */ + this->cheat_line_height = std::max(SETTING_BUTTON_HEIGHT + WidgetDimensions::scaled.vsep_normal, FONT_HEIGHT_NORMAL); + } + void OnPaint() override { this->DrawWidgets(); if (this->IsShaded()) return; // Don't draw anything when the window is shaded. - NWidgetBase *nwi = this->GetWidget(WID_IV_INFO); - uint expected = this->DrawInfo(nwi->pos_x, nwi->pos_x + nwi->current_x - 1, nwi->pos_y) - nwi->pos_y; - if (expected > nwi->current_y - 1) { - this->info_height = expected + 1; + const Rect r = this->GetWidget(WID_IV_INFO)->GetCurrentRect(); + int expected = this->DrawInfo(r); + if (expected != r.bottom) { + this->info_height = expected - r.top + 1; this->ReInit(); return; } @@ -859,35 +856,33 @@ class IndustryViewWindow : public Window /** * Draw the text in the #WID_IV_INFO panel. - * @param left Left edge of the panel. - * @param right Right edge of the panel. - * @param top Top edge of the panel. + * @param r Rectangle of the panel. * @return Expected position of the bottom edge of the panel. */ - int DrawInfo(uint left, uint right, uint top) + int DrawInfo(const Rect &r) { + bool rtl = _current_text_dir == TD_RTL; Industry *i = Industry::Get(this->window_number); const IndustrySpec *ind = GetIndustrySpec(i->type); - int y = top + WD_FRAMERECT_TOP; + Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); bool first = true; bool has_accept = false; if (i->prod_level == PRODLEVEL_CLOSURE) { - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE); - y += 2 * FONT_HEIGHT_NORMAL; + DrawString(ir, STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE); + ir.top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide; } CargoSuffix cargo_suffix[lengthof(i->accepts_cargo)]; GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_VIEW, i, i->type, ind, i->accepts_cargo, cargo_suffix); bool stockpiling = HasBit(ind->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(ind->callback_mask, CBM_IND_PRODUCTION_256_TICKS); - uint left_side = left + WD_FRAMERECT_LEFT * 4; // Indent accepted cargoes. for (byte j = 0; j < lengthof(i->accepts_cargo); j++) { if (i->accepts_cargo[j] == CT_INVALID) continue; has_accept = true; if (first) { - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_REQUIRES); - y += FONT_HEIGHT_NORMAL; + DrawString(ir, STR_INDUSTRY_VIEW_REQUIRES); + ir.top += FONT_HEIGHT_NORMAL; first = false; } SetDParam(0, CargoSpec::Get(i->accepts_cargo[j])->name); @@ -913,19 +908,22 @@ class IndustryViewWindow : public Window default: NOT_REACHED(); } - DrawString(left_side, right - WD_FRAMERECT_RIGHT, y, str); - y += FONT_HEIGHT_NORMAL; + DrawString(ir.Indent(WidgetDimensions::scaled.hsep_indent, rtl), str); + ir.top += FONT_HEIGHT_NORMAL; } GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_VIEW, i, i->type, ind, i->produced_cargo, cargo_suffix); + int line_height = this->editable == EA_RATE ? this->cheat_line_height : FONT_HEIGHT_NORMAL; + int text_y_offset = (line_height - FONT_HEIGHT_NORMAL) / 2; + int button_y_offset = (line_height - SETTING_BUTTON_HEIGHT) / 2; first = true; for (byte j = 0; j < lengthof(i->produced_cargo); j++) { if (i->produced_cargo[j] == CT_INVALID) continue; if (first) { - if (has_accept) y += WD_PAR_VSEP_WIDE; - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE); - y += FONT_HEIGHT_NORMAL; - if (this->editable == EA_RATE) this->production_offset_y = y; + if (has_accept) ir.top += WidgetDimensions::scaled.vsep_wide; + DrawString(ir, STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE); + ir.top += FONT_HEIGHT_NORMAL; + if (this->editable == EA_RATE) this->production_offset_y = ir.top; first = false; } @@ -933,26 +931,27 @@ class IndustryViewWindow : public Window SetDParam(1, i->last_month_production[j]); SetDParamStr(2, cargo_suffix[j].text); SetDParam(3, ToPercent8(i->last_month_pct_transported[j])); - uint x = left + WD_FRAMETEXT_LEFT + (this->editable == EA_RATE ? SETTING_BUTTON_WIDTH + 10 : 0); - DrawString(x, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_TRANSPORTED); + DrawString(ir.Indent(WidgetDimensions::scaled.hsep_indent + (this->editable == EA_RATE ? SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_normal : 0), rtl).Translate(0, text_y_offset), STR_INDUSTRY_VIEW_TRANSPORTED); /* Let's put out those buttons.. */ if (this->editable == EA_RATE) { - DrawArrowButtons(left + WD_FRAMETEXT_LEFT, y, COLOUR_YELLOW, (this->clicked_line == IL_RATE1 + j) ? this->clicked_button : 0, + DrawArrowButtons(ir.Indent(WidgetDimensions::scaled.hsep_indent, rtl).WithWidth(SETTING_BUTTON_WIDTH, rtl).left, ir.top + button_y_offset, COLOUR_YELLOW, (this->clicked_line == IL_RATE1 + j) ? this->clicked_button : 0, i->production_rate[j] > 0, i->production_rate[j] < 255); } - y += FONT_HEIGHT_NORMAL; + ir.top += line_height; } /* Display production multiplier if editable */ if (this->editable == EA_MULTIPLIER) { - y += WD_PAR_VSEP_WIDE; - this->production_offset_y = y; + line_height = this->cheat_line_height; + text_y_offset = (line_height - FONT_HEIGHT_NORMAL) / 2; + button_y_offset = (line_height - SETTING_BUTTON_HEIGHT) / 2; + ir.top += WidgetDimensions::scaled.vsep_wide; + this->production_offset_y = ir.top; SetDParam(0, RoundDivSU(i->prod_level * 100, PRODLEVEL_DEFAULT)); - uint x = left + WD_FRAMETEXT_LEFT + SETTING_BUTTON_WIDTH + 10; - DrawString(x, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LEVEL); - DrawArrowButtons(left + WD_FRAMETEXT_LEFT, y, COLOUR_YELLOW, (this->clicked_line == IL_MULTIPLIER) ? this->clicked_button : 0, + DrawString(ir.Indent(WidgetDimensions::scaled.hsep_indent + SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_normal, rtl).Translate(0, text_y_offset), STR_INDUSTRY_VIEW_PRODUCTION_LEVEL); + DrawArrowButtons(ir.Indent(WidgetDimensions::scaled.hsep_indent, rtl).WithWidth(SETTING_BUTTON_WIDTH, rtl).left, ir.top + button_y_offset, COLOUR_YELLOW, (this->clicked_line == IL_MULTIPLIER) ? this->clicked_button : 0, i->prod_level > PRODLEVEL_MINIMUM, i->prod_level < PRODLEVEL_MAXIMUM); - y += FONT_HEIGHT_NORMAL; + ir.top += line_height; } /* Get the extra message for the GUI */ @@ -964,13 +963,13 @@ class IndustryViewWindow : public Window } else { StringID message = GetGRFStringID(ind->grf_prop.grffile->grfid, 0xD000 + callback_res); if (message != STR_NULL && message != STR_UNDEFINED) { - y += WD_PAR_VSEP_WIDE; + ir.top += WidgetDimensions::scaled.vsep_wide; StartTextRefStackUsage(ind->grf_prop.grffile, 6); /* Use all the available space left from where we stand up to the * end of the window. We ALSO enlarge the window if needed, so we * can 'go' wild with the bottom of the window. */ - y = DrawStringMultiLine(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, UINT16_MAX, message, TC_BLACK); + ir.top = DrawStringMultiLine(ir.left, ir.right, ir.top, UINT16_MAX, message, TC_BLACK); StopTextRefStackUsage(); } } @@ -979,11 +978,12 @@ class IndustryViewWindow : public Window if (!i->text.empty()) { SetDParamStr(0, i->text); - y += WD_PAR_VSEP_WIDE; - y = DrawStringMultiLine(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); + ir.top += WidgetDimensions::scaled.vsep_wide; + ir.top = DrawStringMultiLine(ir.left, ir.right, ir.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); } - return y + WD_FRAMERECT_BOTTOM; + /* Return required bottom position, the last pixel row plus some padding. */ + return ir.top - 1 + WidgetDimensions::scaled.framerect.bottom; } void SetStringParameters(int widget) const override @@ -1007,12 +1007,12 @@ class IndustryViewWindow : public Window case EA_NONE: break; case EA_MULTIPLIER: - if (IsInsideBS(pt.y, this->production_offset_y, FONT_HEIGHT_NORMAL)) line = IL_MULTIPLIER; + if (IsInsideBS(pt.y, this->production_offset_y, this->cheat_line_height)) line = IL_MULTIPLIER; break; case EA_RATE: if (pt.y >= this->production_offset_y) { - int row = (pt.y - this->production_offset_y) / FONT_HEIGHT_NORMAL; + int row = (pt.y - this->production_offset_y) / this->cheat_line_height; for (uint j = 0; j < lengthof(i->produced_cargo); j++) { if (i->produced_cargo[j] == CT_INVALID) continue; row--; @@ -1026,15 +1026,15 @@ class IndustryViewWindow : public Window } if (line == IL_NONE) return; - NWidgetBase *nwi = this->GetWidget(widget); - int left = nwi->pos_x + WD_FRAMETEXT_LEFT; - int right = nwi->pos_x + nwi->current_x - 1 - WD_FRAMERECT_RIGHT; - if (IsInsideMM(pt.x, left, left + SETTING_BUTTON_WIDTH)) { + bool rtl = _current_text_dir == TD_RTL; + Rect r = this->GetWidget(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect).Indent(WidgetDimensions::scaled.hsep_indent, rtl); + + if (r.WithWidth(SETTING_BUTTON_WIDTH, rtl).Contains(pt)) { /* Clicked buttons, decrease or increase production */ - byte button = (pt.x < left + SETTING_BUTTON_WIDTH / 2) ? 1 : 2; + bool decrease = r.WithWidth(SETTING_BUTTON_WIDTH / 2, rtl).Contains(pt); switch (this->editable) { case EA_MULTIPLIER: - if (button == 1) { + if (decrease) { if (i->prod_level <= PRODLEVEL_MINIMUM) return; i->prod_level = std::max(i->prod_level / 2, PRODLEVEL_MINIMUM); } else { @@ -1044,7 +1044,7 @@ class IndustryViewWindow : public Window break; case EA_RATE: - if (button == 1) { + if (decrease) { if (i->production_rate[line - IL_RATE1] <= 0) return; i->production_rate[line - IL_RATE1] = std::max(i->production_rate[line - IL_RATE1] / 2, 0); } else { @@ -1062,8 +1062,8 @@ class IndustryViewWindow : public Window this->SetDirty(); this->SetTimeout(); this->clicked_line = line; - this->clicked_button = button; - } else if (IsInsideMM(pt.x, left + SETTING_BUTTON_WIDTH + 10, right)) { + this->clicked_button = (decrease ^ rtl) ? 1 : 2; + } else if (r.Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_normal, rtl).Contains(pt)) { /* clicked the text */ this->editbox_line = line; switch (this->editable) { @@ -1195,7 +1195,7 @@ static const NWidgetPart _nested_industry_view_widgets[] = { NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_IV_VIEWPORT), SetMinimalSize(254, 86), SetFill(1, 0), SetResize(1, 1), EndContainer(), EndContainer(), - NWidget(WWT_PANEL, COLOUR_CREAM, WID_IV_INFO), SetMinimalSize(260, 2), SetResize(1, 0), + NWidget(WWT_PANEL, COLOUR_CREAM, WID_IV_INFO), SetMinimalSize(260, 0), SetMinimalTextLines(2, WidgetDimensions::unscaled.framerect.Vertical()), SetResize(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_CREAM, WID_IV_DISPLAY), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_INDUSTRY_DISPLAY_CHAIN, STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP), @@ -1227,12 +1227,17 @@ static const NWidgetPart _nested_industry_directory_widgets[] = { EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(NWID_VERTICAL), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), - NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), - NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_ACC_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA), - NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_PROD_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA), - NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), + NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_DROPDOWN_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), + NWidget(WWT_EDITBOX, COLOUR_BROWN, WID_ID_FILTER), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_ACC_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA), + NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_ID_FILTER_BY_PROD_CARGO), SetMinimalSize(225, 12), SetFill(0, 1), SetDataTip(STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER, STR_TOOLTIP_FILTER_CRITERIA), + NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(), + EndContainer(), EndContainer(), NWidget(WWT_PANEL, COLOUR_BROWN, WID_ID_INDUSTRY_LIST), SetDataTip(0x0, STR_INDUSTRY_DIRECTORY_LIST_CAPTION), SetResize(1, 1), SetScrollbar(WID_ID_SCROLLBAR), EndContainer(), EndContainer(), @@ -1328,6 +1333,10 @@ class IndustryDirectoryWindow : public Window { byte accepted_cargo_filter_criteria; ///< Selected accepted cargo filter index static CargoID produced_cargo_filter; + const int MAX_FILTER_LENGTH = 16; ///< The max length of the filter, in chars + StringFilter string_filter; ///< Filter for industries + QueryString industry_editbox; ///< Filter editbox + enum class SorterType : uint8 { ByName, ///< Sorter type to sort by name ByType, ///< Sorter type to sort by type @@ -1412,7 +1421,13 @@ class IndustryDirectoryWindow : public Window { this->industries.clear(); for (const Industry *i : Industry::Iterate()) { - this->industries.push_back(i); + if (this->string_filter.IsEmpty()) { + this->industries.push_back(i); + continue; + } + this->string_filter.ResetState(); + this->string_filter.AddLine(i->GetCachedName()); + if (this->string_filter.GetState()) this->industries.push_back(i); } this->industries.shrink_to_fit(); @@ -1612,7 +1627,7 @@ class IndustryDirectoryWindow : public Window { } public: - IndustryDirectoryWindow(WindowDesc *desc, WindowNumber number) : Window(desc) + IndustryDirectoryWindow(WindowDesc *desc, WindowNumber number) : Window(desc), industry_editbox(MAX_FILTER_LENGTH * MAX_CHAR_LENGTH, MAX_FILTER_LENGTH) { this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_ID_SCROLLBAR); @@ -1623,6 +1638,9 @@ class IndustryDirectoryWindow : public Window { this->BuildSortIndustriesList(); this->FinishInitNested(0); + + this->querystrings[WID_ID_FILTER] = &this->industry_editbox; + this->industry_editbox.cancel_button = QueryString::ACTION_CLEAR; } ~IndustryDirectoryWindow() @@ -1661,9 +1679,9 @@ class IndustryDirectoryWindow : public Window { case WID_ID_INDUSTRY_LIST: { int n = 0; - int y = r.top + WD_FRAMERECT_TOP; + Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); if (this->industries.size() == 0) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_DIRECTORY_NONE); + DrawString(ir, STR_INDUSTRY_DIRECTORY_NONE); break; } TextColour tc; @@ -1676,9 +1694,9 @@ class IndustryDirectoryWindow : public Window { tc = TC_GREY | TC_FORCED; } } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, this->GetIndustryString(this->industries[i]), tc); + DrawString(ir, this->GetIndustryString(this->industries[i]), tc); - y += this->resize.step_height; + ir.top += this->resize.step_height; if (++n == this->vscroll->GetCapacity()) break; // max number of industries in 1 window } break; @@ -1715,8 +1733,8 @@ class IndustryDirectoryWindow : public Window { } resize->height = d.height; d.height *= 5; - d.width += padding.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += padding.width; + d.height += padding.height; *size = maxdim(*size, d); break; } @@ -1745,7 +1763,7 @@ class IndustryDirectoryWindow : public Window { break; case WID_ID_INDUSTRY_LIST: { - uint p = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_ID_INDUSTRY_LIST, WD_FRAMERECT_TOP); + uint p = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_ID_INDUSTRY_LIST, WidgetDimensions::scaled.framerect.top); if (p < this->industries.size()) { if (_ctrl_pressed) { ShowExtraViewportWindow(this->industries[p]->location.tile); @@ -1788,6 +1806,14 @@ class IndustryDirectoryWindow : public Window { this->vscroll->SetCapacityFromWidget(this, WID_ID_INDUSTRY_LIST); } + void OnEditboxChanged(int wid) override + { + if (wid == WID_ID_FILTER) { + this->string_filter.SetFilterTerm(this->industry_editbox.text.buf); + this->InvalidateData(IDIWD_FORCE_REBUILD); + } + } + void OnPaint() override { if (this->industries.NeedRebuild()) this->BuildSortIndustriesList(); @@ -1869,22 +1895,18 @@ static const NWidgetPart _nested_industry_cargoes_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_BROWN), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(NWID_VERTICAL), - NWidget(WWT_PANEL, COLOUR_BROWN, WID_IC_PANEL), SetResize(1, 10), SetMinimalSize(200, 90), SetScrollbar(WID_IC_SCROLLBAR), EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_IC_NOTIFY), - SetDataTip(STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP, STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP), - NWidget(WWT_PANEL, COLOUR_BROWN), SetFill(1, 0), SetResize(0, 0), EndContainer(), - NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_IC_IND_DROPDOWN), SetFill(0, 0), SetResize(0, 0), - SetDataTip(STR_INDUSTRY_CARGOES_SELECT_INDUSTRY, STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP), - NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_IC_CARGO_DROPDOWN), SetFill(0, 0), SetResize(0, 0), - SetDataTip(STR_INDUSTRY_CARGOES_SELECT_CARGO, STR_INDUSTRY_CARGOES_SELECT_CARGO_TOOLTIP), - EndContainer(), - EndContainer(), - NWidget(NWID_VERTICAL), - NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_IC_SCROLLBAR), - NWidget(WWT_RESIZEBOX, COLOUR_BROWN), - EndContainer(), + NWidget(WWT_PANEL, COLOUR_BROWN, WID_IC_PANEL), SetResize(1, 10), SetMinimalSize(200, 90), SetScrollbar(WID_IC_SCROLLBAR), EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_IC_SCROLLBAR), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_IC_NOTIFY), + SetDataTip(STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP, STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_BROWN), SetFill(1, 0), SetResize(0, 0), EndContainer(), + NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_IC_IND_DROPDOWN), SetFill(0, 0), SetResize(0, 0), + SetDataTip(STR_INDUSTRY_CARGOES_SELECT_INDUSTRY, STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP), + NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_IC_CARGO_DROPDOWN), SetFill(0, 0), SetResize(0, 0), + SetDataTip(STR_INDUSTRY_CARGOES_SELECT_CARGO, STR_INDUSTRY_CARGOES_SELECT_CARGO_TOOLTIP), + NWidget(WWT_RESIZEBOX, COLOUR_BROWN), EndContainer(), }; @@ -1910,8 +1932,8 @@ static const uint MAX_CARGOES = 16; ///< Maximum number of cargoes carried in a /** Data about a single field in the #IndustryCargoesWindow panel. */ struct CargoesField { - static const int VERT_INTER_INDUSTRY_SPACE; - static const int BLOB_DISTANCE; + static int vert_inter_industry_space; + static int blob_distance; static Dimension legend; static Dimension cargo_border; @@ -2101,8 +2123,8 @@ struct CargoesField { break; case CFT_INDUSTRY: { - int ypos1 = ypos + VERT_INTER_INDUSTRY_SPACE / 2; - int ypos2 = ypos + normal_height - 1 - VERT_INTER_INDUSTRY_SPACE / 2; + int ypos1 = ypos + vert_inter_industry_space / 2; + int ypos2 = ypos + normal_height - 1 - vert_inter_industry_space / 2; int xpos2 = xpos + industry_width - 1; GfxDrawLine(xpos, ypos1, xpos2, ypos1, INDUSTRY_LINE_COLOUR); GfxDrawLine(xpos, ypos1, xpos, ypos2, INDUSTRY_LINE_COLOUR); @@ -2116,14 +2138,14 @@ struct CargoesField { /* Draw the industry legend. */ int blob_left, blob_right; if (_current_text_dir == TD_RTL) { - blob_right = xpos2 - BLOB_DISTANCE; + blob_right = xpos2 - blob_distance; blob_left = blob_right - CargoesField::legend.width; } else { - blob_left = xpos + BLOB_DISTANCE; + blob_left = xpos + blob_distance; blob_right = blob_left + CargoesField::legend.width; } - GfxFillRect(blob_left, ypos2 - BLOB_DISTANCE - CargoesField::legend.height, blob_right, ypos2 - BLOB_DISTANCE, PC_BLACK); // Border - GfxFillRect(blob_left + 1, ypos2 - BLOB_DISTANCE - CargoesField::legend.height + 1, blob_right - 1, ypos2 - BLOB_DISTANCE - 1, indsp->map_colour); + GfxFillRect(blob_left, ypos2 - blob_distance - CargoesField::legend.height, blob_right, ypos2 - blob_distance, PC_BLACK); // Border + GfxFillRect(blob_left + 1, ypos2 - blob_distance - CargoesField::legend.height + 1, blob_right - 1, ypos2 - blob_distance - 1, indsp->map_colour); } else { DrawString(xpos, xpos2, ypos, STR_INDUSTRY_CARGOES_HOUSES, TC_FROMSTRING, SA_HOR_CENTER); } @@ -2158,8 +2180,8 @@ struct CargoesField { case CFT_CARGO: { int cargo_base = this->GetCargoBase(xpos); - int top = ypos + (this->u.cargo.top_end ? VERT_INTER_INDUSTRY_SPACE / 2 + 1 : 0); - int bot = ypos - (this->u.cargo.bottom_end ? VERT_INTER_INDUSTRY_SPACE / 2 + 1 : 0) + normal_height - 1; + int top = ypos + (this->u.cargo.top_end ? vert_inter_industry_space / 2 + 1 : 0); + int bot = ypos - (this->u.cargo.bottom_end ? vert_inter_industry_space / 2 + 1 : 0) + normal_height - 1; int colpos = cargo_base; for (int i = 0; i < this->u.cargo.num_cargoes; i++) { if (this->u.cargo.top_end) GfxDrawLine(colpos, top - 1, colpos + CargoesField::cargo_line.width - 1, top - 1, CARGO_LINE_COLOUR); @@ -2181,7 +2203,7 @@ struct CargoesField { hor_left = this->u.cargo.supp_cargoes; hor_right = this->u.cargo.cust_cargoes; } - ypos += CargoesField::cargo_border.height + VERT_INTER_INDUSTRY_SPACE / 2 + (FONT_HEIGHT_NORMAL - CargoesField::cargo_line.height) / 2; + ypos += CargoesField::cargo_border.height + vert_inter_industry_space / 2 + (FONT_HEIGHT_NORMAL - CargoesField::cargo_line.height) / 2; for (uint i = 0; i < MAX_CARGOES; i++) { if (hor_left[i] != INVALID_CARGO) { int col = hor_left[i]; @@ -2211,11 +2233,11 @@ struct CargoesField { } case CFT_CARGO_LABEL: - ypos += CargoesField::cargo_border.height + VERT_INTER_INDUSTRY_SPACE / 2; + ypos += CargoesField::cargo_border.height + vert_inter_industry_space / 2; for (uint i = 0; i < MAX_CARGOES; i++) { if (this->u.cargo_label.cargoes[i] != INVALID_CARGO) { const CargoSpec *csp = CargoSpec::Get(this->u.cargo_label.cargoes[i]); - DrawString(xpos + WD_FRAMERECT_LEFT, xpos + industry_width - 1 - WD_FRAMERECT_RIGHT, ypos, csp->name, TC_WHITE, + DrawString(xpos + WidgetDimensions::scaled.framerect.left, xpos + industry_width - 1 - WidgetDimensions::scaled.framerect.right, ypos, csp->name, TC_WHITE, (this->u.cargo_label.left_align) ? SA_LEFT : SA_RIGHT); } ypos += FONT_HEIGHT_NORMAL + CargoesField::cargo_space.height; @@ -2248,7 +2270,7 @@ struct CargoesField { } /* col = 0 -> left of first col, 1 -> left of 2nd col, ... this->u.cargo.num_cargoes right of last-col. */ - int vpos = VERT_INTER_INDUSTRY_SPACE / 2 + CargoesField::cargo_border.width; + int vpos = vert_inter_industry_space / 2 + CargoesField::cargo_border.width; uint row; for (row = 0; row < MAX_CARGOES; row++) { if (pt.y < vpos) return INVALID_CARGO; @@ -2295,7 +2317,7 @@ struct CargoesField { { assert(this->type == CFT_CARGO_LABEL); - int vpos = VERT_INTER_INDUSTRY_SPACE / 2 + CargoesField::cargo_border.height; + int vpos = vert_inter_industry_space / 2 + CargoesField::cargo_border.height; uint row; for (row = 0; row < MAX_CARGOES; row++) { if (pt.y < vpos) return INVALID_CARGO; @@ -2336,9 +2358,9 @@ int CargoesField::normal_height; ///< Height of the non-header rows. int CargoesField::industry_width; ///< Width of an industry field. int CargoesField::cargo_field_width; ///< Width of a cargo field. uint CargoesField::max_cargoes; ///< Largest number of cargoes actually on any industry. -const int CargoesField::VERT_INTER_INDUSTRY_SPACE = 6; ///< Amount of space between two industries in a column. +int CargoesField::vert_inter_industry_space; ///< Amount of space between two industries in a column. -const int CargoesField::BLOB_DISTANCE = 5; ///< Distance of the industry legend colour from the edge of the industry box. +int CargoesField::blob_distance; ///< Distance of the industry legend colour from the edge of the industry box. const int CargoesField::INDUSTRY_LINE_COLOUR = PC_YELLOW; ///< Line colour of the industry type box. const int CargoesField::CARGO_LINE_COLOUR = PC_YELLOW; ///< Line colour around the cargo. @@ -2481,8 +2503,6 @@ next_cargo: ; * customer industries). The remaining two columns are set to #CFT_EMPTY with a width equal to the average of a cargo and an industry column. */ struct IndustryCargoesWindow : public Window { - static const int HOR_TEXT_PADDING, VERT_TEXT_PADDING; - typedef std::vector Fields; Fields fields; ///< Fields to display in the #WID_IC_PANEL. @@ -2505,8 +2525,8 @@ struct IndustryCargoesWindow : public Window { /* Initialize static CargoesField size variables. */ Dimension d = GetStringBoundingBox(STR_INDUSTRY_CARGOES_PRODUCERS); d = maxdim(d, GetStringBoundingBox(STR_INDUSTRY_CARGOES_CUSTOMERS)); - d.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; - d.height += WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM; + d.width += WidgetDimensions::scaled.frametext.Horizontal(); + d.height += WidgetDimensions::scaled.frametext.Vertical(); CargoesField::small_height = d.height; /* Size of the legend blob -- slightly larger than the smallmap legend blob. */ @@ -2514,7 +2534,7 @@ struct IndustryCargoesWindow : public Window { CargoesField::legend.width = CargoesField::legend.height * 8 / 5; /* Size of cargo lines. */ - CargoesField::cargo_line.width = FONT_HEIGHT_NORMAL; + CargoesField::cargo_line.width = ScaleGUITrad(6); CargoesField::cargo_line.height = CargoesField::cargo_line.width; /* Size of border between cargo lines and industry boxes. */ @@ -2529,6 +2549,9 @@ struct IndustryCargoesWindow : public Window { CargoesField::cargo_stub.width = CargoesField::cargo_line.width / 2; CargoesField::cargo_stub.height = CargoesField::cargo_line.height; /* Unused */ + CargoesField::vert_inter_industry_space = WidgetDimensions::scaled.vsep_wide; + CargoesField::blob_distance = WidgetDimensions::scaled.hsep_normal; + /* Decide about the size of the box holding the text of an industry type. */ this->ind_textsize.width = 0; this->ind_textsize.height = 0; @@ -2555,13 +2578,13 @@ struct IndustryCargoesWindow : public Window { d = maxdim(d, this->cargo_textsize); // Box must also be wide enough to hold any cargo label. this->cargo_textsize = maxdim(this->cargo_textsize, GetStringBoundingBox(STR_INDUSTRY_CARGOES_SELECT_CARGO)); - d.width += 2 * HOR_TEXT_PADDING; + d.width += WidgetDimensions::scaled.frametext.Horizontal(); /* Ensure the height is enough for the industry type text, for the horizontal connections, and for the cargo labels. */ uint min_ind_height = CargoesField::cargo_border.height * 2 + CargoesField::max_cargoes * FONT_HEIGHT_NORMAL + (CargoesField::max_cargoes - 1) * CargoesField::cargo_space.height; - d.height = std::max(d.height + 2 * VERT_TEXT_PADDING, min_ind_height); + d.height = std::max(d.height + WidgetDimensions::scaled.frametext.Vertical(), min_ind_height); CargoesField::industry_width = d.width; - CargoesField::normal_height = d.height + CargoesField::VERT_INTER_INDUSTRY_SPACE; + CargoesField::normal_height = d.height + CargoesField::vert_inter_industry_space; /* Width of a #CFT_CARGO field. */ CargoesField::cargo_field_width = CargoesField::cargo_border.width * 2 + CargoesField::cargo_line.width * CargoesField::max_cargoes + CargoesField::cargo_space.width * (CargoesField::max_cargoes - 1); @@ -2572,8 +2595,8 @@ struct IndustryCargoesWindow : public Window { switch (widget) { case WID_IC_PANEL: resize->height = CargoesField::normal_height; - size->width = WD_FRAMETEXT_LEFT + CargoesField::industry_width * 3 + CargoesField::cargo_field_width * 2 + WD_FRAMETEXT_RIGHT; - size->height = WD_FRAMETEXT_TOP + CargoesField::small_height + 2 * resize->height + WD_FRAMETEXT_BOTTOM; + size->width = CargoesField::industry_width * 3 + CargoesField::cargo_field_width * 2 + WidgetDimensions::scaled.frametext.Horizontal(); + size->height = CargoesField::small_height + 2 * resize->height + WidgetDimensions::scaled.frametext.Vertical(); break; case WID_IC_IND_DROPDOWN: @@ -2765,12 +2788,12 @@ struct IndustryCargoesWindow : public Window { _displayed_industries.set(displayed_it); this->fields.clear(); - CargoesRow &row = this->fields.emplace_back(); - row.columns[0].MakeHeader(STR_INDUSTRY_CARGOES_PRODUCERS); - row.columns[1].MakeEmpty(CFT_SMALL_EMPTY); - row.columns[2].MakeEmpty(CFT_SMALL_EMPTY); - row.columns[3].MakeEmpty(CFT_SMALL_EMPTY); - row.columns[4].MakeHeader(STR_INDUSTRY_CARGOES_CUSTOMERS); + CargoesRow &first_row = this->fields.emplace_back(); + first_row.columns[0].MakeHeader(STR_INDUSTRY_CARGOES_PRODUCERS); + first_row.columns[1].MakeEmpty(CFT_SMALL_EMPTY); + first_row.columns[2].MakeEmpty(CFT_SMALL_EMPTY); + first_row.columns[3].MakeEmpty(CFT_SMALL_EMPTY); + first_row.columns[4].MakeHeader(STR_INDUSTRY_CARGOES_CUSTOMERS); const IndustrySpec *central_sp = GetIndustrySpec(displayed_it); bool houses_supply = HousesCanSupply(central_sp->accepts_cargo, lengthof(central_sp->accepts_cargo)); @@ -2842,12 +2865,12 @@ struct IndustryCargoesWindow : public Window { _displayed_industries.reset(); this->fields.clear(); - CargoesRow &row = this->fields.emplace_back(); - row.columns[0].MakeHeader(STR_INDUSTRY_CARGOES_PRODUCERS); - row.columns[1].MakeEmpty(CFT_SMALL_EMPTY); - row.columns[2].MakeHeader(STR_INDUSTRY_CARGOES_CUSTOMERS); - row.columns[3].MakeEmpty(CFT_SMALL_EMPTY); - row.columns[4].MakeEmpty(CFT_SMALL_EMPTY); + CargoesRow &first_row = this->fields.emplace_back(); + first_row.columns[0].MakeHeader(STR_INDUSTRY_CARGOES_PRODUCERS); + first_row.columns[1].MakeEmpty(CFT_SMALL_EMPTY); + first_row.columns[2].MakeHeader(STR_INDUSTRY_CARGOES_CUSTOMERS); + first_row.columns[3].MakeEmpty(CFT_SMALL_EMPTY); + first_row.columns[4].MakeEmpty(CFT_SMALL_EMPTY); bool houses_supply = HousesCanSupply(&cid, 1); bool houses_accept = HousesCanAccept(&cid, 1); @@ -2924,14 +2947,12 @@ struct IndustryCargoesWindow : public Window { { if (widget != WID_IC_PANEL) return; - DrawPixelInfo tmp_dpi, *old_dpi; - int width = r.right - r.left + 1; - int height = r.bottom - r.top + 1 - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM; - if (!FillDrawPixelInfo(&tmp_dpi, r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, width, height)) return; - old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); + DrawPixelInfo tmp_dpi; + if (!FillDrawPixelInfo(&tmp_dpi, ir.left, ir.top, ir.Width(), ir.Height())) return; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); - int left_pos = WD_FRAMERECT_LEFT; + int left_pos = ir.left; if (this->ind_cargo >= NUM_INDUSTRYTYPES) left_pos += (CargoesField::industry_width + CargoesField::cargo_field_width) / 2; int last_column = (this->ind_cargo < NUM_INDUSTRYTYPES) ? 4 : 2; @@ -2958,8 +2979,6 @@ struct IndustryCargoesWindow : public Window { vpos += row_height; if (vpos >= height) break; } - - _cur_dpi = old_dpi; } /** @@ -2975,7 +2994,7 @@ struct IndustryCargoesWindow : public Window { pt.x -= nw->pos_x; pt.y -= nw->pos_y; - int vpos = WD_FRAMERECT_TOP + CargoesField::small_height - this->vscroll->GetPosition() * nw->resize_y; + int vpos = WidgetDimensions::scaled.framerect.top + CargoesField::small_height - this->vscroll->GetPosition() * nw->resize_y; if (pt.y < vpos) return false; int row = (pt.y - vpos) / CargoesField::normal_height; // row is relative to row 1. @@ -2983,7 +3002,7 @@ struct IndustryCargoesWindow : public Window { vpos = pt.y - vpos - row * CargoesField::normal_height; // Position in the row + 1 field row++; // rebase row to match index of this->fields. - int xpos = 2 * WD_FRAMERECT_LEFT + ((this->ind_cargo < NUM_INDUSTRYTYPES) ? 0 : (CargoesField::industry_width + CargoesField::cargo_field_width) / 2); + int xpos = 2 * WidgetDimensions::scaled.framerect.left + ((this->ind_cargo < NUM_INDUSTRYTYPES) ? 0 : (CargoesField::industry_width + CargoesField::cargo_field_width) / 2); if (pt.x < xpos) return false; int column; for (column = 0; column <= 5; column++) { @@ -3139,13 +3158,10 @@ struct IndustryCargoesWindow : public Window { void OnResize() override { - this->vscroll->SetCapacityFromWidget(this, WID_IC_PANEL, WD_FRAMERECT_TOP + CargoesField::small_height); + this->vscroll->SetCapacityFromWidget(this, WID_IC_PANEL, WidgetDimensions::scaled.framerect.top + CargoesField::small_height); } }; -const int IndustryCargoesWindow::HOR_TEXT_PADDING = 5; ///< Horizontal padding around the industry type text. -const int IndustryCargoesWindow::VERT_TEXT_PADDING = 5; ///< Vertical padding around the industry type text. - /** * Open the industry and cargoes window. * @param id Industry type to display, \c NUM_INDUSTRYTYPES selects a default industry type. diff --git a/src/industry_map.h b/src/industry_map.h index 1cdf90e59a016..f1e61827553a2 100644 --- a/src/industry_map.h +++ b/src/industry_map.h @@ -60,10 +60,10 @@ enum IndustryGraphics { * @pre IsTileType(t, MP_INDUSTRY) * @return the industry ID */ -static inline IndustryID GetIndustryIndex(TileIndex t) +static inline IndustryID GetIndustryIndex(Tile t) { assert(IsTileType(t, MP_INDUSTRY)); - return _m[t].m2; + return t.m2(); } /** @@ -72,23 +72,23 @@ static inline IndustryID GetIndustryIndex(TileIndex t) * @pre IsTileType(t, MP_INDUSTRY) * @return true if and only if the industry tile is fully built */ -static inline bool IsIndustryCompleted(TileIndex t) +static inline bool IsIndustryCompleted(Tile t) { assert(IsTileType(t, MP_INDUSTRY)); - return HasBit(_m[t].m1, 7); + return HasBit(t.m1(), 7); } -IndustryType GetIndustryType(TileIndex tile); +IndustryType GetIndustryType(Tile tile); /** * Set if the industry that owns the tile as under construction or not * @param tile the tile to query * @pre IsTileType(tile, MP_INDUSTRY) */ -static inline void SetIndustryCompleted(TileIndex tile) +static inline void SetIndustryCompleted(Tile tile) { assert(IsTileType(tile, MP_INDUSTRY)); - SB(_m[tile].m1, 7, 1, 1); + SB(tile.m1(), 7, 1, 1); } /** @@ -97,10 +97,10 @@ static inline void SetIndustryCompleted(TileIndex tile) * @pre IsTileType(tile, MP_INDUSTRY) * @return the construction stage */ -static inline byte GetIndustryConstructionStage(TileIndex tile) +static inline byte GetIndustryConstructionStage(Tile tile) { assert(IsTileType(tile, MP_INDUSTRY)); - return IsIndustryCompleted(tile) ? (byte)INDUSTRY_COMPLETED : GB(_m[tile].m1, 0, 2); + return IsIndustryCompleted(tile) ? (byte)INDUSTRY_COMPLETED : GB(tile.m1(), 0, 2); } /** @@ -109,10 +109,10 @@ static inline byte GetIndustryConstructionStage(TileIndex tile) * @param value the new construction stage * @pre IsTileType(tile, MP_INDUSTRY) */ -static inline void SetIndustryConstructionStage(TileIndex tile, byte value) +static inline void SetIndustryConstructionStage(Tile tile, byte value) { assert(IsTileType(tile, MP_INDUSTRY)); - SB(_m[tile].m1, 0, 2, value); + SB(tile.m1(), 0, 2, value); } /** @@ -122,10 +122,10 @@ static inline void SetIndustryConstructionStage(TileIndex tile, byte value) * @pre IsTileType(t, MP_INDUSTRY) * @return the gfx ID */ -static inline IndustryGfx GetCleanIndustryGfx(TileIndex t) +static inline IndustryGfx GetCleanIndustryGfx(Tile t) { assert(IsTileType(t, MP_INDUSTRY)); - return _m[t].m5 | (GB(_me[t].m6, 2, 1) << 8); + return t.m5() | (GB(t.m6(), 2, 1) << 8); } /** @@ -134,7 +134,7 @@ static inline IndustryGfx GetCleanIndustryGfx(TileIndex t) * @pre IsTileType(t, MP_INDUSTRY) * @return the gfx ID */ -static inline IndustryGfx GetIndustryGfx(TileIndex t) +static inline IndustryGfx GetIndustryGfx(Tile t) { assert(IsTileType(t, MP_INDUSTRY)); return GetTranslatedIndustryTileID(GetCleanIndustryGfx(t)); @@ -146,11 +146,11 @@ static inline IndustryGfx GetIndustryGfx(TileIndex t) * @pre IsTileType(t, MP_INDUSTRY) * @param gfx the graphics ID */ -static inline void SetIndustryGfx(TileIndex t, IndustryGfx gfx) +static inline void SetIndustryGfx(Tile t, IndustryGfx gfx) { assert(IsTileType(t, MP_INDUSTRY)); - _m[t].m5 = GB(gfx, 0, 8); - SB(_me[t].m6, 2, 1, GB(gfx, 8, 1)); + t.m5() = GB(gfx, 0, 8); + SB(t.m6(), 2, 1, GB(gfx, 8, 1)); } /** @@ -159,10 +159,10 @@ static inline void SetIndustryGfx(TileIndex t, IndustryGfx gfx) * @pre IsTileType(tile, MP_INDUSTRY) * @return the construction counter */ -static inline byte GetIndustryConstructionCounter(TileIndex tile) +static inline byte GetIndustryConstructionCounter(Tile tile) { assert(IsTileType(tile, MP_INDUSTRY)); - return GB(_m[tile].m1, 2, 2); + return GB(tile.m1(), 2, 2); } /** @@ -171,10 +171,10 @@ static inline byte GetIndustryConstructionCounter(TileIndex tile) * @param value the new value for the construction counter * @pre IsTileType(tile, MP_INDUSTRY) */ -static inline void SetIndustryConstructionCounter(TileIndex tile, byte value) +static inline void SetIndustryConstructionCounter(Tile tile, byte value) { assert(IsTileType(tile, MP_INDUSTRY)); - SB(_m[tile].m1, 2, 2, value); + SB(tile.m1(), 2, 2, value); } /** @@ -184,11 +184,11 @@ static inline void SetIndustryConstructionCounter(TileIndex tile, byte value) * @param tile the tile to query * @pre IsTileType(tile, MP_INDUSTRY) */ -static inline void ResetIndustryConstructionStage(TileIndex tile) +static inline void ResetIndustryConstructionStage(Tile tile) { assert(IsTileType(tile, MP_INDUSTRY)); - SB(_m[tile].m1, 0, 4, 0); - SB(_m[tile].m1, 7, 1, 0); + SB(tile.m1(), 0, 4, 0); + SB(tile.m1(), 7, 1, 0); } /** @@ -196,10 +196,10 @@ static inline void ResetIndustryConstructionStage(TileIndex tile) * @param tile the tile to get the animation loop number of * @pre IsTileType(tile, MP_INDUSTRY) */ -static inline byte GetIndustryAnimationLoop(TileIndex tile) +static inline byte GetIndustryAnimationLoop(Tile tile) { assert(IsTileType(tile, MP_INDUSTRY)); - return _m[tile].m4; + return tile.m4(); } /** @@ -208,63 +208,63 @@ static inline byte GetIndustryAnimationLoop(TileIndex tile) * @param count the new animation frame number * @pre IsTileType(tile, MP_INDUSTRY) */ -static inline void SetIndustryAnimationLoop(TileIndex tile, byte count) +static inline void SetIndustryAnimationLoop(Tile tile, byte count) { assert(IsTileType(tile, MP_INDUSTRY)); - _m[tile].m4 = count; + tile.m4() = count; } /** * Get the random bits for this tile. * Used for grf callbacks - * @param tile TileIndex of the tile to query + * @param tile the tile to query * @pre IsTileType(tile, MP_INDUSTRY) * @return requested bits */ -static inline byte GetIndustryRandomBits(TileIndex tile) +static inline byte GetIndustryRandomBits(Tile tile) { assert(IsTileType(tile, MP_INDUSTRY)); - return _m[tile].m3; + return tile.m3(); } /** * Set the random bits for this tile. * Used for grf callbacks - * @param tile TileIndex of the tile to query + * @param tile the tile to query * @param bits the random bits * @pre IsTileType(tile, MP_INDUSTRY) */ -static inline void SetIndustryRandomBits(TileIndex tile, byte bits) +static inline void SetIndustryRandomBits(Tile tile, byte bits) { assert(IsTileType(tile, MP_INDUSTRY)); - _m[tile].m3 = bits; + tile.m3() = bits; } /** * Get the activated triggers bits for this industry tile * Used for grf callbacks - * @param tile TileIndex of the tile to query + * @param tile the tile to query * @pre IsTileType(tile, MP_INDUSTRY) * @return requested triggers */ -static inline byte GetIndustryTriggers(TileIndex tile) +static inline byte GetIndustryTriggers(Tile tile) { assert(IsTileType(tile, MP_INDUSTRY)); - return GB(_me[tile].m6, 3, 3); + return GB(tile.m6(), 3, 3); } /** * Set the activated triggers bits for this industry tile * Used for grf callbacks - * @param tile TileIndex of the tile to query + * @param tile the tile to query * @param triggers the triggers to set * @pre IsTileType(tile, MP_INDUSTRY) */ -static inline void SetIndustryTriggers(TileIndex tile, byte triggers) +static inline void SetIndustryTriggers(Tile tile, byte triggers) { assert(IsTileType(tile, MP_INDUSTRY)); - SB(_me[tile].m6, 3, 3, triggers); + SB(tile.m6(), 3, 3, triggers); } /** @@ -275,17 +275,17 @@ static inline void SetIndustryTriggers(TileIndex tile, byte triggers) * @param random the random value * @param wc the water class for this industry; only useful when build on water */ -static inline void MakeIndustry(TileIndex t, IndustryID index, IndustryGfx gfx, uint8 random, WaterClass wc) +static inline void MakeIndustry(Tile t, IndustryID index, IndustryGfx gfx, uint8 random, WaterClass wc) { SetTileType(t, MP_INDUSTRY); - _m[t].m1 = 0; - _m[t].m2 = index; + t.m1() = 0; + t.m2() = index; SetIndustryRandomBits(t, random); // m3 - _m[t].m4 = 0; + t.m4() = 0; SetIndustryGfx(t, gfx); // m5, part of m6 SetIndustryTriggers(t, 0); // rest of m6 SetWaterClass(t, wc); - _me[t].m7 = 0; + t.m7() = 0; } #endif /* INDUSTRY_MAP_H */ diff --git a/src/intro_gui.cpp b/src/intro_gui.cpp index d163edc6362c0..bdee1351d1b96 100644 --- a/src/intro_gui.cpp +++ b/src/intro_gui.cpp @@ -22,6 +22,7 @@ #include "strings_func.h" #include "fios.h" #include "ai/ai_gui.hpp" +#include "game/game_gui.hpp" #include "gfx_func.h" #include "core/geometry_func.hpp" #include "language.h" @@ -259,7 +260,7 @@ struct SelectGameWindow : public Window { } IntroGameViewportCommand &vc = intro_viewport_commands[this->cur_viewport_command_index]; - Window *mw = FindWindowByClass(WC_MAIN_WINDOW); + Window *mw = GetMainWindow(); Viewport *vp = mw->viewport; /* Early exit if the current command hasn't elapsed and isn't animated. */ @@ -416,6 +417,7 @@ struct SelectGameWindow : public Window { } break; case WID_SGI_AI_SETTINGS: ShowAIConfigWindow(); break; + case WID_SGI_GS_SETTINGS: ShowGSConfigWindow(); break; case WID_SGI_GAMEYEAR_DROPDOWN: // Game Year generator ShowDropDownList( this, @@ -432,18 +434,27 @@ struct SelectGameWindow : public Window { switch (widget) { case WID_SGI_GAMEYEAR_DROPDOWN: // Game year if (_game_mode == GM_MENU) { - _settings_newgame.game_creation.year_pace_option = index; + // _newgame, because that's what this applies to. + // _game, because GetPaceFactor() uses values from that. if (!index) { ShowSetPaceFactorWindow( this, _settings_newgame.game_creation.year_pace_custom_15minutes, [this](int pace_factor) { + _settings_newgame.game_creation.year_pace_option = 0; + _settings_game.game_creation.year_pace_option = 0; _settings_newgame.game_creation.year_pace_custom_15minutes = pace_factor; + _settings_game.game_creation.year_pace_custom_15minutes = pace_factor; + SetWindowDirty(WC_GAME_OPTIONS, WN_GAME_OPTIONS_GAME_OPTIONS); this->InvalidateData(); } ); + } else { + _settings_newgame.game_creation.year_pace_option = index; + _settings_game.game_creation.year_pace_option = index; } + } break; } @@ -457,7 +468,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(WWT_PANEL, COLOUR_BROWN), NWidget(NWID_SPACER), SetMinimalSize(0, 8), - /* 'generate game' and 'load game' buttons */ + /* 'New Game' and 'Load Game' buttons */ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_GENERATE_GAME), SetMinimalSize(158, 12), SetDataTip(STR_INTRO_NEW_GAME, STR_INTRO_TOOLTIP_NEW_GAME), SetPadding(0, 0, 0, 10), SetFill(1, 0), @@ -467,7 +478,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 6), - /* 'play scenario' and 'play heightmap' buttons */ + /* 'Play Scenario' and 'Play Heightmap' buttons */ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_PLAY_SCENARIO), SetMinimalSize(158, 12), SetDataTip(STR_INTRO_PLAY_SCENARIO, STR_INTRO_TOOLTIP_PLAY_SCENARIO), SetPadding(0, 0, 0, 10), SetFill(1, 0), @@ -477,7 +488,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 6), - /* 'edit scenario' and 'play multiplayer' buttons */ + /* 'Scenario Editor' and 'Multiplayer' buttons */ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_EDIT_SCENARIO), SetMinimalSize(158, 12), SetDataTip(STR_INTRO_SCENARIO_EDITOR, STR_INTRO_TOOLTIP_SCENARIO_EDITOR), SetPadding(0, 0, 0, 10), SetFill(1, 0), @@ -487,7 +498,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 7), - /* climate selection buttons */ + /* Climate selection buttons */ NWidget(NWID_HORIZONTAL), NWidget(NWID_SPACER), SetMinimalSize(10, 0), SetFill(1, 0), NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_SGI_TEMPERATE_LANDSCAPE), SetMinimalSize(77, 55), @@ -531,7 +542,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 6), - /* 'game options' and 'advanced settings' buttons */ + /* 'Game Options' and 'Settings' buttons */ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_OPTIONS), SetMinimalSize(158, 12), SetDataTip(STR_INTRO_GAME_OPTIONS, STR_INTRO_TOOLTIP_GAME_OPTIONS), SetPadding(0, 0, 0, 10), SetFill(1, 0), @@ -541,27 +552,35 @@ static const NWidgetPart _nested_select_game_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 6), - /* 'script settings' and 'newgrf settings' buttons */ + /* 'AI Settings' and 'Game Script Settings' buttons */ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_AI_SETTINGS), SetMinimalSize(158, 12), - SetDataTip(STR_INTRO_SCRIPT_SETTINGS, STR_INTRO_TOOLTIP_SCRIPT_SETTINGS), SetPadding(0, 0, 0, 10), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_GRF_SETTINGS), SetMinimalSize(158, 12), - SetDataTip(STR_INTRO_NEWGRF_SETTINGS, STR_INTRO_TOOLTIP_NEWGRF_SETTINGS), SetPadding(0, 10, 0, 0), SetFill(1, 0), + SetDataTip(STR_INTRO_AI_SETTINGS, STR_INTRO_TOOLTIP_AI_SETTINGS), SetPadding(0, 0, 0, 10), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_GS_SETTINGS), SetMinimalSize(158, 12), + SetDataTip(STR_INTRO_GAMESCRIPT_SETTINGS, STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS), SetPadding(0, 10, 0, 0), SetFill(1, 0), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 6), - /* 'online content' and 'highscore' buttons */ + /* 'Check Online Content' and 'NewGRF Settings' buttons */ NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_CONTENT_DOWNLOAD), SetMinimalSize(158, 12), SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), SetPadding(0, 0, 0, 10), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_HIGHSCORE), SetMinimalSize(158, 12), - SetDataTip(STR_INTRO_HIGHSCORE, STR_INTRO_TOOLTIP_HIGHSCORE), SetPadding(0, 10, 0, 0), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_GRF_SETTINGS), SetMinimalSize(158, 12), + SetDataTip(STR_INTRO_NEWGRF_SETTINGS, STR_INTRO_TOOLTIP_NEWGRF_SETTINGS), SetPadding(0, 10, 0, 0), SetFill(1, 0), + EndContainer(), + + NWidget(NWID_SPACER), SetMinimalSize(0, 6), + + /* 'Highscore Table' button */ + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_HIGHSCORE), SetMinimalSize(316, 12), + SetDataTip(STR_INTRO_HIGHSCORE, STR_INTRO_TOOLTIP_HIGHSCORE), SetPadding(0, 10, 0, 10), SetFill(1, 0), EndContainer(), NWidget(NWID_SPACER), SetMinimalSize(0, 6), - /* 'exit program' button */ + /* 'Exit' button */ NWidget(NWID_HORIZONTAL), NWidget(NWID_SPACER), SetFill(1, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_EXIT), SetMinimalSize(128, 12), diff --git a/src/landscape.cpp b/src/landscape.cpp index b921deef22fdf..af70e74982d3c 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -32,6 +32,8 @@ #include "saveload/saveload.h" #include "framerate_type.h" #include "landscape_cmd.h" +#include "terraform_cmd.h" +#include "station_func.h" #include #include #include @@ -111,8 +113,8 @@ Point InverseRemapCoords2(int x, int y, bool clamp_to_map, bool *clamped) Point pt = InverseRemapCoords(x, y); const uint min_coord = _settings_game.construction.freeform_edges ? TILE_SIZE : 0; - const uint max_x = MapMaxX() * TILE_SIZE - 1; - const uint max_y = MapMaxY() * TILE_SIZE - 1; + const uint max_x = Map::MaxX() * TILE_SIZE - 1; + const uint max_y = Map::MaxY() * TILE_SIZE - 1; if (clamp_to_map) { /* Bring the coordinates near to a valid range. At the top we allow a number @@ -358,7 +360,7 @@ int GetSlopePixelZ(int x, int y) */ int GetSlopePixelZOutsideMap(int x, int y) { - if (IsInsideBS(x, 0, MapSizeX() * TILE_SIZE) && IsInsideBS(y, 0, MapSizeY() * TILE_SIZE)) { + if (IsInsideBS(x, 0, Map::SizeX() * TILE_SIZE) && IsInsideBS(y, 0, Map::SizeY() * TILE_SIZE)) { return GetSlopePixelZ(x, y); } else { return _tile_type_procs[MP_VOID]->get_slope_z_proc(INVALID_TILE, x, y); @@ -498,7 +500,7 @@ void DrawFoundation(TileInfo *ti, Foundation f) if (!IsNonContinuousFoundation(f)) { /* Lower part of foundation */ AddSortableSpriteToDraw( - leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z + leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z ); } @@ -510,38 +512,44 @@ void DrawFoundation(TileInfo *ti, Foundation f) byte inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0); AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, - f == FOUNDATION_INCLINED_X ? 16 : 1, - f == FOUNDATION_INCLINED_Y ? 16 : 1, + f == FOUNDATION_INCLINED_X ? TILE_SIZE : 1, + f == FOUNDATION_INCLINED_Y ? TILE_SIZE : 1, TILE_HEIGHT, ti->z ); - OffsetGroundSprite(31, 9); + OffsetGroundSprite(0, 0); } else if (IsLeveledFoundation(f)) { - AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z - TILE_HEIGHT); - OffsetGroundSprite(31, 1); + AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z - TILE_HEIGHT); + OffsetGroundSprite(0, -(int)TILE_HEIGHT); } else if (f == FOUNDATION_STEEP_LOWER) { /* one corner raised */ - OffsetGroundSprite(31, 1); + OffsetGroundSprite(0, -(int)TILE_HEIGHT); } else { /* halftile foundation */ - int x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? 8 : 0); - int y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? 8 : 0); - - AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z + TILE_HEIGHT); - OffsetGroundSprite(31, 9); + int x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? TILE_SIZE / 2 : 0); + int y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? TILE_SIZE / 2 : 0); + + AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1, ti->z + TILE_HEIGHT); + /* Reposition ground sprite back to original position after bounding box change above. This is similar to + * RemapCoords() but without zoom scaling. */ + Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb}; + OffsetGroundSprite(-pt.x, -pt.y); } } else { if (IsLeveledFoundation(f)) { /* leveled foundation */ - AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z); - OffsetGroundSprite(31, 1); + AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z); + OffsetGroundSprite(0, -(int)TILE_HEIGHT); } else if (IsNonContinuousFoundation(f)) { /* halftile foundation */ Corner halftile_corner = GetHalftileFoundationCorner(f); - int x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? 8 : 0); - int y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? 8 : 0); - - AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z); - OffsetGroundSprite(31, 9); + int x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? TILE_SIZE / 2 : 0); + int y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? TILE_SIZE / 2 : 0); + + AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1, ti->z); + /* Reposition ground sprite back to original position after bounding box change above. This is similar to + * RemapCoords() but without zoom scaling. */ + Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb}; + OffsetGroundSprite(-pt.x, -pt.y); } else if (IsSpecialRailFoundation(f)) { /* anti-zig-zag foundation */ SpriteID spr; @@ -552,18 +560,18 @@ void DrawFoundation(TileInfo *ti, Foundation f) /* tile-slope = sloped along X/Y, foundation-slope = three corners raised */ spr = inclined_base + 2 * GetRailFoundationCorner(f) + ((ti->tileh == SLOPE_SW || ti->tileh == SLOPE_NE) ? 1 : 0); } - AddSortableSpriteToDraw(spr, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z); - OffsetGroundSprite(31, 9); + AddSortableSpriteToDraw(spr, PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z); + OffsetGroundSprite(0, 0); } else { /* inclined foundation */ byte inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0); AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, - f == FOUNDATION_INCLINED_X ? 16 : 1, - f == FOUNDATION_INCLINED_Y ? 16 : 1, + f == FOUNDATION_INCLINED_X ? TILE_SIZE : 1, + f == FOUNDATION_INCLINED_Y ? TILE_SIZE : 1, TILE_HEIGHT, ti->z ); - OffsetGroundSprite(31, 9); + OffsetGroundSprite(0, 0); } ti->z += ApplyPixelFoundationToSlope(f, &ti->tileh); } @@ -574,8 +582,10 @@ void DoClearSquare(TileIndex tile) /* If the tile can have animation and we clear it, delete it from the animated tile list. */ if (_tile_type_procs[GetTileType(tile)]->animate_tile_proc != nullptr) DeleteAnimatedTile(tile); + bool remove = IsDockingTile(tile); MakeClear(tile, CLEAR_GRASS, _generating_world ? 3 : 0); MarkTileDirtyByTile(tile); + if (remove) RemoveDockingTile(tile); } /** @@ -738,7 +748,7 @@ CommandCost CmdLandscapeClear(DoCommandFlag flags, TileIndex tile) */ std::tuple CmdClearArea(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, bool diagonal) { - if (start_tile >= MapSize()) return { CMD_ERROR, 0 }; + if (start_tile >= Map::Size()) return { CMD_ERROR, 0 }; Money money = GetAvailableMoneyForCommand(); CommandCost cost(EXPENSES_CONSTRUCTION); @@ -748,7 +758,7 @@ std::tuple CmdClearArea(DoCommandFlag flags, TileIndex tile, const Company *c = (flags & (DC_AUTO | DC_BANKRUPT)) ? nullptr : Company::GetIfValid(_current_company); int limit = (c == nullptr ? INT32_MAX : GB(c->clear_limit, 16, 16)); - TileIterator *iter = diagonal ? (TileIterator *)new DiagonalTileIterator(tile, start_tile) : new OrthogonalTileIterator(tile, start_tile); + std::unique_ptr iter = TileIterator::Create(tile, start_tile, diagonal); for (; *iter != INVALID_TILE; ++(*iter)) { TileIndex t = *iter; CommandCost ret = Command::Do(flags & ~DC_EXEC, t); @@ -764,7 +774,6 @@ std::tuple CmdClearArea(DoCommandFlag flags, TileIndex tile, if (flags & DC_EXEC) { money -= ret.GetCost(); if (ret.GetCost() > 0 && money < 0) { - delete iter; return { cost, ret.GetCost() }; } Command::Do(flags, t); @@ -784,7 +793,6 @@ std::tuple CmdClearArea(DoCommandFlag flags, TileIndex tile, cost.AddCost(ret); } - delete iter; return { had_success ? cost : last_error, 0 }; } @@ -808,10 +816,10 @@ void RunTileLoop() 0xD8F, 0x1296, 0x2496, 0x4357, 0x8679, 0x1030E, 0x206CD, 0x403FE, 0x807B8, 0x1004B2, 0x2006A8, 0x4004B2, 0x800B87 }; static_assert(lengthof(feedbacks) == 2 * MAX_MAP_SIZE_BITS - 2 * MIN_MAP_SIZE_BITS + 1); - const uint32 feedback = feedbacks[MapLogX() + MapLogY() - 2 * MIN_MAP_SIZE_BITS]; + const uint32 feedback = feedbacks[Map::LogX() + Map::LogY() - 2 * MIN_MAP_SIZE_BITS]; /* We update every tile every 256 ticks, so divide the map size by 2^8 = 256 */ - uint count = 1 << (MapLogX() + MapLogY() - 8); + uint count = 1 << (Map::LogX() + Map::LogY() - 8); TileIndex tile = _cur_tileloop_tile; /* The LFSR cannot have a zeroed state. */ @@ -835,8 +843,8 @@ void RunTileLoop() void InitializeLandscape() { - for (uint y = _settings_game.construction.freeform_edges ? 1 : 0; y < MapMaxY(); y++) { - for (uint x = _settings_game.construction.freeform_edges ? 1 : 0; x < MapMaxX(); x++) { + for (uint y = _settings_game.construction.freeform_edges ? 1 : 0; y < Map::MaxY(); y++) { + for (uint x = _settings_game.construction.freeform_edges ? 1 : 0; x < Map::MaxX(); x++) { MakeClear(TileXY(x, y), CLEAR_GRASS, 3); SetTileHeight(TileXY(x, y), 0); SetTropicZone(TileXY(x, y), TROPICZONE_NORMAL); @@ -844,8 +852,8 @@ void InitializeLandscape() } } - for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, MapMaxY())); - for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(MapMaxX(), y)); + for (uint x = 0; x < Map::SizeX(); x++) MakeVoid(TileXY(x, Map::MaxY())); + for (uint y = 0; y < Map::SizeY(); y++) MakeVoid(TileXY(Map::MaxX(), y)); } static const byte _genterrain_tbl_1[5] = { 10, 22, 33, 37, 4 }; @@ -855,12 +863,15 @@ static void GenerateTerrain(int type, uint flag) { uint32 r = Random(); - const Sprite *templ = GetSprite((((r >> 24) * _genterrain_tbl_1[type]) >> 8) + _genterrain_tbl_2[type] + 4845, ST_MAPGEN); + /* Choose one of the templates from the graphics file. */ + const Sprite *templ = GetSprite((((r >> 24) * _genterrain_tbl_1[type]) >> 8) + _genterrain_tbl_2[type] + SPR_MAPGEN_BEGIN, ST_MAPGEN); if (templ == nullptr) usererror("Map generator sprites could not be loaded"); - uint x = r & MapMaxX(); - uint y = (r >> MapLogX()) & MapMaxY(); + /* Chose a random location to apply the template to. */ + uint x = r & Map::MaxX(); + uint y = (r >> Map::LogX()) & Map::MaxY(); + /* Make sure the template is not too close to the upper edges; bottom edges are checked later. */ uint edge_distance = 1 + (_settings_game.construction.freeform_edges ? 1 : 0); if (x <= edge_distance || y <= edge_distance) return; @@ -873,14 +884,17 @@ static void GenerateTerrain(int type, uint flag) const byte *p = templ->data; if ((flag & 4) != 0) { - uint xw = x * MapSizeY(); - uint yw = y * MapSizeX(); - uint bias = (MapSizeX() + MapSizeY()) * 16; + /* This is only executed in secondary/tertiary loops to generate the terrain for arctic and tropic. + * It prevents the templates to be applied to certain parts of the map based on the flags, thus + * creating regions with different elevations/topography. */ + uint xw = x * Map::SizeY(); + uint yw = y * Map::SizeX(); + uint bias = (Map::SizeX() + Map::SizeY()) * 16; switch (flag & 3) { default: NOT_REACHED(); case 0: - if (xw + yw > MapSize() - bias) return; + if (xw + yw > Map::Size() - bias) return; break; case 1: @@ -888,7 +902,7 @@ static void GenerateTerrain(int type, uint flag) break; case 2: - if (xw + yw < MapSize() + bias) return; + if (xw + yw < Map::Size() + bias) return; break; case 3: @@ -897,11 +911,15 @@ static void GenerateTerrain(int type, uint flag) } } - if (x + w >= MapMaxX()) return; - if (y + h >= MapMaxY()) return; + /* Ensure the template does not overflow at the bottom edges of the map; upper edges were checked before. */ + if (x + w >= Map::MaxX()) return; + if (y + h >= Map::MaxY()) return; TileIndex tile = TileXY(x, y); + /* Get the template and overlay in a particular direction over the map's height from the given + * origin point (tile), and update the map's height everywhere where the height from the template + * is higher than the height of the map. In other words, this only raises the tile heights. */ switch (direction) { default: NOT_REACHED(); case DIAGDIR_NE: @@ -965,10 +983,10 @@ static void GenerateTerrain(int type, uint flag) static void CreateDesertOrRainForest(uint desert_tropic_line) { - TileIndex update_freq = MapSize() / 4; + TileIndex update_freq = Map::Size() / 4; const TileIndexDiffC *data; - for (TileIndex tile = 0; tile != MapSize(); ++tile) { + for (TileIndex tile = 0; tile != Map::Size(); ++tile) { if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE); if (!IsValidTile(tile)) continue; @@ -989,7 +1007,7 @@ static void CreateDesertOrRainForest(uint desert_tropic_line) RunTileLoop(); } - for (TileIndex tile = 0; tile != MapSize(); ++tile) { + for (TileIndex tile = 0; tile != Map::Size(); ++tile) { if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE); if (!IsValidTile(tile)) continue; @@ -1056,11 +1074,7 @@ static bool MakeLake(TileIndex tile, void *user_data) for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) { TileIndex t2 = tile + TileOffsByDiagDir(d); if (IsWaterTile(t2)) { - MakeRiver(tile, Random()); - MarkTileDirtyByTile(tile); - /* Remove desert directly around the river tile. */ - TileIndex t = tile; - CircularTileSearch(&t, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr); + MakeRiverAndModifyDesertZoneAround(tile); return false; } } @@ -1068,6 +1082,153 @@ static bool MakeLake(TileIndex tile, void *user_data) return false; } +/** + * Widen a river by expanding into adjacent tiles via circular tile search. + * @param tile The tile to try expanding the river into. + * @param data The tile to try surrounding the river around. + * @return Always false, so it continues searching. + */ +static bool RiverMakeWider(TileIndex tile, void *data) +{ + /* Don't expand into void tiles. */ + if (!IsValidTile(tile)) return false; + + /* If the tile is already sea or river, don't expand. */ + if (IsWaterTile(tile)) return false; + + /* If the tile is at height 0 after terraforming but the ocean hasn't flooded yet, don't build river. */ + if (GetTileMaxZ(tile) == 0) return false; + + TileIndex origin_tile = *(TileIndex *)data; + Slope cur_slope = GetTileSlope(tile); + Slope desired_slope = GetTileSlope(origin_tile); // Initialize matching the origin tile as a shortcut if no terraforming is needed. + + /* Never flow uphill. */ + if (GetTileMaxZ(tile) > GetTileMaxZ(origin_tile)) return false; + + /* If the new tile can't hold a river tile, try terraforming. */ + if (!IsTileFlat(tile) && !IsInclinedSlope(cur_slope)) { + /* Don't try to terraform steep slopes. */ + if (IsSteepSlope(cur_slope)) return false; + + bool flat_river_found = false; + bool sloped_river_found = false; + + /* There are two common possibilities: + * 1. River flat, adjacent tile has one corner lowered. + * 2. River descending, adjacent tile has either one or three corners raised. + */ + + /* First, determine the desired slope based on adjacent river tiles. This doesn't necessarily match the origin tile for the CircularTileSearch. */ + for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) { + TileIndex other_tile = TileAddByDiagDir(tile, d); + Slope other_slope = GetTileSlope(other_tile); + + /* Only consider river tiles. */ + if (IsWaterTile(other_tile) && IsRiver(other_tile)) { + /* If the adjacent river tile flows downhill, we need to check where we are relative to the slope. */ + if (IsInclinedSlope(other_slope) && GetTileMaxZ(tile) == GetTileMaxZ(other_tile)) { + /* Check for a parallel slope. If we don't find one, we're above or below the slope instead. */ + if (GetInclinedSlopeDirection(other_slope) == ChangeDiagDir(d, DIAGDIRDIFF_90RIGHT) || + GetInclinedSlopeDirection(other_slope) == ChangeDiagDir(d, DIAGDIRDIFF_90LEFT)) { + desired_slope = other_slope; + sloped_river_found = true; + break; + } + } + /* If we find an adjacent river tile, remember it. We'll terraform to match it later if we don't find a slope. */ + if (IsTileFlat(other_tile)) flat_river_found = true; + } + } + /* We didn't find either an inclined or flat river, so we're climbing the wrong slope. Bail out. */ + if (!sloped_river_found && !flat_river_found) return false; + + /* We didn't find an inclined river, but there is a flat river. */ + if (!sloped_river_found && flat_river_found) desired_slope = SLOPE_FLAT; + + /* Now that we know the desired slope, it's time to terraform! */ + + /* If the river is flat and the adjacent tile has one corner lowered, we want to raise it. */ + if (desired_slope == SLOPE_FLAT && IsSlopeWithThreeCornersRaised(cur_slope)) { + /* Make sure we're not affecting an existing river slope tile. */ + for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) { + TileIndex other_tile = TileAddByDiagDir(tile, d); + if (IsInclinedSlope(GetTileSlope(other_tile)) && IsWaterTile(other_tile)) return false; + } + Command::Do(DC_EXEC | DC_AUTO, tile, ComplementSlope(cur_slope), true); + + /* If the river is descending and the adjacent tile has either one or three corners raised, we want to make it match the slope. */ + } else if (IsInclinedSlope(desired_slope)) { + /* Don't break existing flat river tiles by terraforming under them. */ + DiagDirection river_direction = ReverseDiagDir(GetInclinedSlopeDirection(desired_slope)); + + for (DiagDirDiff d = DIAGDIRDIFF_BEGIN; d < DIAGDIRDIFF_END; d++) { + /* We don't care about downstream or upstream tiles, just the riverbanks. */ + if (d == DIAGDIRDIFF_SAME || d == DIAGDIRDIFF_REVERSE) continue; + + TileIndex other_tile = (TileAddByDiagDir(tile, ChangeDiagDir(river_direction, d))); + if (IsWaterTile(other_tile) && IsRiver(other_tile) && IsTileFlat(other_tile)) return false; + } + + /* Get the corners which are different between the current and desired slope. */ + Slope to_change = cur_slope ^ desired_slope; + + /* Lower unwanted corners first. If only one corner is raised, no corners need lowering. */ + if (!IsSlopeWithOneCornerRaised(cur_slope)) { + to_change = to_change & ComplementSlope(desired_slope); + Command::Do(DC_EXEC | DC_AUTO, tile, to_change, false); + } + + /* Now check the match and raise any corners needed. */ + cur_slope = GetTileSlope(tile); + if (cur_slope != desired_slope && IsSlopeWithOneCornerRaised(cur_slope)) { + to_change = cur_slope ^ desired_slope; + Command::Do(DC_EXEC | DC_AUTO, tile, to_change, true); + } + } + /* Update cur_slope after possibly terraforming. */ + cur_slope = GetTileSlope(tile); + } + + /* Sloped rivers need water both upstream and downstream. */ + if (IsInclinedSlope(cur_slope)) { + DiagDirection slope_direction = GetInclinedSlopeDirection(cur_slope); + + TileIndex upstream_tile = TileAddByDiagDir(tile, slope_direction); + TileIndex downstream_tile = TileAddByDiagDir(tile, ReverseDiagDir(slope_direction)); + + /* Don't look outside the map. */ + if (!IsValidTile(upstream_tile) || !IsValidTile(downstream_tile)) return false; + + /* Downstream might be new ocean created by our terraforming, and it hasn't flooded yet. */ + bool downstream_is_ocean = GetTileZ(downstream_tile) == 0 && (GetTileSlope(downstream_tile) == SLOPE_FLAT || IsSlopeWithOneCornerRaised(GetTileSlope(downstream_tile))); + + /* If downstream is dry, flat, and not ocean, try making it a river tile. */ + if (!IsWaterTile(downstream_tile) && !downstream_is_ocean) { + /* If the tile upstream isn't flat, don't bother. */ + if (GetTileSlope(downstream_tile) != SLOPE_FLAT) return false; + + MakeRiverAndModifyDesertZoneAround(downstream_tile); + } + + /* If upstream is dry and flat, try making it a river tile. */ + if (!IsWaterTile(upstream_tile)) { + /* If the tile upstream isn't flat, don't bother. */ + if (GetTileSlope(upstream_tile) != SLOPE_FLAT) return false; + + MakeRiverAndModifyDesertZoneAround(upstream_tile); + } + } + + /* If the tile slope matches the desired slope, add a river tile. */ + if (cur_slope == desired_slope) { + MakeRiverAndModifyDesertZoneAround(tile); + } + + /* Always return false to keep searching. */ + return false; +} + /** * Check whether a river at begin could (logically) flow down to end. * @param begin The origin of the flow. @@ -1090,6 +1251,12 @@ static bool FlowsDown(TileIndex begin, TileIndex end) ((slopeEnd == slopeBegin && heightEnd < heightBegin) || slopeEnd == SLOPE_FLAT || slopeBegin == SLOPE_FLAT); } +/** Parameters for river generation to pass as AyStar user data. */ +struct River_UserData { + TileIndex spring; ///< The current spring during river generation. + bool main_river; ///< Whether the current river is a big river that others flow into. +}; + /* AyStar callback for checking whether we reached our destination. */ static int32 River_EndNodeCheck(const AyStar *aystar, const OpenListNode *current) { @@ -1127,13 +1294,34 @@ static void River_GetNeighbours(AyStar *aystar, OpenListNode *current) /* AyStar callback when an route has been found. */ static void River_FoundEndNode(AyStar *aystar, OpenListNode *current) { - for (PathNode *path = ¤t->path; path != nullptr; path = path->parent) { + River_UserData *data = (River_UserData *)aystar->user_data; + + /* First, build the river without worrying about its width. */ + uint cur_pos = 0; + for (PathNode *path = ¤t->path; path != nullptr; path = path->parent, cur_pos++) { TileIndex tile = path->node.tile; if (!IsWaterTile(tile)) { - MakeRiver(tile, Random()); - MarkTileDirtyByTile(tile); - /* Remove desert directly around the river tile. */ - CircularTileSearch(&tile, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr); + MakeRiverAndModifyDesertZoneAround(tile); + } + } + + /* If the river is a main river, go back along the path to widen it. + * Don't make wide rivers if we're using the original landscape generator. + */ + if (_settings_game.game_creation.land_generator != LG_ORIGINAL && data->main_river) { + const uint long_river_length = _settings_game.game_creation.min_river_length * 4; + uint current_river_length; + uint radius; + + cur_pos = 0; + for (PathNode *path = ¤t->path; path != nullptr; path = path->parent, cur_pos++) { + TileIndex tile = path->node.tile; + + /* Check if we should widen river depending on how far we are away from the source. */ + current_river_length = DistanceManhattan(data->spring, tile); + radius = std::min(3u, (current_river_length / (long_river_length / 3u)) + 1u); + + if (radius > 1) CircularTileSearch(&tile, radius, RiverMakeWider, (void *)&path->node.tile); } } } @@ -1155,9 +1343,13 @@ static uint River_Hash(uint tile, uint dir) * Actually build the river between the begin and end tiles using AyStar. * @param begin The begin of the river. * @param end The end of the river. + * @param spring The springing point of the river. + * @param main_river Whether the current river is a big river that others flow into. */ -static void BuildRiver(TileIndex begin, TileIndex end) +static void BuildRiver(TileIndex begin, TileIndex end, TileIndex spring, bool main_river) { + River_UserData user_data = { spring, main_river }; + AyStar finder = {}; finder.CalculateG = River_CalculateG; finder.CalculateH = River_CalculateH; @@ -1165,6 +1357,7 @@ static void BuildRiver(TileIndex begin, TileIndex end) finder.EndNodeCheck = River_EndNodeCheck; finder.FoundEndNode = River_FoundEndNode; finder.user_target = &end; + finder.user_data = &user_data; finder.Init(River_Hash, 1 << RIVER_HASH_SIZE); @@ -1180,15 +1373,19 @@ static void BuildRiver(TileIndex begin, TileIndex end) * Try to flow the river down from a given begin. * @param spring The springing point of the river. * @param begin The begin point we are looking from; somewhere down hill from the spring. - * @return True iff a river could/has been built, otherwise false. + * @param min_river_length The minimum length for the river. + * @return First element: True iff a river could/has been built, otherwise false; second element: River ends at sea. */ -static bool FlowRiver(TileIndex spring, TileIndex begin) +static std::tuple FlowRiver(TileIndex spring, TileIndex begin, uint min_river_length) { # define SET_MARK(x) marks.insert(x) # define IS_MARKED(x) (marks.find(x) != marks.end()) uint height = TileHeight(begin); - if (IsWaterTile(begin)) return DistanceManhattan(spring, begin) > _settings_game.game_creation.min_river_length; + + if (IsWaterTile(begin)) { + return { DistanceManhattan(spring, begin) > min_river_length, GetTileZ(begin) == 0 }; + } std::set marks; SET_MARK(begin); @@ -1220,9 +1417,10 @@ static bool FlowRiver(TileIndex spring, TileIndex begin) } } while (!queue.empty()); + bool main_river = false; if (found) { /* Flow further down hill. */ - found = FlowRiver(spring, end); + std::tie(found, main_river) = FlowRiver(spring, end, min_river_length); } else if (count > 32) { /* Maybe we can make a lake. Find the Nth of the considered tiles. */ TileIndex lakeCenter = 0; @@ -1241,13 +1439,9 @@ static bool FlowRiver(TileIndex spring, TileIndex begin) /* We don't want lakes in the desert. */ (_settings_game.game_creation.landscape != LT_TROPIC || GetTropicZone(lakeCenter) != TROPICZONE_DESERT) && /* We only want a lake if the river is long enough. */ - DistanceManhattan(spring, lakeCenter) > _settings_game.game_creation.min_river_length) { + DistanceManhattan(spring, lakeCenter) > min_river_length) { end = lakeCenter; - MakeRiver(lakeCenter, Random()); - MarkTileDirtyByTile(lakeCenter); - /* Remove desert directly around the river tile. */ - CircularTileSearch(&lakeCenter, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr); - lakeCenter = end; + MakeRiverAndModifyDesertZoneAround(lakeCenter); uint range = RandomRange(8) + 3; CircularTileSearch(&lakeCenter, range, MakeLake, &height); /* Call the search a second time so artefacts from going circular in one direction get (mostly) hidden. */ @@ -1258,8 +1452,8 @@ static bool FlowRiver(TileIndex spring, TileIndex begin) } marks.clear(); - if (found) BuildRiver(begin, end); - return found; + if (found) BuildRiver(begin, end, spring, main_river); + return { found, main_river }; } /** @@ -1270,18 +1464,33 @@ static void CreateRivers() int amount = _settings_game.game_creation.amount_of_rivers; if (amount == 0) return; - uint wells = ScaleByMapSize(4 << _settings_game.game_creation.amount_of_rivers); + uint wells = Map::ScaleBySize(4 << _settings_game.game_creation.amount_of_rivers); + const uint num_short_rivers = wells - std::max(1u, wells / 10); SetGeneratingWorldProgress(GWP_RIVER, wells + 256 / 64); // Include the tile loop calls below. + /* Try to create long rivers. */ + for (; wells > num_short_rivers; wells--) { + IncreaseGeneratingWorldProgress(GWP_RIVER); + for (int tries = 0; tries < 512; tries++) { + TileIndex t = RandomTile(); + if (!CircularTileSearch(&t, 8, FindSpring, nullptr)) continue; + if (std::get<0>(FlowRiver(t, t, _settings_game.game_creation.min_river_length * 4))) break; + } + } + + /* Try to create short rivers. */ for (; wells != 0; wells--) { IncreaseGeneratingWorldProgress(GWP_RIVER); for (int tries = 0; tries < 128; tries++) { TileIndex t = RandomTile(); if (!CircularTileSearch(&t, 8, FindSpring, nullptr)) continue; - if (FlowRiver(t, t)) break; + if (std::get<0>(FlowRiver(t, t, _settings_game.game_creation.min_river_length))) break; } } + /* Widening rivers may have left some tiles requiring to be watered. */ + ConvertGroundTilesIntoWaterTiles(); + /* Run tile loop to update the ground density. */ for (uint i = 0; i != 256; i++) { if (i % 64 == 0) IncreaseGeneratingWorldProgress(GWP_RIVER); @@ -1321,7 +1530,7 @@ static uint CalculateCoverageLine(uint coverage, uint edge_multiplier) std::array edge_histogram = {}; /* Build a histogram of the map height. */ - for (TileIndex tile = 0; tile < MapSize(); tile++) { + for (TileIndex tile = 0; tile < Map::Size(); tile++) { uint h = TileHeight(tile); histogram[h]++; @@ -1337,7 +1546,7 @@ static uint CalculateCoverageLine(uint coverage, uint edge_multiplier) } /* The amount of land we have is the map size minus the first (sea) layer. */ - uint land_tiles = MapSizeX() * MapSizeY() - histogram[0]; + uint land_tiles = Map::Size() - histogram[0]; int best_score = land_tiles; /* Our goal is the coverage amount of the land-mass. */ @@ -1420,19 +1629,19 @@ void GenerateLandscape(byte mode) } else { SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_ORIGINAL); if (_settings_game.construction.freeform_edges) { - for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0)); - for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y)); + for (uint x = 0; x < Map::SizeX(); x++) MakeVoid(TileXY(x, 0)); + for (uint y = 0; y < Map::SizeY(); y++) MakeVoid(TileXY(0, y)); } switch (_settings_game.game_creation.landscape) { case LT_ARCTIC: { uint32 r = Random(); - for (uint i = ScaleByMapSize(GB(r, 0, 7) + 950); i != 0; --i) { + for (uint i = Map::ScaleBySize(GB(r, 0, 7) + 950); i != 0; --i) { GenerateTerrain(2, 0); } uint flag = GB(r, 7, 2) | 4; - for (uint i = ScaleByMapSize(GB(r, 9, 7) + 450); i != 0; --i) { + for (uint i = Map::ScaleBySize(GB(r, 9, 7) + 450); i != 0; --i) { GenerateTerrain(4, flag); } break; @@ -1441,18 +1650,18 @@ void GenerateLandscape(byte mode) case LT_TROPIC: { uint32 r = Random(); - for (uint i = ScaleByMapSize(GB(r, 0, 7) + 170); i != 0; --i) { + for (uint i = Map::ScaleBySize(GB(r, 0, 7) + 170); i != 0; --i) { GenerateTerrain(0, 0); } uint flag = GB(r, 7, 2) | 4; - for (uint i = ScaleByMapSize(GB(r, 9, 8) + 1700); i != 0; --i) { + for (uint i = Map::ScaleBySize(GB(r, 9, 8) + 1700); i != 0; --i) { GenerateTerrain(0, flag); } flag ^= 2; - for (uint i = ScaleByMapSize(GB(r, 17, 7) + 410); i != 0; --i) { + for (uint i = Map::ScaleBySize(GB(r, 17, 7) + 410); i != 0; --i) { GenerateTerrain(3, flag); } break; @@ -1462,7 +1671,7 @@ void GenerateLandscape(byte mode) uint32 r = Random(); assert(_settings_game.difficulty.quantity_sea_lakes != CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY); - uint i = ScaleByMapSize(GB(r, 0, 7) + (3 - _settings_game.difficulty.quantity_sea_lakes) * 256 + 100); + uint i = Map::ScaleBySize(GB(r, 0, 7) + (3 - _settings_game.difficulty.quantity_sea_lakes) * 256 + 100); for (; i != 0; --i) { /* Make sure we do not overflow. */ GenerateTerrain(Clamp(_settings_game.difficulty.terrain_type, 0, 3), 0); diff --git a/src/lang/afrikaans.txt b/src/lang/afrikaans.txt index 7603109ec3aa5..310c4648c84f6 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -200,6 +200,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}pk STR_UNITS_POWER_METRIC :{COMMA}{NBSP}pk STR_UNITS_POWER_SI :{COMMA}{NBSP}kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -382,10 +383,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Verlaat # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Spel opsies STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Stellings -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Spel skript instellings STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF stellings STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Deursigtigheid opsies STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Dorp name vertoon @@ -945,36 +945,6 @@ STR_GAME_OPTIONS_CURRENCY_NTD :Nuwe Taiwan dol STR_GAME_OPTIONS_CURRENCY_CNY :Chinese Renminbi (CNY) STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dollar (HKD) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Bestuur aan linkerkant -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Bestuur aan regterkant - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Dorp name -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Kies dorp naam styl - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Engels (Oorspronkilik) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Frans -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Duits -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Engels (Addisioneel) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latyns-Amerikaans -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Snaaks -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Sweeds -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Hollands -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finnish -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polish -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovak -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norwegian -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungarian -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austrian -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romanian -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Czech -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Swiss -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Deens -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turks -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiaans -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalan - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Outostoor STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Kies interval tussen outomatiese store @@ -999,18 +969,8 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :ander -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK} Koppelvlak groote -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK} Kies die koppelvlak element groote om te gebruik -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normaal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dubbel groote -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quad grootte -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Skrifgrootte - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normaal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dubbele grootte -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quad grootte @@ -1057,8 +1017,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Voorsko STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pond (£) in jou koers STR_CURRENCY_CHANGE_PARAMETER :{BLACK}verander gebruiklike koers parameter -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimum no. mededingers: {ORANGE}{COMMA} - STR_NONE :Geen STR_FUNDING_ONLY :Befondsing alleen STR_MINIMAL :Minimale @@ -1108,6 +1066,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Matige klimaat +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-artiese landskap +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropiese landskap +STR_CLIMATE_TOYLAND_LANDSCAPE :Speelgoedland landskap + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Baie Plat STR_TERRAIN_TYPE_FLAT :Plat @@ -1181,6 +1145,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Regs STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maksimum aanvanklike lening: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maksimum bedrag wat 'n maatskappy kan leen (sonder die inagneming van inflasie) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Rentekoers: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Lening rentekoers: beheer ook inflasie indien aangeskakel @@ -1447,6 +1412,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Verbeter STR_CONFIG_SETTING_ROAD_SIDE :Padvoertuie: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Kies die bestuurskant +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Bestuur aan linkerkant +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Bestuur aan regterkant + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Reliëfkaart orientasie: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Anti-kloksgewys @@ -1935,7 +1904,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Outomatiese rig STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Laat treine toe om agteruit te gaan by signale, as hulle daar lank gewag het ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Aanbevole) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Aanbevole) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Verander stel waarde @@ -1976,7 +1945,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Hoogste STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Stellings STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Stellings STR_INTRO_ONLINE_CONTENT :{BLACK}Soek aanlyn -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI/Spel Skript Instellings STR_INTRO_QUIT :{BLACK}Verlaat STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Begin nuwe spel. Ctrl+klik ignoreer kaart konfigurasie @@ -1996,7 +1964,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Vertoon STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Vertoon instellings STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Wys NewGRF stellings STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Kyk vir nuwe of bygewerkde inhoud om af te laai -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Vertoon AI/Spel skript konfigurasie STR_INTRO_TOOLTIP_QUIT :{BLACK}Verlaat 'OpenTTD' STR_INTRO_TRANSLATION :{BLACK}Die vertaling kort {NUM} string{P "" s}. Help aseblief om OpenTTD beter te maak, deur aan te sluit as 'n vertaaler. Sien die readme.txt vir meer inligting. @@ -2025,12 +1992,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Verande STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Verander huidige jaar STR_CHEAT_SETUP_PROD :{LTBLUE}Aktiveer modifisering van produksie waardes: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Matige klimaat -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-artiese landskap -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropiese landskap -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Speelgoedland landskap - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Kleur Skema @@ -2432,6 +2393,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}versadig STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}oorlaai +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Dekking area verlig STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Af @@ -2520,8 +2483,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Verhoog STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Kies Spoor Brug STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Selekteer Pad Brug STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Brugkeuring - klik op jou verkose brug om dit te bou -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Kabelstut, Staal STR_BRIDGE_NAME_GIRDER_STEEL :Balk, Staal STR_BRIDGE_NAME_CANTILEVER_STEEL :Vrydraer, Staal @@ -2919,16 +2880,40 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kaart gr STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Kies kaartgrootte teëls. Die aantal werklike beskikbare teëls sal ietwat minder wees. STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Hoev. dorpe: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Dorp name +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Kies dorp naam styl STR_MAPGEN_DATE :{BLACK}Datum: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Hoev. nywerhede: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Land genereerder: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terrein tipe: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Seevlak: +STR_MAPGEN_SEA_LEVEL :{BLACK}Seevlak: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Riviere: STR_MAPGEN_SMOOTHNESS :{BLACK}Gladheid: STR_MAPGEN_VARIETY :{BLACK}Verskeidenheid verspreiding: STR_MAPGEN_GENERATE :{WHITE}Genereer +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Engels (Oorspronkilik) +STR_MAPGEN_TOWN_NAME_FRENCH :Frans +STR_MAPGEN_TOWN_NAME_GERMAN :Duits +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Engels (Addisioneel) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latyns-Amerikaans +STR_MAPGEN_TOWN_NAME_SILLY :Snaaks +STR_MAPGEN_TOWN_NAME_SWEDISH :Sweeds +STR_MAPGEN_TOWN_NAME_DUTCH :Hollands +STR_MAPGEN_TOWN_NAME_FINNISH :Finnish +STR_MAPGEN_TOWN_NAME_POLISH :Polish +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovak +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norwegian +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungarian +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austrian +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romanian +STR_MAPGEN_TOWN_NAME_CZECH :Czech +STR_MAPGEN_TOWN_NAME_SWISS :Swiss +STR_MAPGEN_TOWN_NAME_DANISH :Deens +STR_MAPGEN_TOWN_NAME_TURKISH :Turks +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiaans +STR_MAPGEN_TOWN_NAME_CATALAN :Catalan + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kaart kante: STR_MAPGEN_NORTHWEST :{BLACK}Noordwes @@ -3067,6 +3052,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Vorige s STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Gaan na vorige normale sprite, en ignoreer enige pseudo/her-kleur/font sprite en spring terug na die einde STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Voorstelling van geselekteerde sprite. Die belyning word geignoreer waneer sprite geteken word STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Beweeg die sprite rond, verander die X en Y afwyking. Ctrl-klik om die sprite agt lengtes rond te beweeg op 'n slag + +###length 2 + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Relatiewe herstel STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Herstel die huidige relatiewe verplasing STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X verplasing: {NUM}, Y verplasing: {NUM} (Werklik) @@ -3081,7 +3070,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Waarskuwing: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Fout: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fataal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}'n Fataale NewGRF fout het gebeur:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} sal nie met die TTDPatch uitgawe rapporteer deur OpenTTD werk nie. STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} is vir die {STRING} uitgawe van TTD. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} is onderwerp om saam met {STRING} gebruik te word @@ -3608,6 +3596,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Maks. Tr STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Afstand: {GOLD}{COMMA} teëls STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Vliegtuig tipe: {GOLD}{STRING} +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Trein kieslys - klik op voertuig vir inligting. CTRL+kliek vir wegsteek van die voertuig tipe STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Pad voertuig kieslys - klik op voertuig vir inligting. CTRL+kliek vir wegsteek van die voertuig tipe @@ -4251,12 +4241,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Een van STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Rekenaar Speler/Spel Skrip Ontfout venster is slegs beskikbaar aan die verskaffer # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI/Spel Konfigurasie STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Spel Skrip wat in die volgende spel gelaai sal word STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Die AIs wat om die volgende spel gelaai sal word STR_AI_CONFIG_HUMAN_PLAYER :Mens Speler STR_AI_CONFIG_RANDOM_AI :Lukraak AI STR_AI_CONFIG_NONE :(geen) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maksimum no. mededingers: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Beweeg op STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Beweeg gekose AI op in die lys @@ -4266,8 +4256,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Beweeg g STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spel Skrip STR_AI_CONFIG_AI :{SILVER}AIs -STR_AI_CONFIG_CHANGE :{BLACK}Selekteer {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :AI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Spel Skrip STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Laai nog 'n script @@ -4297,10 +4285,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Volledig STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Hoogtekaart-skermkiekie STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minimap-skermkiekie -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Speletjie Skrif STR_AI_SETTINGS_CLOSE :{BLACK}Maak toe STR_AI_SETTINGS_RESET :{BLACK}Herstel STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4712,6 +4698,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Kan nie STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... voertuig is vernietig + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Geen voertuie gaan beskikbaar wees nie STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Verander jou NewGRF stellings STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Geen voertuie is op die oomblik beskikbaar nie @@ -4745,6 +4732,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Kan nie STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... te ver van vorige bestemming STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... vliegtuig kan nie so ver vlieg nie +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kan nie voertuig 'n rooster gee nie... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Voertuie kan slegs by stasies wag diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index 2327acbd9c259..99894c2103425 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -199,6 +199,8 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}ح STR_UNITS_POWER_METRIC :{COMMA}{NBSP}حصان STR_UNITS_POWER_SI :{COMMA}{NBSP}ك واط +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP} طن STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}طن STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}كجم @@ -220,6 +222,7 @@ STR_UNITS_FORCE_METRIC :{COMMA}{NBSP}ك STR_UNITS_FORCE_SI :{COMMA}{NBSP} كيلو نيوتن STR_UNITS_HEIGHT_IMPERIAL :{COMMA}{NBSP} قدم +STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}م STR_UNITS_HEIGHT_SI :{COMMA}{NBSP} متر # Common window strings @@ -380,10 +383,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :انهاء # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :إعدادات اللعبه STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :الإعدادات -STR_SETTINGS_MENU_SCRIPT_SETTINGS :الذكاء الصناعي/ اعدادات اللعبة STR_SETTINGS_MENU_NEWGRF_SETTINGS :إعدادات اﻹضافات STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :خيارات الشفافية STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :عرض اسماء المدن @@ -929,40 +931,11 @@ 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_NTD :الدولار التايواني الجديد (NTD) STR_GAME_OPTIONS_CURRENCY_CNY :(CNY) الرنمينبي الصيني STR_GAME_OPTIONS_CURRENCY_HKD :(HKD) دولار هونج كونج STR_GAME_OPTIONS_CURRENCY_INR :الروبية الهندية (INR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}اختيار طريقة عرض اسماء المدن - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :English (Original) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :فرنسي -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :الماني -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :انجليزي اضافي -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :امريكي لاتيني -STR_GAME_OPTIONS_TOWN_NAME_SILLY :مضحك -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :سويدي -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :هولندي -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :فنلندي -STR_GAME_OPTIONS_TOWN_NAME_POLISH :بلغاري -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :سلوفاكي -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :نرويجي -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :هنغاري -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :نمساوي -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :روماني -STR_GAME_OPTIONS_TOWN_NAME_CZECH :تشيكي -STR_GAME_OPTIONS_TOWN_NAME_SWISS :سويدي -STR_GAME_OPTIONS_TOWN_NAME_DANISH :دنماكي -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :تركي -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :ايطالي -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :كتالونية - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}حفظ آلي STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}اختار مدة الحفظ الآلي @@ -986,25 +959,17 @@ STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}اختر STR_GAME_OPTIONS_RESOLUTION_OTHER :اخرى STR_GAME_OPTIONS_VIDEO_ACCELERATION :{BLACK}تسريع الأجهزة -STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP :{BLACK}حدد هذا المربع للسماح لـ OpenTTD بمحاولة استخدام تسريع الأجهزة. سيتم تطبيق الإعداد الذي تم تغييره فقط عند إعادة تشغيل اللعبة +STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP :{BLACK}اخترهذا المربع للسماح لـ OpenTTD بمحاولة استخدام تسريع الأجهزة. سيتم تطبيق الإعداد الذي تم تغييره فقط عند إعادة تشغيل اللعبة STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}لن يعمل الإعداد إلا بعد إعادة تشغيل اللعبة +STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync +STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}حدد هذا المربع لمزامنة الشاشة (v-sync). سيتم تطبيق الإعداد الذي تم تغييره فقط عند إعادة تشغيل اللعبة. يعمل فقط مع تمكين تسريع الأجهزة (hardware acceleration) -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}حجم اللوحة -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}حدد العنصر المطلوب +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}الكشف التلقائي عن الحجم +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}اختر هذا المربع لكشف حجم الواجهة تلقائيا -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 -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}حجم الخط -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}حدد حجم خط الواجهة المراد استخدامه - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(كشف أوتوماتيكي) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :عادي -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :حجم مزدوج -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :حجم رباعي STR_GAME_OPTIONS_GRAPHICS :{BLACK}الرسومات @@ -1056,8 +1021,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}عرض: STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK} 10000 جنية استرليني في عملتك STR_CURRENCY_CHANGE_PARAMETER :{BLACK}غير الخيارات الاختيارة -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}العدد الاقصى للمتنافسين: {ORANGE}{COMMA} - STR_NONE :بدون STR_FUNDING_ONLY :التمويل فقط STR_MINIMAL :الادنى @@ -1107,6 +1070,12 @@ STR_SUBSIDY_X2 :*2 STR_SUBSIDY_X3 :*3 STR_SUBSIDY_X4 :*4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :مناطق معتدلة +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :مناطق ثلجية +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :مناطق مدارية +STR_CLIMATE_TOYLAND_LANDSCAPE :ألعاب + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :مسطح تماما STR_TERRAIN_TYPE_FLAT :مسطح @@ -1130,6 +1099,7 @@ 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_RESET_ALL_CONFIRMATION_DIALOG_CAPTION :{WHITE}تحذير! STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK} فئة: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}نوع: @@ -1167,9 +1137,11 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_LEFT :يسار STR_CONFIG_SETTING_HORIZONTAL_POS_CENTER :متوسط STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :يمين +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :سعر الفائدة على القرض يتحكم أيضًا في التضخم ، إذا تم تمكينه +STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :تحديد مستوى تكاليف الصيانة والتشغيل للمركبات والبنية التحتية STR_CONFIG_SETTING_CONSTRUCTION_SPEED ::سرعة البناء {STRING} @@ -1184,6 +1156,7 @@ STR_CONFIG_SETTING_SUBSIDY_DURATION_VALUE :{NUM} سنة STR_CONFIG_SETTING_RECESSIONS :حالات الركود: {STRING} +STR_CONFIG_SETTING_TRAIN_REVERSING :عدم السماح بعودة القطار إلى الخلف في المحطات: {STRING} STR_CONFIG_SETTING_DISASTERS :الكوارث: {STRING} @@ -1218,9 +1191,11 @@ STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :السماح ب STR_CONFIG_SETTING_INFLATION :التضخم: {STRING} STR_CONFIG_SETTING_INFLATION_HELPTEXT :تمكين التضخم في الاقتصاد ، حيث ترتفع التكاليف بشكل أسرع قليلاً من المدفوعات +STR_CONFIG_SETTING_MAX_BRIDGE_LENGTH :أقصى طول للجسر: {STRING} STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT_HELPTEXT :الارتفاع الأقصى لبناء الجسور +STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT :الطول الأقصى لبناء الأنفاق STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD :طريقة بناء المصانع الأولية يدوية : {STRING} ###length 3 @@ -1307,6 +1282,7 @@ STR_CONFIG_SETTING_ERRMSG_DURATION_VALUE :{COMMA} ثان ###setting-zero-is-special STR_CONFIG_SETTING_POPULATION_IN_LABEL :أعرض عدد السكان مع الاسم على العلامة: {STRING} +STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :اعرض عدد سكان البلدات في علماتها على الخريطة STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :سمك الخطوط في العرض: {STRING} @@ -1358,6 +1334,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :المحسن STR_CONFIG_SETTING_ROAD_SIDE :السيارات: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :إختر جهة القيادة +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :القيادة على اليسار +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :القيادة على اليمين + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :اتجاة خريطة المرتفعات: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :عكس عقارب الساعة @@ -1381,6 +1361,7 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :اخضر غام STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :بنفسجي ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :رمادي إلى أحمر ###length 4 @@ -1407,6 +1388,7 @@ STR_CONFIG_SETTING_SCROLLWHEEL_OFF :عدم استخ STR_CONFIG_SETTING_OSK_ACTIVATION :كيبورد على الشاشة: {STRING} ###length 4 STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :غير مفعل +STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK_FOCUS :نقرة واحدة (عند التركيز) ###length 3 STR_CONFIG_SETTING_USE_RELAY_SERVICE_ALLOW :سماح @@ -1425,7 +1407,7 @@ STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :اختر الو STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :استخدم {STRING} نمط التاريخ لاسم اللعبة المحفوظة ###length 3 STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_LONG :طويل - 31 ديسمبر 2008 -STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_SHORT :قصير - 31 - 12 - 2008 +STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_SHORT :قصير (31-12-2008) STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_ISO :ايزو 31-12-2008 STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME :إيقاف اللعبة تلقائيا عند بدأ لعبة جديدة: {STRING} @@ -1497,6 +1479,7 @@ STR_CONFIG_SETTING_MAX_AIRCRAFT_HELPTEXT :الحد الأ STR_CONFIG_SETTING_MAX_SHIPS :الحد الأعلى لعدد السفن لكل شركة: {STRING} STR_CONFIG_SETTING_AI_BUILDS_TRAINS :حظر القطارات على الحاسوب: {STRING} +STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :يؤدي تمكين هذا الإعداد إلى جعل بناء القطارات مستحيلًا لللاعب الآلي STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :حظر العربات على الكمبيوتر: {STRING} @@ -1511,6 +1494,7 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :السماح ب STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :السماح بلاعبين كمبيوترالذكاء الصناعي بالمشاركة في الالعاب الجماعية. STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes قبل تعليق الاسكربت: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :فترات الصيانة بالنسبة المئوية : {STRING} @@ -1524,6 +1508,7 @@ STR_CONFIG_SETTING_WAGONSPEEDLIMITS :السماح ب STR_CONFIG_SETTING_DISABLE_ELRAILS :تعطيل سكة القطار الكهربائي: {STRING} STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN :وصول اول مركبة لمحطة اللاعب: {STRING} +STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN_HELPTEXT :عرض جريدة عندما تصل السيارة الأولى إلى محطة اللاعب الجديد STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER :وصول اول مركبة لمحطة الخصوم: {STRING} @@ -1577,6 +1562,7 @@ STR_CONFIG_SETTING_ENDING_YEAR_ZERO :لا تنتهي STR_CONFIG_SETTING_ECONOMY_TYPE_FROZEN :مجمد STR_CONFIG_SETTING_ALLOW_SHARES :السماح بشراء حصص من الشركات الاخرى: {STRING} +STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :عند التمكين ، السماح بشراء وبيع أسهم الشركة. ستكون الأسهم متاحة فقط للشركات التي بلغت سنًا معينة @@ -1585,11 +1571,13 @@ STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :عند السح STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :اتاحة استخدام الأشارات بالأعلام قبل :{STRING} STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :الدوران خلال الاشارات: {STRING} +STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :حدد أنواع الإشارات التي تريد التنقل خلالها عند النقر (Ctrl+Click) فوق إشارة مبنية باستخدام أداة الإشارة ###length 2 STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :اشارات الطريق فقط STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :الكل واضح ###length 2 +STR_CONFIG_SETTING_SIGNAL_GUI_MODE_PATH :اشارات الطريق فقط STR_CONFIG_SETTING_TOWN_LAYOUT :تصميم الطرق للمدن الجديدة : {STRING} ###length 5 @@ -1611,6 +1599,7 @@ 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 :توليد البضائع في المدينة: {STRING} ###length 2 STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :تربيعي (أصلي) STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :خطي @@ -1621,9 +1610,11 @@ STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_RAINFOREST :تنموا ول STR_CONFIG_SETTING_TOOLBAR_POS :موقع شريط الأدوات الرئيسي: {STRING} STR_CONFIG_SETTING_STATUSBAR_POS :موقع شريط المعلومات: {STRING} +STR_CONFIG_SETTING_SNAP_RADIUS :دائرة تثبيت النافذة: {STRING} ###setting-zero-is-special STR_CONFIG_SETTING_SNAP_RADIUS_DISABLED :غير مفعل STR_CONFIG_SETTING_SOFT_LIMIT :حدود نعومة النوافذ - غير ملتصقة - :{STRING} +STR_CONFIG_SETTING_SOFT_LIMIT_HELPTEXT :عدد النوافذ المفتوحة غير اللاصقة قبل أن يتم إغلاق النوافذ القديمة تلقائيًا لإفساح المجال للنوافذ الجديدة ###setting-zero-is-special STR_CONFIG_SETTING_SOFT_LIMIT_DISABLED :غير مفعل @@ -1649,6 +1640,7 @@ STR_CONFIG_SETTING_TOWN_GROWTH_FAST :سريع STR_CONFIG_SETTING_TOWN_GROWTH_VERY_FAST :سريع جدا STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :عدد المدن التي ستصبح مدينة كبيرة، وبالتالي اي مدينة تبدء اكبر وتنمو بطريقة سريعة. +STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 في {COMMA} ###setting-zero-is-special STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :مضاعف المدن المبدئي: {STRING} @@ -1660,26 +1652,29 @@ STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :كلما قمت STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :ضبط هذا إلى أقل من 100٪ يؤدي إلى جعل التوزيع المتماثل يتصرف مثل التوزيع غير المتماثل. سيتم إعادة شحنات أقل غصبا إذا تم إرسال مبلغ معين إلى المحطة. إذا قمت بتعيينه على 0٪ ، فإن التوزيع المتماثل يتصرف تمامًا مثل التوزيع غير المتماثل +STR_CONFIG_SETTING_SHORT_PATH_SATURATION :تشبع المسارات القصيرة قبل استخدام المسارات عالية القدرة: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :وحدات السرعة: {STRING} ###length 4 -STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_METRIC :(متري (كم / ساعة +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_IMPERIAL :إمبراطوري (ميل/ساعة) +STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_METRIC :متري (كم / ساعة) STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_SI :متري (م / ثانية) STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER :وحدات الطاقة في السيارة: {STRING} ###length 3 ###length 3 -STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_METRIC :(متري (طن +STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT_METRIC :متري (طن) ###length 3 STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE ::وحدات جهد الجر {STRING} ###length 3 +STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_METRIC :متري (كغ - قوة) ###length 3 STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :إمبراطوري (قدم) -STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :م) متري) +STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :متري (م) STR_CONFIG_SETTING_GRAPHICS :رسوميات {ORANGE} STR_CONFIG_SETTING_SOUND :{ORANGE}الصوت @@ -1703,15 +1698,17 @@ STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE} مصا STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :توزيع البضائع{ORANGE} STR_CONFIG_SETTING_AI :{ORANGE}المتنافسين STR_CONFIG_SETTING_AI_NPC :{ORANGE} لاعبين الحاسوب +STR_CONFIG_SETTING_NETWORK :{ORANGE}شبكة الاتصال STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS :موجد الطريق- قصاص الطريق - للقطارات:{STRING} STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES :موجد الطريق (قصاص الأثر) للعربات: {STRING} STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES_HELPTEXT :مكتشف المسار لاستخدامه لعربات الطرق STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS :موجد طريق العبور للسفن: {STRING} +STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS_HELPTEXT :مكتشف المسار لاستخدامه للسفن STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :العكس عند الإشارات: {STRING} ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(مفضل) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(مفضل) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}عدل قيمة التغيير @@ -1748,7 +1745,6 @@ STR_INTRO_HIGHSCORE :{BLACK}قائم STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}الاعدادات STR_INTRO_NEWGRF_SETTINGS :{BLACK} اعدادات NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK} إبحث عن المحتوى عبر الشبكه العنكبوتيه -STR_INTRO_SCRIPT_SETTINGS :{BLACK}إعدادات الذكاء الصناعى STR_INTRO_QUIT :{BLACK}خروج STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}بدأ لعبة جديدة @@ -1791,16 +1787,11 @@ STR_CHEAT_CHANGE_COMPANY :{LTBLUE}الع STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}الجرافة السحرية - لازالة المصانع و الاجسام غير القابلة للازالة.{ORANGE}{STRING} STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}يمكن للانفاق ان تتقاطع: {ORANGE}{STRING} STR_CHEAT_NO_JETCRASH :{LTBLUE}الطائرات النفاثه لا تتحطم (كثيراً) فى المطارات الصغيره: {ORANGE}{STRING} +STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}تعدبل أقصى ارتفاع لتضاريس الخريطة STR_CHEAT_CHANGE_DATE :{LTBLUE}عدل التاريخ {ORANGE} {DATE_SHORT} STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}غير السنة الحالية STR_CHEAT_SETUP_PROD :{LTBLUE}تفعيل تغيير قيمة الانتاج: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :مناطق معتدلة -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :مناطق ثلجية -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :مناطق مدارية -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :ألعاب - # Livery window STR_LIVERY_GENERAL_TOOLTIP :{BLACK}اظهر اللون العام @@ -1992,6 +1983,9 @@ STR_NETWORK_COMPANY_LIST_SPECTATE :شاهد # Network client list STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}اللاعبون عبر الإنترنت +STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}الاسم +STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}الاسم +STR_NETWORK_CLIENT_LIST_SPECTATORS :المشاهدين STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(شركة جديدة) # Matches ConnectionType @@ -2002,6 +1996,7 @@ STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :منع 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_ASK_RELAY_NO :{BLACK}لا @@ -2053,6 +2048,7 @@ STR_NETWORK_ERROR_KICKED :{WHITE}لقد STR_NETWORK_ERROR_KICK_MESSAGE :{WHITE}السبب: {STRING} STR_NETWORK_ERROR_CHEATER :{WHITE}الغش ليس مسموحا به في هذه اللعبة STR_NETWORK_ERROR_TOO_MANY_COMMANDS :{WHITE}أنت تقوم بإرسال العديد من الأوامر للخادم +STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}اسم اللاعب الخاص بك غير صالح STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}احتمال فقد الاتصال STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION :{WHITE}اخر {NUM} ثواني لم تصل بيانات من السيرفر @@ -2202,6 +2198,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}عادي الاستخدام STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}زائد الاستخدام +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}وضح منطقة التغطية STR_STATION_BUILD_COVERAGE_OFF :{BLACK}غلق @@ -2290,8 +2288,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}زياد STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}اختر جسر السكة STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}اختر الجسر المناسب STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}بناء الجسور - اختر الجسر المفضل لديك لبنائة -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :تعليق, حديدي STR_BRIDGE_NAME_GIRDER_STEEL :العارضة, حديدية STR_BRIDGE_NAME_CANTILEVER_STEEL :الحامل, حديدي @@ -2468,6 +2464,7 @@ STR_FUND_INDUSTRY_CAPTION :{WHITE}مول STR_FUND_INDUSTRY_SELECTION_TOOLTIP :{BLACK}اختر المصنع المناسب من القائمة 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_INDUSTRY_BUILD_COST :{BLACK}التكلفة: {YELLOW}{CURRENCY_LONG} STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY :{BLACK} الاحتمالية STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY :{BLACK}بناء @@ -2633,6 +2630,9 @@ STR_FRAMERATE_GAMESCRIPT :{BLACK} مخط STR_FRAMERATE_AI :{BLACK} AI {NUM} {STRING} ###length 15 +STR_FRAMETIME_CAPTION_GAMELOOP :تكرارات اللعبة +STR_FRAMETIME_CAPTION_GL_TRAINS : تكتكة القطار +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :تأخر ارتباط الرسم البياني STR_FRAMETIME_CAPTION_SOUND :اختلاط الصوت STR_FRAMETIME_CAPTION_GAMESCRIPT :كتابة اللعبة @@ -2670,21 +2670,47 @@ STR_MAPGEN_MAPSIZE :{BLACK}حجم STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK} حدد حجم الخريطة بالمربعات. سيكون عدد المربعات المتاحة أصغر قليلاً STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}عدد المدن: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}اسماء المدن: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}اختيار طريقة عرض اسماء المدن STR_MAPGEN_DATE :{BLACK}التاريخ: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}عدد المصانع: STR_MAPGEN_HEIGHTMAP_HEIGHT_UP :{BLACK}قم بزيادة أقصى ارتفاع لأعلى قمة على الخريطة بواحد STR_MAPGEN_SNOW_COVERAGE :{BLACK}تغطية الثلج: STR_MAPGEN_SNOW_COVERAGE_DOWN :{BLACK}تقليل تغطية الثلوج بنسبة عشرة بالمائة +STR_MAPGEN_SNOW_COVERAGE_TEXT :{BLACK}{NUM}% STR_MAPGEN_DESERT_COVERAGE :{BLACK}مدى تغطيت السحراء: +STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}تقليل التغطية الصحراوية بنسبة عشرة بالمائة STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}مولد الخريطة: STR_MAPGEN_TERRAIN_TYPE :{BLACK} نوع التضاريس -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}مستوى البحر +STR_MAPGEN_SEA_LEVEL :{BLACK}مستوى البحر STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}انهار: STR_MAPGEN_SMOOTHNESS :{BLACK} النعومة: STR_MAPGEN_VARIETY :{BLACK}توزيع التنوع: STR_MAPGEN_GENERATE :{WHITE}ولد +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :English (Original) +STR_MAPGEN_TOWN_NAME_FRENCH :فرنسي +STR_MAPGEN_TOWN_NAME_GERMAN :الماني +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :انجليزي اضافي +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :امريكي لاتيني +STR_MAPGEN_TOWN_NAME_SILLY :مضحك +STR_MAPGEN_TOWN_NAME_SWEDISH :سويدي +STR_MAPGEN_TOWN_NAME_DUTCH :هولندي +STR_MAPGEN_TOWN_NAME_FINNISH :فنلندي +STR_MAPGEN_TOWN_NAME_POLISH :بلغاري +STR_MAPGEN_TOWN_NAME_SLOVAK :سلوفاكي +STR_MAPGEN_TOWN_NAME_NORWEGIAN :نرويجي +STR_MAPGEN_TOWN_NAME_HUNGARIAN :هنغاري +STR_MAPGEN_TOWN_NAME_AUSTRIAN :نمساوي +STR_MAPGEN_TOWN_NAME_ROMANIAN :روماني +STR_MAPGEN_TOWN_NAME_CZECH :تشيكي +STR_MAPGEN_TOWN_NAME_SWISS :سويدي +STR_MAPGEN_TOWN_NAME_DANISH :دنماكي +STR_MAPGEN_TOWN_NAME_TURKISH :تركي +STR_MAPGEN_TOWN_NAME_ITALIAN :ايطالي +STR_MAPGEN_TOWN_NAME_CATALAN :كتالونية + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK} حدود الخريطة: STR_MAPGEN_NORTHWEST :{BLACK} الشمال الغربي @@ -2818,7 +2844,13 @@ STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK}اذهب STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}العفريتة السابقة. STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}نابع للعفريتة الطبيعية التالية، تجاوز اي عفريتة موقوفة/ مصبوغة/مخطوطة و انهي في البداية. STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}عرض العفريتة المختارة حاليا. يتم تجاهل الموائمة عند رسم هذا العفريت. -STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}حرك العفريتة في الجوار، غير الاحداثيات س ، ص. +STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}حرك الرسمة، وقم بتغيير إزاحة X وY. قم ب Ctrl+Click لتحريك الكائن ثماني وحدات في المرة الواحدة + +###length 2 + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}الخطوت المتقاطعة + +STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}الازاحة (X): {NUM}، الازاحة (Y): {NUM} (نسبي) STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}اختر عفريتة STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}اختر عفريتة من اي مكان في الشاشة. @@ -2829,7 +2861,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED} تحذير: {SILVER}{STRING} 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_VERSION_NUMBER :{1:STRING} لن يعمل مع اصدار الباتش المسجل في النسخة المفتوحة STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} يعمل مع {STRING} اصدار من TTD. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} مصمم ليستخدم مع {STRING} @@ -2983,9 +3014,11 @@ STR_GOAL_QUESTION_CAPTION_ERROR :{YELLOW}خطا # Goal Question button list ###length 18 +STR_GOAL_QUESTION_BUTTON_OK :موافقة STR_GOAL_QUESTION_BUTTON_NO :لا STR_GOAL_QUESTION_BUTTON_YES :نعم STR_GOAL_QUESTION_BUTTON_RETRY :إعادة المحاولة +STR_GOAL_QUESTION_BUTTON_CONTINUE :الاستمرار STR_GOAL_QUESTION_BUTTON_RESTART :إعادة تشغيل STR_GOAL_QUESTION_BUTTON_POSTPONE :تأجيل STR_GOAL_QUESTION_BUTTON_SURRENDER :استسلام @@ -3036,8 +3069,10 @@ STR_STATION_VIEW_GROUP :{BLACK}جمع STR_STATION_VIEW_WAITING_AMOUNT :الكمية: في الانتظار STR_STATION_VIEW_PLANNED_AMOUNT :المبلغ: تم تخطيطه STR_STATION_VIEW_FROM :{YELLOW}{CARGO_SHORT} من {STATION} +STR_STATION_VIEW_VIA :{YELLOW}{CARGO_SHORT} من خلال {STATION} STR_STATION_VIEW_TO :{YELLOW}{CARGO_SHORT} إلى {STATION} STR_STATION_VIEW_TO_ANY :{RED}{CARGO_SHORT} إلى أي محطة +STR_STATION_VIEW_NONSTOP :{YELLOW}{CARGO_SHORT} بدون توقف STR_STATION_VIEW_GROUP_V_S_D :عبر-المصدر-الوجهة @@ -3184,6 +3219,7 @@ STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}وسط الشاشة على المصنع STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}نسبة الانتاج: {YELLOW}{COMMA}% +STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}ينتج: {YELLOW}{STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}:يتطلب STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} تنتظر{STRING} @@ -3290,15 +3326,20 @@ STR_PURCHASE_INFO_COST :{BLACK}التك STR_PURCHASE_INFO_COST_REFIT :{BLACK}التكلفة: {GOLD}{CURRENCY_LONG}{BLACK} (تكلفة التغيير: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}الوزن: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}التكلفة: {GOLD}{CURRENCY_LONG}{BLACK} السرعة : {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}التكلفة: {GOLD}{CURRENCY_LONG}{BLACK} (تكلفة التغير: {GOLD}{CURRENCY_LONG}{BLACK}) السرعة: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK} السعة {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK} العربات ذات الطاقة: {GOLD}+{POWER}{BLACK} الوزن: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}يمكن تعديلها الى: {GOLD}{STRING} STR_PURCHASE_INFO_ALL_TYPES :جميع انواع الحمولة STR_PURCHASE_INFO_NONE :بدون +STR_PURCHASE_INFO_ENGINES_ONLY :محركات فقط STR_PURCHASE_INFO_ALL_BUT :الكل الا {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}تأثير الجذب القصى: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}نوع الطائرة:{GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_NONE :لا شيء + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}قائمة اختيار القطارات - اضغط على العربة لعرض معلوماتها STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}قائمة اختيار العربات - اضغط على العربة لاظهار معلوماتها @@ -3313,6 +3354,7 @@ STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}شراء ###length VEHICLE_TYPES STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}شراء العربة وتجديد بضائعها +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}شراء وإعادة تجهيز السفينة ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}شراء العربة الموضحة @@ -3498,6 +3540,7 @@ STR_REPLACE_TRAM_VEHICLES :مركبات ا STR_REPLACE_REMOVE_WAGON :{BLACK} إزالة العربة ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK} المحافظة على طول القطار بازالة عربات ابتداء من المقدمة عند التبديل - عندما يكون التبدل ينتج قطارا اطول. +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl + Click للتطبيق أيضًا على المجموعات الفرعية # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -3776,6 +3819,7 @@ STR_ORDER_REFIT_STOP_ORDER :هيئت الى STR_ORDER_STOP_ORDER :توقف STR_ORDER_GO_TO_STATION :{STRING} {STATION} {STRING} +STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(لا يمكن استخدام المحطة){POP_COLOUR} {STRING} {STATION} {STRING} STR_ORDER_IMPLICIT :(تلقائى) @@ -3830,13 +3874,14 @@ STR_TIMETABLE_ORDER_VIEW_TOOLTIP :{BLACK}حول STR_TIMETABLE_TOOLTIP :{BLACK}جدولة الأوامر - اضغط على الامر لاظهارة STR_TIMETABLE_NO_TRAVEL :لا رحيل -STR_TIMETABLE_NOT_TIMETABLEABLE :المغادرة (ذاتي: بواسطة الامر اليدوي التالي) +STR_TIMETABLE_NOT_TIMETABLEABLE :المغادرة (ذاتي: مجدول بواسطة الامر اليدوي التالي) STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :مسافر (غير مجدوله) STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED :سافر(بدون جدول زمني) مع تقريبا {2:VELOCITY} STR_TIMETABLE_TRAVEL_FOR :مسافر لـ {STRING} STR_TIMETABLE_TRAVEL_FOR_SPEED :سافر لي {STRING} بمعدل {VELOCITY} STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :سافر(إلى {STRING}, بدون جدول زمني) STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :سافر (إلى {STRING}, بدون الجدول الزمني) مع تقريبا {VELOCITY} +STR_TIMETABLE_STAY_FOR_ESTIMATED :(البقاء ل{STRING}، ليس مجدول) STR_TIMETABLE_STAY_FOR :ويبقى لـ {STRING} STR_TIMETABLE_AND_TRAVEL_FOR :ويسافر لـ {STRING} STR_TIMETABLE_DAYS :{COMMA}يوم @@ -3912,11 +3957,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}واحد STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW} شاشة اخطاء الذكاء الصناعي متوفرة فقط للخادم (سرڤر) # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}إعدادات الذكاء الصناعي -STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}مخطوطات اللعبة الذي سيتم تحميله في اللعبة التالية +STR_AI_CONFIG_CAPTION_AI :{WHITE}اعدادات االذكاء الاصطناعي +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}تكوين مخطوط اللعبة +STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}النص البرمجي الخاص باللعبة الذي سيتم تحميله في اللعبة التالية +STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}الذكاء الاصطناعي الذي سيتم تحميله في اللعبة التالية STR_AI_CONFIG_HUMAN_PLAYER :لاعب انساني STR_AI_CONFIG_RANDOM_AI :ذكاء صناعي عشوائي STR_AI_CONFIG_NONE :(لا شيء) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}العدد الاقصى للمتنافسين: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}انقل للاعلى STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}انقل الذكاء الاصطناعي المختار للاعلى @@ -3925,10 +3973,9 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}انقل STR_AI_CONFIG_AI :{SILVER} الذكاء الاصطناعي -STR_AI_CONFIG_CHANGE :{BLACK}اختر {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :الذكاء الاصطناعي STR_AI_CONFIG_CHANGE_GAMESCRIPT :مخطوط اللعبة +STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}تحميل نص برمجي آخر STR_AI_CONFIG_CONFIGURE :{BLACK} اعداد STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK} اعداد خواص الذكاء الصناعي @@ -3944,10 +3991,11 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK} اخت STR_AI_LIST_CANCEL :{BLACK} الغاء STR_AI_LIST_CANCEL_TOOLTIP :{BLACK} لا تغير الذكاء الصناعي +STR_SCREENSHOT_SCREENSHOT :{BLACK}لقطة شاشة عادية STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}التقط لقطة شاشة كاملة STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}صور الخاريطة الكاملة -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CLOSE :{BLACK} اغلاق STR_AI_SETTINGS_RESET :{BLACK} اعادة ضبط STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4199,6 +4247,8 @@ STR_ERROR_DEPOT_WRONG_DEPOT_TYPE :مستودع خ STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}{VEHICLE} طويل للغايه بعد اﻹستبدال STR_ERROR_AUTOREPLACE_NOTHING_TO_DO :{WHITE}لا يوجد نظام مطبق للتبديل/ التجديد STR_ERROR_AUTOREPLACE_MONEY_LIMIT :(حدود التكلفة للتبديل) +STR_ERROR_AUTOREPLACE_INCOMPATIBLE_CARGO :{WHITE}العربة الجديدة لا تستطيع حمل {STRING} +STR_ERROR_AUTOREPLACE_INCOMPATIBLE_REFIT :{WHITE}لا يمكن تجديد السيارة الجديدة بالترتيب {NUM} # Rail construction errors STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}تركيبة سكك غير صالحة @@ -4227,6 +4277,7 @@ 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_NO_SUITABLE_ROAD :{WHITE}لا يوجد طريق مناسب STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}لا يوجد ترام مناسب # Waterway construction errors @@ -4344,6 +4395,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}لا ي STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... العربة تحطمت + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}لن تتوافر اى وسائل نقل على اﻹطلاق STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}لا تتوافر اى آليه نقل بعد @@ -4375,6 +4427,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}لا ي STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}بعيد جدا من محطة/علامة الوصول السابقة STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... الطائرات ليس لها مدى كاف +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}لا يمكن جدولة العربة ... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}يمكن للعربات الانتظار في المحطات فقط. diff --git a/src/lang/basque.txt b/src/lang/basque.txt index 275f9dde3d66a..f679a3ec099c3 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -198,6 +198,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -371,10 +372,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Irten # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Jokoaren aukerak STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Ezarpenak -STR_SETTINGS_MENU_SCRIPT_SETTINGS :IA/Jokoaren scriptaren ezaugarriak STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF ezarpenak STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Transparentzia ezarpenak STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Herri izenak erakutsita @@ -916,36 +916,6 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :Pertsonalizatua STR_GAME_OPTIONS_CURRENCY_GEL :Lari Georgiarra (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iraniarra (IRR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Ezkerretik gidatu -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Eskuinetik gidatu - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Herrien izenak -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Herrien izenen estiloak aukeratu - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Ingelesa (Jatorrizkoa) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Frantsesak -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Alemaniarrak -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Ingelesa (Adizionala) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latino-Amerikarra -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Inozoak -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Suediarrak -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Herbeheretakoak -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandiarrak -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Poloniarrak -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Eslovakiarrak -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norvegiarrak -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungariarrak -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austriarrak -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Errumaniarrak -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Txekoak -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Suitzarrak -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danierarrak -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turkiarrak -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiarrak -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalanak - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Auto-gordea STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Aukeratu jokoa automatikoki gordetzeko denbora @@ -970,11 +940,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :besteak -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Interfaze tamaina - -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normala -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Tamaina doblea -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Tamaina laukoitza @@ -1022,8 +987,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Aurreik STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 libra (£) zure dibisan STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Dibisa pertsonalaren ezaugarriak aldatu -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Gehienezko arerio kopurua: {ORANGE}{COMMA} - STR_NONE :Ezer ez STR_FUNDING_ONLY :Finantzazioa bakarrik STR_MINIMAL :Gutxienekoa @@ -1073,6 +1036,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Klima epeleko paisaia +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Klima artikoko paisaia +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Klima tropikaleko paisaia +STR_CLIMATE_TOYLAND_LANDSCAPE :Jostailu munduko paisaia + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Oso laua STR_TERRAIN_TYPE_FLAT :Laua @@ -1139,6 +1108,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Eskuina STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Gehienezko mailegua joko hasieran: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Konpainiek eskatu dezaketen gehienezko mailegua(inflazioa kontua hartu gabe) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Interes tasa: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Maileguen interes tasa; inflazioa ere kontrolatuko du, gaitzen bada @@ -1387,6 +1357,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Hobetua STR_CONFIG_SETTING_ROAD_SIDE :Errepideko garraioak: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Gidatzeko aldea aukeratu +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Ezkerretik gidatu +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Eskuinetik gidatu + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Garaiera maparen norabidea: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Erlojuko orratzen kontrara @@ -1814,7 +1788,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Seinaletan auto STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Trenak seinaleetan buelta ematea baimendu, denbora luzez itxaroten ari badira ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Gomendatua) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Gomendatua) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Ezarpenaren balioa aldatu @@ -1854,7 +1828,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Puntuazi STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Ezarpenak STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF-ren Ezarpenak STR_INTRO_ONLINE_CONTENT :{BLACK}Edukiak Online Kontsultatu -STR_INTRO_SCRIPT_SETTINGS :{BLACK}IA/Joko Scripten Ezarpenak STR_INTRO_QUIT :{BLACK}Irten STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Joko berria hasi. Krtl+klik mapa konfigurazioa desgaitzen du @@ -1874,7 +1847,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Puntuazi STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Ezarpenak erakutsi STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF ezarpenak erakutsi STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Bilatu eduki berria eta eguneratua deskargatzeko -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}IA/Joko Scripten Ezarpenak STR_INTRO_TOOLTIP_QUIT :{BLACK}'OpenTTD'-tik Irten STR_INTRO_TRANSLATION :{BLACK}Itzultze honi {NUM} string falta zaio/zaizkio. Mesedez OpenTTD hobeago egiten lagundu itzultzaile bezala aritzen. Ikusi readme.txt xehetasunentzako. @@ -1901,12 +1873,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Data al STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Aurtengo urtea aldatu STR_CHEAT_SETUP_PROD :{LTBLUE}Ekoizpen balioak aldatzea baimendu: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Klima epeleko paisaia -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Klima artikoko paisaia -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Klima tropikaleko paisaia -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Jostailu munduko paisaia - # Livery window STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Erakutsi kolore eskema orokorrak @@ -2299,6 +2265,8 @@ STR_LINKGRAPH_LEGEND_NONE :{BLACK}Bat ere STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}erabiltzeke STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}saturatua +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Geltoki irismena erakutsi STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Itzali @@ -2387,8 +2355,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Seinale STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Trenbide zubia aukeratu STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Errepide zubia aukeratu STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Zubi aukerak - eraiki nahi duzun zubian klik egin -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Altzairuzko zubi esekia STR_BRIDGE_NAME_GIRDER_STEEL :Altzairuzko habe zubia STR_BRIDGE_NAME_CANTILEVER_STEEL :Altzairuzko mentsula zubia @@ -2747,16 +2713,40 @@ STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}Mundua s STR_MAPGEN_MAPSIZE :{BLACK}Maparen tamaina: STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Herri kopurua: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Herrien izenak +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Herrien izenen estiloak aukeratu STR_MAPGEN_DATE :{BLACK}Data: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Industria kopurua: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Paisaia sortzailea: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Lur mota: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Itsaso kopurua: +STR_MAPGEN_SEA_LEVEL :{BLACK}Itsaso kopurua: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Errekak: STR_MAPGEN_SMOOTHNESS :{BLACK}Leuntasuna: STR_MAPGEN_VARIETY :{BLACK}Barietateen distribuzioa: STR_MAPGEN_GENERATE :{WHITE}Sortu +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Ingelesa (Jatorrizkoa) +STR_MAPGEN_TOWN_NAME_FRENCH :Frantsesak +STR_MAPGEN_TOWN_NAME_GERMAN :Alemaniarrak +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Ingelesa (Adizionala) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latino-Amerikarra +STR_MAPGEN_TOWN_NAME_SILLY :Inozoak +STR_MAPGEN_TOWN_NAME_SWEDISH :Suediarrak +STR_MAPGEN_TOWN_NAME_DUTCH :Herbeheretakoak +STR_MAPGEN_TOWN_NAME_FINNISH :Finlandiarrak +STR_MAPGEN_TOWN_NAME_POLISH :Poloniarrak +STR_MAPGEN_TOWN_NAME_SLOVAK :Eslovakiarrak +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norvegiarrak +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungariarrak +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austriarrak +STR_MAPGEN_TOWN_NAME_ROMANIAN :Errumaniarrak +STR_MAPGEN_TOWN_NAME_CZECH :Txekoak +STR_MAPGEN_TOWN_NAME_SWISS :Suitzarrak +STR_MAPGEN_TOWN_NAME_DANISH :Danierarrak +STR_MAPGEN_TOWN_NAME_TURKISH :Turkiarrak +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiarrak +STR_MAPGEN_TOWN_NAME_CATALAN :Katalanak + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Maparen ertzak: STR_MAPGEN_NORTHWEST :{BLACK}Ipar mendebaldea @@ -2884,6 +2874,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Aldez au STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Aurreko grafiko arruntera joan, pseudo/birkoloretu/grafiko tipoak desgaituz STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Orain aukeratutako grafikoaren aurkezpena. Alineazioa ez da kontua hartzen grafiko hau egiterakoan STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Sprite-a mugitu ingurunean, X eta Y-ren desplazamenduak aldatuz. Ctrl+Klik sprite-a zortzi unitatero mugitzeko + +###length 2 + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Erlatiboa berezarri STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Momentuan dauden desplazamendu erlatiboak erreseteatu STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X desplazamendua: {NUM}, Y desplazamendua: {NUM} (Absolutua) @@ -2898,7 +2892,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Kontuz: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Akatsa {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Larria: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}NewGRF-an akats larria gertatu da:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} ez du funtzionatuko OpenTTD-k esandakoTTDPatch bertsioarekin STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} {STRING} TTD bertsioarentzat da STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} {STRING}arekin erabiltzeko diseinatua izan da @@ -3387,6 +3380,8 @@ STR_PURCHASE_INFO_ALL_BUT :Guztia {CARGO_L STR_PURCHASE_INFO_MAX_TE :{BLACK}Gehienezko trakzio indarra: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Irismena: {GOLD}{COMMA} lauki +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Trenak aukeratzeko zerrenda - Klik xehetasunak ikusteko. Ctrl+Klik ibilgailu motaren ezkutapenaren artean aukeratzeko STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Errepide ibilbideak aukeratzeko zerrenda - Klik xehetasunak ikusteko @@ -3998,12 +3993,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Abiarazi STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}IA/Joko Script Garbitzailearen lehioa bakarrik zerbitzariarentzako erabilgarria da # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}IA/Joko Script-aren Ezarpenak STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Hurrengo jokoan kargatuko den Joko Script-a STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Hurrengo jokoan kargatuko diren IA-k STR_AI_CONFIG_HUMAN_PLAYER :Jokalaria STR_AI_CONFIG_RANDOM_AI :Ausazko IA STR_AI_CONFIG_NONE :(ezer ez) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Gehienezko arerio kopurua: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Gora Mugitu STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Auratutako IA zerrendan gora igo @@ -4013,8 +4008,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Aukeratu STR_AI_CONFIG_GAMESCRIPT :{SILVER}Jokoaren Script-a STR_AI_CONFIG_AI :{SILVER}IAk -STR_AI_CONFIG_CHANGE :{BLACK}Aukeratu {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :IA STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script jokoa STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Bestelako script bat kargatu @@ -4037,10 +4030,8 @@ STR_AI_LIST_CANCEL :{BLACK}Ezeztatu STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ez aldatu script-a -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametroak +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :IA -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Jokoaren Script-ak STR_AI_SETTINGS_CLOSE :{BLACK}Itxi STR_AI_SETTINGS_RESET :{BLACK}Berrabiarazi STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4441,6 +4432,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Ezin da STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... garraioa suntsituta + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Ez da ibilgailu erabilgarririk egongo STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Aldatu zure NewGRF konfigurazioa STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Ez dago ibilgailu erabilgarririk oraindik @@ -4473,6 +4465,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Ezin da STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... aurreko helmugatik urrutiegi STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... hegazkinaren irismen eremutik kanpo +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Ezin da ibilgailuren ordutegia egin... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Ibilgailuek bakarrik geltokietan itxaron dezakete diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 626f1b4d03dbe..71cb617270cb9 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -511,6 +511,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}к STR_UNITS_POWER_METRIC :{COMMA}{NBSP}к.с. STR_UNITS_POWER_SI :{COMMA}{NBSP}кВт + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}т STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}т STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}кг @@ -691,10 +692,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Выхад # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Наладкі гульні STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Наладкі -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Наладкі ШІ / скрыпту STR_SETTINGS_MENU_NEWGRF_SETTINGS :Наладкі NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Наладкі празрыстасьці STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Паказваць назвы гарадоў @@ -1254,36 +1254,6 @@ STR_GAME_OPTIONS_CURRENCY_CNY :Кітайск STR_GAME_OPTIONS_CURRENCY_HKD :Ганконскі даляр (HKD) STR_GAME_OPTIONS_CURRENCY_INR :Індыйская рупія (INR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}На якой мове будуць назвы населеных пунктаў - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Анґельскія (арыґінальныя) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Францускія -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Нямецкія -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Анґельскія (дадатковыя) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Лацінаамэрыканскія -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Анґельскія (жартоўныя) -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Швэдзкія -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Нідэрляндзкія -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Фінскія -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Польскія -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Славацкія -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Нарвэскія -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Вугорскія -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Аўстрыйскія -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Румынскія -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Чэскія -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Швайцарскія -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Дацкія -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Турэцкія -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Італьянскія -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Каталёнскія - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Аўтазахаваньне STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Інтэрвал паміж аўтаматычнымі захаваньнямі гульні @@ -1308,18 +1278,8 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :Iншае -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Памер элементаў інтэрфейсу -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Выберыце памер элементаў інтэрфейсу -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Звычайны -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Падвоены -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Пачацвяроны -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Памер шрыфта -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Абярыце памер шрыфта, выкарыстоўванага ў гульні - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Звычайны -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Падвоены STR_GAME_OPTIONS_REFRESH_RATE :{BLACK}Чашчыня абнаўлення экрана @@ -1367,8 +1327,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Узо STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 брыт. фунтаў (£) у вашай валюце STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Зьмяніць парамэтр уласнай валюты -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Максымальная колькасьць канкурэнтаў: {ORANGE}{COMMA} - STR_NONE :Няма STR_FUNDING_ONLY :Будаваць самому STR_MINIMAL :Мінімальнае @@ -1418,6 +1376,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :умераны ляндшафт +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :субарктычны ляндшафт +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :субтрапічны ляндшафт +STR_CLIMATE_TOYLAND_LANDSCAPE :цацачны ляндшафт + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Вельмі пляскатая STR_TERRAIN_TYPE_FLAT :Раўнінная @@ -1492,6 +1456,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :правару STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Максымальная сума пазыкі: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Максымальная сума пазыкі для кампаніі (без уліку інфляцыі) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Адсоткавая стаўка: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Адсоткавая стаўка па пазыках; таксама кантралюе інфляцыю, калі тая ўключана @@ -1759,6 +1724,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Палепша STR_CONFIG_SETTING_ROAD_SIDE :Рух аўтатранспарту: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Выберыце бок дарогі, па якому рухаецца аўтатранспарт +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Езьдзіць леваруч +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Езьдзіць праваруч + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Кручэньне мапы вышыняў: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :супраць руху гадзіньнікавай стрэлкі @@ -2255,7 +2224,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Аўтамат STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Дазволіць цягнікам разварочвацца перад сыґналамі, калі яны чакаюць доўгі час. ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(рэкамэндуецца) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(рэкамэндуецца) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Зьмяніць значэньне @@ -2296,7 +2265,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Табл STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Наладкі STR_INTRO_NEWGRF_SETTINGS :{BLACK}Наладкi NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Праверыць анлайн-кантэнт -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Наладкі ШІ / скрыпту STR_INTRO_QUIT :{BLACK}Выхад STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Пачаць новую гульню. Ctrl+клік прапускае этап наладак мапы @@ -2316,7 +2284,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Пака STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Акно наладак STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Паказаць наладкі NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Праверыць новы й абноўлены кантэнт, каб спампаваць -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Зьмяніць наладкі ШІ ды гульнёвага скрыпту STR_INTRO_TOOLTIP_QUIT :{BLACK}Выйсьці з OpenTTD STR_INTRO_BASESET :{BLACK}У абраным наборы базавай графікі адсутнічае {NUM} спрайт{P "" а аў}. Калі ласка, абнавіце набор графікі. @@ -2346,12 +2313,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Зьм STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Зьмяніць бягучы год STR_CHEAT_SETUP_PROD :{LTBLUE}Дазволіць зьмяненьне прадукцыйнасьці: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :умераны ляндшафт -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :субарктычны ляндшафт -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :субтрапічны ляндшафт -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :цацачны ляндшафт - # Livery window STR_LIVERY_CAPTION :{WHITE}Колеры кампаніі «{COMPANY}» @@ -2779,6 +2740,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}насычана STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}перагруз +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Падсьветка зоны пакрыцьця STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Выкл. @@ -2868,8 +2831,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Павя STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Выберыце чыгуначны мост STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Выберыце аўтамабiльны мост STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Выбар моста — пстрыкніце па малюнку моста, які Вы хочаце пабудаваць -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Падвесны сталёвы STR_BRIDGE_NAME_GIRDER_STEEL :Бэлечны сталёвы STR_BRIDGE_NAME_CANTILEVER_STEEL :Кансольны сталёвы @@ -3267,18 +3228,42 @@ STR_MAPGEN_MAPSIZE :{BLACK}Паме STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Выберыце памер памы ў клетках. Колькасьць даступных клетак будзе трохі меншай STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Колькасьць гарадоў: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Назвы гарадоў +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}На якой мове будуць назвы населеных пунктаў STR_MAPGEN_DATE :{BLACK}Дата: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Колькасьць прадпрыемстваў: STR_MAPGEN_SNOW_COVERAGE_TEXT :{BLACK}{NUM}% STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Паменшыць плошчу пяшчанага пакрыцця на 10% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Ґенэратар ляндшафту: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Тып ляндшафту: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Колькасьць азёраў/мораў: +STR_MAPGEN_SEA_LEVEL :{BLACK}Колькасьць азёраў/мораў: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Колькасьць рэк: STR_MAPGEN_SMOOTHNESS :{BLACK}Гладкасьць: STR_MAPGEN_VARIETY :{BLACK}Разнастайнасьць ляндшафту: STR_MAPGEN_GENERATE :{WHITE}Стварыць +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Анґельскія (арыґінальныя) +STR_MAPGEN_TOWN_NAME_FRENCH :Францускія +STR_MAPGEN_TOWN_NAME_GERMAN :Нямецкія +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Анґельскія (дадатковыя) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Лацінаамэрыканскія +STR_MAPGEN_TOWN_NAME_SILLY :Анґельскія (жартоўныя) +STR_MAPGEN_TOWN_NAME_SWEDISH :Швэдзкія +STR_MAPGEN_TOWN_NAME_DUTCH :Нідэрляндзкія +STR_MAPGEN_TOWN_NAME_FINNISH :Фінскія +STR_MAPGEN_TOWN_NAME_POLISH :Польскія +STR_MAPGEN_TOWN_NAME_SLOVAK :Славацкія +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Нарвэскія +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Вугорскія +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Аўстрыйскія +STR_MAPGEN_TOWN_NAME_ROMANIAN :Румынскія +STR_MAPGEN_TOWN_NAME_CZECH :Чэскія +STR_MAPGEN_TOWN_NAME_SWISS :Швайцарскія +STR_MAPGEN_TOWN_NAME_DANISH :Дацкія +STR_MAPGEN_TOWN_NAME_TURKISH :Турэцкія +STR_MAPGEN_TOWN_NAME_ITALIAN :Італьянскія +STR_MAPGEN_TOWN_NAME_CATALAN :Каталёнскія + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Краі мапы: STR_MAPGEN_NORTHWEST :{BLACK}Паўночны захад @@ -3417,6 +3402,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Папя STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Перайсьці да папярэдняга звычайнага спрайта, прапускаючы змяняючыя колер, шрыфтавыя, псэўдаспрайты. Пераход з пачатку сьпісу да апошняга спрайта. STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Прадстаўленьне выбранага спрайта. Выраўноўваньне не ўлічваецца пры прарысоўцы гэтага спрайта. STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Рухайце спрайт, зьмяняючы зрушэньне па X і па Y. Ctrl+пстрычка, каб зрушыць спрайт на восем адзінак за раз + +###length 2 + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Скід зрушэння STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Скінуць значэнні адноснага зрушэння STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Зрушэнне X: {NUM}; зрушэнне Y: {NUM} (абсалютнае) @@ -3431,8 +3420,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Увага: {SILVER}{STRING} 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} ня будзе працаваць з вэрсіяй TTDPatch, паведламленай OpenTTD. STR_NEWGRF_ERROR_DOS_OR_WINDOWS :Файл {1:STRING} патрабуе {STRING}-вэрсію TTD. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} зроблены для выкарыстаньня сумесна з {STRING} @@ -3954,6 +3941,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Макс STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Далёкасьць: {GOLD}{COMMA} клет{P ка кi ак} STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Тып паветр. судна: {GOLD}{STRING} +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Сьпіс лакаматываў і вагонаў - пстрыкніце для атрыманьня інфармацыі. Ctrl+пстрычка схавае/пакажа ТС. STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Сьпіс аўтатранспарту - пстрыкніце для атрыманьня інфармацыі. Ctrl+пстрычка схавае/пакажа выбраны аўтамабіль. @@ -4614,12 +4603,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Адзі STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Вакно адладкі ШІ / скрыпту даступна толькі для сэрвэра # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Канфігурацыя ШІ / скрыпту STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Гульнёвы скрыпт, які будзе загружаны ў наступнай гульні STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Модулі ШІ, якія будуць загружаны ў наступнай гульні STR_AI_CONFIG_HUMAN_PLAYER :Чалавек STR_AI_CONFIG_RANDOM_AI :Выпадковы ШI STR_AI_CONFIG_NONE :(няма) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Максымальная колькасьць канкурэнтаў: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Уверх STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Перамясьціць гэты модуль ШI ўверх па сьпісе @@ -4629,8 +4618,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Пера STR_AI_CONFIG_GAMESCRIPT :{SILVER}Гульнёвы скрыпт STR_AI_CONFIG_AI :{SILVER}ШI -STR_AI_CONFIG_CHANGE :{BLACK}Выбраць {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :ШI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Гульнёвы скрыпт STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Загрузіць іншы скрыпт @@ -4654,10 +4641,8 @@ STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Не з STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Бачная вобласць у максімальным набліжэнні -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}Параметры {STRING} +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :ШI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Гульнёвы скрыпт STR_AI_SETTINGS_CLOSE :{BLACK}Закрыць STR_AI_SETTINGS_RESET :{BLACK}Ськід STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -5065,6 +5050,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Не а STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... транспартны сродак зьнішчаны + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Усе транспартныя сродкі будуць недаступныя STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Зьмяніце канфігурацыю модуля NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Няма даступных транспартных сродкаў @@ -5098,6 +5084,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Нема STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... занадта далёка ад папярэдняй кропкі STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... Паветранаму судну не хапае далёкасьцi +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Не атрымалася скласьці расклад руху... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Транспарт можа чакаць толькі на станцыі. diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index c2c01a974d837..1989bb620459a 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}cv STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}T STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -227,8 +237,8 @@ STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Filtro: -STR_LIST_FILTER_OSKTITLE :{BLACK}Digite o filtro de série -STR_LIST_FILTER_TOOLTIP :{BLACK}Digite uma palavra-chave para filtrar a lista +STR_LIST_FILTER_OSKTITLE :{BLACK}Insira uma ou mais palavras-chave para filtrar a lista +STR_LIST_FILTER_TOOLTIP :{BLACK}Insira uma ou mais palavras-chave para filtrar a lista STR_TOOLTIP_GROUP_ORDER :{BLACK}Selecionar ordem de agrupamento STR_TOOLTIP_SORT_ORDER :{BLACK}Selecione ordem de classificação (descendente/ascendente) @@ -377,9 +387,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Geraçã STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Geração de indústria STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Contrução de rodovias STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Construção de trilho de bonde -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantar árvores. Shift alterna construção/exibição de preço estimado +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantar árvores. Ctrl seleciona a área na diagonal. Shift alterna construir/mostrar estimativa de custo STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Colocar placa -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar objeto. Shift alterna construção/preço estimado +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar objeto. Ctrl seleciona a área na diagonal. Shift alterna construir/mostrar estimativa de custo # Scenario editor file menu ###length 7 @@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Sair # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Opções do jogo STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Configurações -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Configurações de IA /Script do jogo +STR_SETTINGS_MENU_AI_SETTINGS :Definições de IA +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Definições de script do jogo STR_SETTINGS_MENU_NEWGRF_SETTINGS :Definições do NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opções de Transparência STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Nomes de cidades exibidos @@ -735,7 +746,7 @@ STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP :{BLACK}Exibir i STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP :{BLACK}Exibir fluxo de carga no mapa STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Exibir rotas de transporte no mapa STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP :{BLACK}Exibir vegetação no mapa -STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Exibir proprietários de terreno no mapa +STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Exibir proprietários de terrenos no mapa STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Clique em um tipo de indústria para alternar sua exibição. Ctrl+Clique desabilita todos os tipos exceto a selecionada. Ctrl+Clique nela novamente para habilitar todos os tipos de indústrias STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Clique em uma compania para alternar a exibição de suas propriedades. Ctrl+Clique desabilita todas as companias exceto a selecionada. Ctrl+Clique nela novamente para habilitar todas as companias STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Clique numa carga para alternar a exibição de sua propriedade. Ctrl+Clique desativa todas as cargas exceto a selecionada. Ctrl+Clique novamente para exibir todas @@ -966,36 +977,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rúpia Indiana STR_GAME_OPTIONS_CURRENCY_IDR :Rupia Indonésia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit Malaio (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Dirigem na esquerda -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Dirigem na direita - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nome das cidades: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Selecionar o estilo dos nomes das cidades - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Inglês (Original) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francês -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Alemão -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Inglês (Adicional) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latino-Americano -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Idiota -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Sueco -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holandês -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandês -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polonês -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Eslovaco -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norueguês -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Húngaro -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austríaco -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romeno -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Checo -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Suiço -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dinamarquês -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turco -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiano -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalão - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Salvar automaticamente STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selecionar o intervalo entre jogos salvos automaticos @@ -1026,23 +1007,21 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}A config STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Marque esta caixa para habilitar o v-sync na tela. Qualquer mudança nesta configuração só será aplicada após reiniciar o jogo. Só funciona com a aceleração de hardware habilitada -STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Motorista atual: {STRING} +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Driver de vídeo atual: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Tamanho da interface -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Selecione o tamanho de elemento de interface a ser usado +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Tamanho da interface +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Arraste o controle deslizante para definir o tamanho do interface. Mantenha pressionada a tecla Ctrl para um ajuste contínuo +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Detectar tamanho automaticamente +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marque esta caixa para detectar o tamanho da interface automaticamente -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(detecção automática) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dobro -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quádruplo +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Escalar de chanfros +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marque esta caixa para dimensionar os chanfros por tamanho de interface -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Tamanho da fonte -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Selecione o tamanho da fonte da interface a ser usado - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(detecção automática) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Tamanho duplo -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Tamanho quádruplo +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Gráficos @@ -1094,8 +1073,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Previs STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Libras (£) na sua moeda STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Alterar o parâmetro de moeda personalizada -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Número máximo de concorrentes: {ORANGE}{COMMA} - STR_NONE :Nenhum STR_FUNDING_ONLY :Apenas financiamento STR_MINIMAL :Mínimo @@ -1145,6 +1122,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :terreno temperado +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :terreno subártico +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :terreno subtropical +STR_CLIMATE_TOYLAND_LANDSCAPE :terreno 'toyland' + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Muito Plano STR_TERRAIN_TYPE_FLAT :Plano @@ -1224,6 +1207,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Direita STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Empréstimo Inicial Máximo: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Quantia máxima a ser emprestada para uma companhia (sem levar em conta a inflação) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Sem empréstimo {RED}Requer Script de Jogo para fornecer fundos iniciais STR_CONFIG_SETTING_INTEREST_RATE :Taxa de Juros: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Juros de empréstimo; também controla inflação, se ativado @@ -1450,6 +1436,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Espessura da li STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Mostrar o nome do NewGRF na janela de comprar veículos: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Adicione uma linha à janela de construção do veículo, mostrando de qual NewGRF o veículo selecionado vem. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Mostrar as cargas que os veículos podem transportar nas janelas de listagem {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Quando ativado, a carga transportável do veículo aparecerá acima dela nas listas de veículos STR_CONFIG_SETTING_LANDSCAPE :Terreno: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :O terreno define a jogabilidade básica com diferentes cargas e requerimentos para o crescimento das cidades. NewGRF's e Scripts de Jogo permitem um controle mais fino @@ -1504,6 +1492,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Melhorado STR_CONFIG_SETTING_ROAD_SIDE :Automóveis: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Escolha a mão de direção +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Dirigem na esquerda +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Dirigem na direita + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotação do mapa topográfico: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Sentido Anti-Horário @@ -1937,13 +1929,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Demore {STRING} STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tempo tomado para cada recálculo de um componente de um gráfico. Quando um recálculo começa, um processo é criado e é executado por esse número de dias. Quanto menos dias você define, maior a chance do processo não terminar quando era para ter terminado. Nesse caso, o jogo irá parar até ele terminar ("lag"). Quanto maior você definir isso, mais tempo leva para a distribuição ser atualizada quando as rotas mudarem. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modo de distribuição para passageiros: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"simétrico" significa que aproximadamente a mesma quantidade de passageiros será enviada da estação A para a estação B assim como de B para A. "assimétrico" significa que a quantidade de passageiros enviada em ambas as direções será arbitrária. "manual" significa que não haverá distribuição automática. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simétrico" significa que aproximadamente o mesmo número de passageiros irá de uma estação A para uma estação B como de B para A. "Assimétrico" significa que um número arbitrário de passageiros pode ir em qualquer direção. "Manual" significa que não haverá distribuição automática para os passageiros. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Modo de distribuição para correios: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"simétrico" significa que aproximadamente a mesma quantidade de correio será enviada da estação A para a estação B assim como de B para A. "assimétrico" significa que a quantidade de correio enviada em ambas as direções será arbitrária. "manual" significa que não haverá distribuição automática. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Simétrico" significa que aproximadamente a mesma quantidade de correspondência será enviada de uma estação A para uma estação B como de B para A. "Assimétrica" significa que quantidades arbitrárias de correspondência podem ser enviadas em qualquer direção. "Manual" significa que nenhuma distribuição automática ocorrerá por correio. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Modo de distribuição para classe BLINDADOS de carga: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :A classe BLINDADO indica objetos de valor no clima temperado, diamantes no subtropical ou ouro no subártico. NewGRF's podem mudar isso. "simétrico" significa que aproximadamente a mesma quantidade de carga será enviada da estação A para a estação B assim como de B para A. "assimétrico" significa que quantidades de carga arbitrárias serão enviadas em ambas as direções. "manual" significa que não haverá distribuição automática. Para objetos de valor, sugere-se usar "assimétrico" ou "manual" para subártico, já que bancos não enviam ouro de volta a minas. Para temperado e subtropical você pode selecionar "simétrico", já que bancos trocam objetos de valor entre si. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :A classe de carga BLINDADA contém objetos de valor em clima temperado, diamantes em clima subtropical ou ouro em clima subártico. NewGRFs podem mudar isso. "Simétrica" significa que aproximadamente a mesma quantidade dessa carga será enviada de uma estação A para uma estação B como de B para A. "Assimétrica" significa que quantidades arbitrárias dessa carga podem ser enviadas em qualquer direção. "Manual" significa que não haverá distribuição automática para aquela carga. Recomenda-se definir isso como assimétrico ou manual ao jogar subártico ou subtropical, pois os bancos só recebem carga nesses climas. Para temperado, você também pode escolher simétrico, pois os bancos enviarão objetos de valor de volta ao banco de origem. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modo de distribuição para outras classes de carga: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"assimétrico" significa que quantidades de carga arbitrárias serão enviadas em ambas as direções. "manual" significa que não haverá distribuição automática. Você provavelmente irá querer usar "assimétrico" ou "manual". +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Assimétrico" significa que quantidades arbitrárias de carga podem ser enviadas em qualquer direção. "Manual" significa que não haverá distribuição automática dessas cargas. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :assimétrico @@ -2038,7 +2030,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Reversão autom STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Permite trens reverterem sentido num sinal, se estiverem aguardando por muito tempo ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomendado) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recomendado) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Alterar valor @@ -2081,7 +2073,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Pontuaç STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Configurações STR_INTRO_NEWGRF_SETTINGS :{BLACK}Configurar NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Checar conteúdo on-line -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Configurações de IA / Script do jogo +STR_INTRO_AI_SETTINGS :{BLACK}Definições de IA +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Definições de Script do Jogo STR_INTRO_QUIT :{BLACK}Sair STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Iniciar um novo jogo. Ctrl+Clique para pular a configuração do mapa @@ -2101,7 +2094,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Exibe as STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Config. de exibição STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Exibir configs. dos NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Checar por conteúdo novo e atualizado para baixar -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Exibe configurações de IA e script do jogo +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Mostrar definições de IA +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Mostrar definições de Script do Jogo STR_INTRO_TOOLTIP_QUIT :{BLACK}Sair do 'OpenTTD' STR_INTRO_BASESET :{BLACK}Faltam {NUM} "sprite{P "" s}" no conjunto de gráficos base selecionado. Por favor verifique se há atualizações para ele. @@ -2133,12 +2127,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Alterar STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Mudar ano atual STR_CHEAT_SETUP_PROD :{LTBLUE}Ativar modificação de valores de produção: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :terreno temperado -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :terreno subártico -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :terreno subtropical -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :terreno 'toyland' - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Esquema de cores @@ -2371,7 +2359,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nova empresa) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Cria uma nova empresa e se une a ela STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Esse é você STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Esse é o hospedeiro do jogo -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s} / {NUM} empresa{P "" s} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s} - {NUM}/{NUM} empres{P a as} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}O número de clientes atualmente conectados, número de empresas e número máximo de empresas permitido pelo administrador do servidor # Matches ConnectionType ###length 5 @@ -2498,13 +2487,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :aguardando atua STR_NETWORK_MESSAGE_CLIENT_LEAVING :saindo STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} entrou no jogo -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} entrou no jogo (Client #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} entrou na companhia #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} entrou no jogo (Client #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} entrou na empresa #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} está assistindo ao jogo -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} abriu uma nova companhia (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} saiu do jogo ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} iniciou uma nova empresa (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} saiu do jogo ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} mudou seu nome para {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} deu {2:CURRENCY_LONG} a {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} deu {2:CURRENCY_LONG} a {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}O servidor fechou a sessão STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}O servidor está reiniciando...{}Aguarde... STR_NETWORK_MESSAGE_KICKED :*** {STRING} foi kickado. Motivo: ({STRING}) @@ -2515,7 +2504,7 @@ STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Seu serv STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Outros jogadores não poderão se conectar ao seu servidor # Content downloading window -STR_CONTENT_TITLE :{WHITE}Baixando conteúdo +STR_CONTENT_TITLE :{WHITE}Download de conteúdo STR_CONTENT_TYPE_CAPTION :{BLACK}Tipo STR_CONTENT_TYPE_CAPTION_TOOLTIP :{BLACK}Tipo do conteúdo STR_CONTENT_NAME_CAPTION :{BLACK}Nome @@ -2537,7 +2526,7 @@ STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Visitar STR_CONTENT_DOWNLOAD_CAPTION :{BLACK}Baixar STR_CONTENT_DOWNLOAD_CAPTION_TOOLTIP :{BLACK}Baixa o conteúdo selecionado STR_CONTENT_TOTAL_DOWNLOAD_SIZE :{SILVER}Tamanho total do download: {WHITE}{BYTES} -STR_CONTENT_DETAIL_TITLE :{SILVER}INFO DO CONT. +STR_CONTENT_DETAIL_TITLE :{SILVER}INFORMAÇÕES DO CONTEÚDO ###length 5 STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED :{SILVER}Você não selecionou para ser baixado @@ -2618,6 +2607,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}saturado STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}sobrecarregado +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} a ser transportado mensalmente de {STATION} para {STATION} ({COMMA}% da capacidade){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} para ser transportado de volta ({COMMA}% da capacidade) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Tempo médio de viagem: {NUM}{NBSP}dia{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Destacar cobertura STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Desativar @@ -2626,6 +2620,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Não des STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Destacar área de cobertura da construção proposta STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Aceita: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Suprimentos: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Custo de manutenção: {GOLD}{CURRENCY_SHORT}/ano # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Unir estação @@ -2708,8 +2703,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Aumentar STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Selecionar Ponte Ferroviária STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Selecionar Ponte Rodoviária STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Seleção de ponte - clique na ponte desejada para construir -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Suspensa, Aço STR_BRIDGE_NAME_GIRDER_STEEL :Vigas, Aço STR_BRIDGE_NAME_CANTILEVER_STEEL :Cantilever, Aço @@ -2813,11 +2810,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Terreno STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Baixar um canto do terreno. Arrastar abaixa o primeiro canto selecionado e nivela a área selecionada à altura do novo canto. CTRL seleciona a área diagonalmente. Shift alterna construção/preço estimado STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK} Elevar um canto do terreno. Arrastar eleva o primeiro canto selecionado e nivela a área selecionada à nova altura do canto. Ctrl seleciona a área diagonalmente. Shift alterna contrução/preço estimado STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Nivelar uma área do terreno à altura do primeiro canto selecionado. Ctrl seleciona uma área diagonalmente. Shift alterna contrução/preço estimado -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreno para uso futuro. Shift altera construção/preço estimado +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreno para uso futuro. Ctrl seleciona a área na diagonal. Shift alterna construir/mostrar estimativa de custo # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Seleção de Objeto -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selecione o objeto a ser construído. Shift alterna construção/preço estimado +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selecione o objeto para construir. Ctrl seleciona a área na diagonal. Shift alterna construir/mostrar estimativa de custo STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Selecione uma categoria de objeto para construir STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Pré-visualização do objeto STR_OBJECT_BUILD_SIZE :{BLACK}Tamanho: {GOLD}{NUM} x {NUM} quadrados @@ -2829,15 +2826,15 @@ STR_OBJECT_CLASS_TRNS :Transmissores STR_PLANT_TREE_CAPTION :{WHITE}Árvores STR_PLANT_TREE_TOOLTIP :{BLACK}Selecionar um tipo de árvore para plantar. Se o local já tiver uma árvore, isso irá adicionar mais árvores do tipo misto indepentendemente do tipo selecionado STR_TREES_RANDOM_TYPE :{BLACK}Árvores de tipo aleatório -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Plantar árvores de tipo aleatório, Shift alterna entre construção/preço estimado +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Coloque árvores de tipo aleatório. Ctrl seleciona a área na diagonal. Shift alterna construir/mostrar estimativa de custo STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Plantar Aleatoriamente -STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Planta árvores aleatoriamente pelo terreno +STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plantar árvores aleatoriamente pelo terreno STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal STR_TREES_MODE_NORMAL_TOOLTIP :{BLACK}Planta árvores isoladas ao arrastar pelo terreno. STR_TREES_MODE_FOREST_SM_BUTTON :{BLACK}Bosque -STR_TREES_MODE_FOREST_SM_TOOLTIP :{BLACK}Planta pequenas florestas ao arrastar pelo terreno. +STR_TREES_MODE_FOREST_SM_TOOLTIP :{BLACK}Plantar pequenas florestas ao arrastar sobre o terreno. STR_TREES_MODE_FOREST_LG_BUTTON :{BLACK}Floresta -STR_TREES_MODE_FOREST_LG_TOOLTIP :{BLACK}Planta florestas grandes ao arrastar pelo terreno. +STR_TREES_MODE_FOREST_LG_TOOLTIP :{BLACK}Plantar florestas grandes ao arrastar pelo terreno. # Land generation window (SE) STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION :{WHITE}Gerar Terreno @@ -2861,6 +2858,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Cidade A STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Constrói cidade num local aleatório STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Várias cidades aleatórias STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cobrir o mapa com cidades colocadas aleatoriamente +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Expandir todas as cidades +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Fazer com que todas as cidades cresçam ligeiramente STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nome da cidade: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Coloque o nome da cidade @@ -3139,6 +3138,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Dimensõ STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Seleciona o tamanho do mapa em quadrados. O número de quadrados disponíveis será um pouco menor STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}No. de cidades: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nome das cidades: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Selecionar o estilo dos nomes das cidades STR_MAPGEN_DATE :{BLACK}Data: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}No. de indústrias: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Pico mais alto: @@ -3152,13 +3153,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Cobertur STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Aumentar a cobertura do deserto em dez por cento STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Diminuir a cobertura do deserto em dez por cento STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Gerador de terra STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tipo de terreno -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Nível do mar: +STR_MAPGEN_SEA_LEVEL :{BLACK}Nível do mar: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Rios: STR_MAPGEN_SMOOTHNESS :{BLACK}Regularidade STR_MAPGEN_VARIETY :{BLACK}Distribuição da variedade STR_MAPGEN_GENERATE :{WHITE}Gerar +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Definições de NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Mostrar definições de NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Definições de IA +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Mostrar definições de IA +STR_MAPGEN_GS_SETTINGS :{BLACK}Definições de Script do Jogo +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Mostrar definições de script do jogo + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Inglês (Original) +STR_MAPGEN_TOWN_NAME_FRENCH :Francês +STR_MAPGEN_TOWN_NAME_GERMAN :Alemão +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Inglês (Adicional) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latino-Americano +STR_MAPGEN_TOWN_NAME_SILLY :Idiota +STR_MAPGEN_TOWN_NAME_SWEDISH :Sueco +STR_MAPGEN_TOWN_NAME_DUTCH :Holandês +STR_MAPGEN_TOWN_NAME_FINNISH :Finlandês +STR_MAPGEN_TOWN_NAME_POLISH :Polonês +STR_MAPGEN_TOWN_NAME_SLOVAK :Eslovaco +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norueguês +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Húngaro +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austríaco +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romeno +STR_MAPGEN_TOWN_NAME_CZECH :Checo +STR_MAPGEN_TOWN_NAME_SWISS :Suiço +STR_MAPGEN_TOWN_NAME_DANISH :Dinamarquês +STR_MAPGEN_TOWN_NAME_TURKISH :Turco +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiano +STR_MAPGEN_TOWN_NAME_CATALAN :Catalão # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Bordas do mapa: @@ -3304,6 +3333,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}"Sprite" STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Retorna ao "sprite" normal anterior, pulando quaisquer "sprites" falsos, recoloridos ou de fontes, e junta tudo do primeiro ao último STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representação do "sprite" atualmente selecionado. O alinhamento é ignorado ao desenhar esse "sprite" STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Move o "sprite", alterando os offsets X e Y. Ctrl+Clique para mover o sprite 8 unidades por vez + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Deslocamento centralizado +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centralizado + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Mira + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Resetar relativo STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Reseta os offsets relativos atuais STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X offset: {NUM}, Y offset: {NUM} (Absoluto) @@ -3318,18 +3354,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Atenção: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Erro: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Erro Fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Um erro de NewGRF fatal ocorreu:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Um erro NewGRF ocorreu:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}O NewGRF "{STRING}" retornou um erro fatal:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}O NewGRF "{STRING}" retornou um erro fatal:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} não irá funcionar com a versão do TTDPatch encontrada pelo OpenTTD STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} funciona na versão {STRING} de TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} é projetado para ser usado com {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :parâmetro inválido para {1:STRING}: parâmetro {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} deve ser carregado antes de {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} deve ser carregado depois de {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requer versão {STRING} ou maior do OpenTTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} é projetado para ser usado com {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Parâmetro inválido para {1:STRING}: parâmetro {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} deve ser carregado antes de {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} deve ser carregado depois de {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requer versão {STRING} ou superior do OpenTTD STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :o arquivo GRF foi designado para tradução STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Muitas NewGRFs estão carregadas -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Carregar {1:STRING} como um NewGRF estático em conjunto com {STRING} pode causar desincronias +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Carregar {1:STRING} como NewGRF estático com {2:STRING} pode causar dessincronizações STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :"Sprite" inesperado (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Propriedade de Ação Desconhecida 0 {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Tentativa de uso de ID inválido (sprite {3:NUM}) @@ -3461,14 +3497,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Comprar exclusi STR_LOCAL_AUTHORITY_ACTION_BRIBE :Subornar a prefeitura ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Iniciar uma pequena campanha publicitária local, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um pequeno raio ao redor do centro da cidade.{}Preço: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Iniciar uma campanha publicitária média, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um raio médio ao redor do centro da cidade.{}Preço: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Iniciar uma grande campanha publicitária, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um grande raio ao redor do centro da cidade.{}Preço: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Financiar a reconstrução da malha rodoviária urbana.{}Causa engarrafamentos consideráveis ao tráfego por até 6 meses.{}Preço: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Construir uma estátua em homenagem à sua empresa.{}Fornece um aumento permanente na avaliação da estação nesta cidade.{}Preço: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Financiar a construção de edifícios comerciais novos na cidade.{}Fornece um aumento temporário do crescimento da cidade nesta cidade.{}Preço: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Comprar a exclusividade dos serviços durante 1 ano na cidade.{}A prefeitura da cidade não permitirá que passageiros e cargas usem as estações de seus concorrentes.{}Preço: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Subornar a prefeitura para aumentar a sua avaliação, correndo o risco de uma penalidade severa se apanhado.{}Preço: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Iniciar uma pequena campanha publicitária local, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um pequeno raio ao redor do centro da cidade.{}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Iniciar uma campanha publicitária média, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um raio médio ao redor do centro da cidade.{}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniciar uma grande campanha publicitária, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um grande raio ao redor do centro da cidade{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Financiar obras de reconstrução da malha rodoviária urbana.{}Causa engarrafamentos consideráveis ao tráfego por até 6 meses.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Construir uma estátua em homenagem à sua empresa.{}Fornece um aumento permanente na classificação da estação nesta cidade..{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Financiar a construção de novos edifícios na cidade.{}Providencia um aumento temporário no crescimento desta cidade.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Comprar a exclusividade dos serviços durante 1 ano na cidade.{}A prefeitura da cidade não permitirá que passageiros e cargas utilizem as estações de seus concorrentes..{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Subornar a autoridade local para aumentar a sua avaliação, correndo o risco de uma penalidade severa se for pego.{}{POP_COLOUR}Custo: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Objetivos @@ -3641,15 +3677,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Navios STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Juros do Empréstimo STR_FINANCES_SECTION_OTHER :{GOLD}Outros +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Lucro Líquido +STR_FINANCES_PROFIT :{WHITE}Lucro STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Balanço Bancário STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Fundos Próprios STR_FINANCES_LOAN_TITLE :{WHITE}Empréstimo STR_FINANCES_INTEREST_RATE :{WHITE}Juro do Empréstimo: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Empréstimo Máximo: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Pedir {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Pedir empréstimo. Ctrl+Clique pede o máximo possível STR_FINANCES_REPAY_BUTTON :{BLACK}Pagar {CURRENCY_LONG} @@ -3750,7 +3789,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produz: STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Necessita: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} aguardando{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Modificar produção (múltiplo de 8, até 2040) @@ -3780,6 +3819,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Envia in STR_VEHICLE_LIST_REPLACE_VEHICLES :Substituir veículos STR_VEHICLE_LIST_SEND_FOR_SERVICING :Enviar para Manutenção STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Lucro anual: {CURRENCY_LONG} (último ano: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Enviar para Depósito STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Enviar para Garagem @@ -3871,6 +3912,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Tração STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Alcance: {GOLD}{COMMA} quadrados STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipo de aeronave: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Todos os tipos de carga +STR_CARGO_TYPE_FILTER_FREIGHT :Frete +STR_CARGO_TYPE_FILTER_NONE :Nenhum + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Lista de trens - clique num trem para informações. Cltr+Clique para alterar a visibilidade do tipo de trem STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Lista de automóveis - clique num automóvel para informações. Cltr+Clique para alterar a visibilidade do tipo de automóvel @@ -4039,7 +4085,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :aeronave STR_ENGINE_PREVIEW_SHIP :embarcação STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Preço: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocidade: {VELOCITY} Potência: {POWER}{}Custo de manutenção: {CURRENCY_LONG}/ano{}Capacidade: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Preço: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Vel.: {VELOCITY} Potência: {POWER} Tração Máx: {6:FORCE}{}Custo de manutenção: {4:CURRENCY_LONG}/yr{}Capacidade: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Custo: {0:CURRENCY_LONG} Peso: {1:WEIGHT_SHORT}{}Velocidade: {2:VELOCITY} Potência: {3:POWER} Tração Máx: {6:FORCE}{}Custo de Operação: {4:CURRENCY_LONG}/ano{}Capacidade: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Preço: {CURRENCY_LONG} Vel. Max.: {VELOCITY}{}Capacidade: {CARGO_LONG}{}Custo de manuteção: {CURRENCY_LONG}/ano STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Vel Máx.: {VELOCITY}{}Tipo de aeronave: {STRING}{}Capacidade: {CARGO_LONG}, {CARGO_LONG}{}Custo de oper.: {CURRENCY_LONG}/ano STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Vel Máx.: {VELOCITY}{}Tipo de aeronave: {STRING}{}Capacidade: {CARGO_LONG}{}Custo de oper.: {CURRENCY_LONG}/ano @@ -4198,11 +4244,12 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {L STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Força: {LTBLUE}{POWER}{BLACK} Velocidade Max: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucros desse ano: {LTBLUE}{CURRENCY_LONG} (ano passado: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Lucro deste ano: {LTBLUE}{CURRENCY_LONG} (último ano: {CURRENCY_LONG}) {BLACK}Performance min.: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Confiabilidade: {LTBLUE}{COMMA}% {BLACK}Quebras desde a última manutenção: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacidade: {LTBLUE}Nenhuma{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidade: {LTBLUE}{0:CARGO_LONG}{3:STRING} STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} @@ -4469,25 +4516,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Este hor STR_TIMETABLE_STATUS_START_AT :{BLACK}Este horário começará em{STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Data de início -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Seleciona uma data como ponto de partida para esse horário. Ctrl+Clique define o ponto de partida desse horário, e distribui todos os veículos que compartilham essa ordem igualmente, baseados na sua ordem relativa, mesmo que a ordem esteja totalmente tabelada +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Seleciona uma data como ponto de partida para esse horário. Ctrl+Clique define o ponto de partida desse horário e distribui todos os veículos que compartilham essa ordem igualmente, baseados na sua ordem relativa, mesmo que a ordem esteja totalmente tabelada STR_TIMETABLE_CHANGE_TIME :{BLACK}Mudar horário -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Mudar a quantidade de tempo que a ordem destacada deverá levar +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Mudar a duração do tempo que a ordem em destaque deve durar. Ctrl+Clique define o tempo para todas as ordens STR_TIMETABLE_CLEAR_TIME :{BLACK}Limpar Horário -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Limpar a quantidade de tempo para a ordem destacada +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Limpar a duração do tempo da ordem destacada. Ctrl+Clique limpa os tempos para todas as ordens STR_TIMETABLE_CHANGE_SPEED :{BLACK}Alterar Limite de Vel. -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Altera a velocidade máxima de viagem para a ordem selecionada +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Altera a velocidade máxima de viagem para a ordem selecionada. Ctrl+Clique define a velocidade para todas as ordens STR_TIMETABLE_CLEAR_SPEED :{BLACK}Limpa Limite de Vel. -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Limpar a velocidade máxima de viagem para a ordem selecionada +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Limpar a velocidade máxima de viagem da ordem em destaque. Ctrl+Clique limpa as velocidades para todas as ordens STR_TIMETABLE_RESET_LATENESS :{BLACK}Restabelecer Contador de Atraso -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Restabelecer o contador de atraso,então o veículo estará pontual +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Redefina o contador de atrasos, para que o veículo chegue no horário. Ctrl+Clique redefinirá todo o grupo para que o veículo mais recente chegue no horário e todos os outros cheguem mais cedo STR_TIMETABLE_AUTOFILL :{BLACK}Autopreencher -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Preencher o horário automaticamente com os valores da próxima jornada. (CTRL+Clique para tentar manter os tempos de espera) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Preencher o horário automaticamente com os valores da próxima viagem. Ctrl+Clique para tentar manter os tempos de espera STR_TIMETABLE_EXPECTED :{BLACK}Esperado STR_TIMETABLE_SCHEDULED :{BLACK}Agendado @@ -4531,12 +4578,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Um dos s STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Depuração de I.A./Script do jogo só é acessível pelo servidor # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Configuração da I.A./Script do jogo +STR_AI_CONFIG_CAPTION_AI :{WHITE}Configuração de IA +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Configuração de Script de Jogo STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}O script do jogo que será carregado no próximo jogo -STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}IAs que serão carregadas no próximo jogo +STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}As IAs que serão carregadas no próximo jogo STR_AI_CONFIG_HUMAN_PLAYER :Jogador humano STR_AI_CONFIG_RANDOM_AI :IA aleatória STR_AI_CONFIG_NONE :{G=m}(nenhum) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Número máximo de concorrentes: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Subir STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Mover a IA selecionada para cima na lista @@ -4544,12 +4593,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Descer STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Mover a IA selecionada para baixo na lista STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script do jogo +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parâmetros STR_AI_CONFIG_AI :{G=f}{SILVER}IAs -STR_AI_CONFIG_CHANGE :{BLACK}Selecionar {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :{G=f}IA -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script do jogo +STR_AI_CONFIG_CHANGE_AI :{BLACK}Selecionar IA +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Selecionar Script do Jogo STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carregar outro script STR_AI_CONFIG_CONFIGURE :{BLACK}Configurar STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configurar os parâmetros do Script @@ -4577,10 +4625,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Captura STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Captura de tela do mapa topográfico STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Captura de tela do minimapa -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parâmetros -STR_AI_SETTINGS_CAPTION_AI :{G=f}IA -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script do jogo +STR_AI_SETTINGS_CAPTION_AI :IA +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script de Jogo STR_AI_SETTINGS_CLOSE :{BLACK}Fechar STR_AI_SETTINGS_RESET :{BLACK}Resetar STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4590,11 +4638,11 @@ STR_AI_SETTINGS_START_DELAY :Número de dias # Textfile window STR_TEXTFILE_WRAP_TEXT :{WHITE}Quebra de linha STR_TEXTFILE_WRAP_TEXT_TOOLTIP :[BLACK}Quebra linhas automaticamente para que o texto caiba na janela -STR_TEXTFILE_VIEW_README :{BLACK}Ler o Leiame +STR_TEXTFILE_VIEW_README :{BLACK}Ver o leia-me STR_TEXTFILE_VIEW_CHANGELOG :{BLACK}Log de mudanças STR_TEXTFILE_VIEW_LICENCE :{BLACK}Licença ###length 3 -STR_TEXTFILE_README_CAPTION :{WHITE}{STRING} Leiame de {STRING} +STR_TEXTFILE_README_CAPTION :{WHITE}{STRING} Leia-me de {STRING} STR_TEXTFILE_CHANGELOG_CAPTION :{WHITE}{STRING} log de mudanças de {STRING} STR_TEXTFILE_LICENCE_CAPTION :{WHITE}{STRING} licença de {STRING} @@ -4744,6 +4792,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... exis STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Impossível gerar indústrias... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Impossível construir {STRING} aqui... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Impossível construir este tipo de indústria aqui... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Não é possível prospectar indústria... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... muito perto de outra indústria STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... deve construir uma cidade antes STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... só é permitido uma por cidade @@ -4758,6 +4807,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... a fl STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... só pode ser construído acima do nível da neve STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... só pode ser construída abaixo do nível da neve +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}O financiamento falhou em prospectar devido ao azar; tente novamente +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Não havia locais adequados para prospectar esta indústria STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Não existe locais aceitáveis para '{STRING}' indústrias STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Mude os parâmetros de geração do mapa para obter um mapa melhor @@ -4903,7 +4954,7 @@ STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Remova a STR_ERROR_CAN_T_START_AND_END_ON :{WHITE}Impossível iniciar e terminar no mesmo ponto STR_ERROR_BRIDGEHEADS_NOT_SAME_HEIGHT :{WHITE}Extremidades da ponte não estão no mesmo nível STR_ERROR_BRIDGE_TOO_LOW_FOR_TERRAIN :{WHITE}Ponte é muito baixa para o terreno -STR_ERROR_BRIDGE_TOO_HIGH_FOR_TERRAIN :{WHITE}A ponte está muito alta para esse terreno. +STR_ERROR_BRIDGE_TOO_HIGH_FOR_TERRAIN :{WHITE}A ponte está muito alta para este terreno. STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Inicio e fim devem estar alinhados STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... os extremos da ponte devem estar sobre a terra STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... ponte muito longa @@ -4925,6 +4976,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objeto n STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... sede de empresa no caminho STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Impossível comprar esta área... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... já a possui! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... limite de construção de objetos atingido # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Impossível criar grupo... @@ -4997,6 +5049,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Impossí STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... veículo está destruído +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... nem todos os veículos são idênticos + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Não haverá nenhum veículo disponível STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Altere sua configuração de NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Não há veículos disponíveis ainda @@ -5023,6 +5077,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Impossí STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... o veículo não pode chegar a todas as estações STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... o veículo não chega àquela estação STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... um veículo com essa mesma ordem não chega àquela estação +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... nem todos os veículos possuem as mesmas ordens +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... nem todos os veículos estão compartilhando ordens STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Impossível compartilhar a lista de ordens... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Impossível compartilhar lista de ordens... @@ -5030,6 +5086,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Impossí STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... muito distante do destino anterior STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... aeronave não tem alcance o bastante +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Não há estação ferroviária +STR_ERROR_NO_BUS_STATION :{WHITE}Não há estação de ônibus +STR_ERROR_NO_TRUCK_STATION :{WHITE}Não há estação de caminhões +STR_ERROR_NO_DOCK :{WHITE}Não há doca +STR_ERROR_NO_AIRPORT :{WHITE}Não há aeroporto/heliporto +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Não há paradas com um tipo de estrada compatível +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Não há paradas com um tipo de bonde compatível +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Não há paradas adequadas para veículos rodoviários articulados.{}Os veículos rodoviários articulados exigem uma parada drive-through, não uma parada de baia +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Este avião não pode pousar neste heliporto +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Este helicóptero não pode pousar neste aeroporto +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Não há ponto de referência ferroviário +STR_ERROR_NO_BUOY :{WHITE}Não há boia + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Impossível programar veículo... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Veículos só podem aguardar em estações diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index 0c2c1a61d839d..5dc58e1943ef6 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -200,6 +200,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA} к.с. STR_UNITS_POWER_METRIC :{COMMA} к.с. STR_UNITS_POWER_SI :{COMMA} kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}т STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA} т. STR_UNITS_WEIGHT_SHORT_SI :{COMMA} кг. @@ -375,10 +376,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Изход # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Игрови опции STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Настройки -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Настройка на ИИ програмите STR_SETTINGS_MENU_NEWGRF_SETTINGS :Newgrf настройки STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Настройки на прозрачност STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Показване имената на градовете @@ -924,36 +924,6 @@ STR_GAME_OPTIONS_CURRENCY_IRR :Ирански STR_GAME_OPTIONS_CURRENCY_NTD :Нов тайвански долар STR_GAME_OPTIONS_CURRENCY_HKD :Хонгконгски долар (HKD) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}Избор стила на имената на градовете - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :английски (оригинални) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :френски -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :германски -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :английски (допълнителни) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :латиноамерикански -STR_GAME_OPTIONS_TOWN_NAME_SILLY :глупави -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :шведски -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :холандски -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :финландски -STR_GAME_OPTIONS_TOWN_NAME_POLISH :полски -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :словашки -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :норвежки -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :унгарски -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :австрийски -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :румънски -STR_GAME_OPTIONS_TOWN_NAME_CZECH :чешки -STR_GAME_OPTIONS_TOWN_NAME_SWISS :швейцарски -STR_GAME_OPTIONS_TOWN_NAME_DANISH :датски -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :турски -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :италиански -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :каталонски - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Автозаписване STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Интервала между две автозаписваня @@ -978,12 +948,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :друго -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Интерфейс размер -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Изберете размера на интерфейс елемент за използване - -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Нормално -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Двукратно -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Четирикратно @@ -1032,8 +996,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Пре STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 лири(£) в твоята валута STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Промяна параметрите на парична единица -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Максимален брой конкуренти: {ORANGE}{COMMA} - STR_NONE :николко STR_FUNDING_ONLY :Единствено финансиране STR_MINIMAL :Минимален @@ -1083,6 +1045,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :умерен климат +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Арктичен климат +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Тропически климат +STR_CLIMATE_TOYLAND_LANDSCAPE :Земята на играчките + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :платовиден STR_TERRAIN_TYPE_FLAT :равнинен @@ -1160,6 +1128,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :дясно STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Максимален начален заем: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Максимално количество заем за компания (без отчитане на инфлацията) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Лихвен процент: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Лихвен процент на заемите; също така контролира инфлацията ако е разрешена @@ -1411,6 +1380,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :подобре STR_CONFIG_SETTING_ROAD_SIDE :Пътни превозни средства: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Изберете страна шофиране +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :ляво +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :дясно + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Завъртане на картата: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Обратрно на часовниковата стрелка @@ -1858,7 +1831,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Автомат STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Позволява на влаковете да обръщат ако са чакали твърде дълго ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(препоръчва се) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(препоръчва се) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Промяна стойноста на настройка @@ -1898,7 +1871,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Табл STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Настройки STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF настройки STR_INTRO_ONLINE_CONTENT :{BLACK}Провери онлайн съдържанието -STR_INTRO_SCRIPT_SETTINGS :{BLACK}ИИ/Игрови настройки STR_INTRO_QUIT :{BLACK}Изход STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Започни нова игра. Ctrl+Click пропуска конфигурацията на картата @@ -1918,7 +1890,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Пока STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Настройки на дисплея STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Покажи NewGRF настройки STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Провери за ново съдържание за сваляне -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Показва настройките на ИИ STR_INTRO_TOOLTIP_QUIT :{BLACK}Изход от 'OpenTTD' STR_INTRO_TRANSLATION :{BLACK}На този превод му липсват {NUM} string{P "" s}. Помогнете на OpenTTD като се запишете за преводач. Вижте readme.txt за повече информация. @@ -1947,12 +1918,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Про STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Промяна настоящата година STR_CHEAT_SETUP_PROD :{LTBLUE}Промяна на производствените стойности: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :умерен климат -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Арктичен климат -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Тропически климат -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Земята на играчките - # Livery window STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Показване на общи цветови схеми @@ -2348,6 +2313,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}наситен STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}претоварен +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Маркиране на Отбелязаната зона STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Изключен @@ -2436,8 +2403,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Увел STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Избери ЖП мост STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Избор на асфалтов мост STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Избиране на мост - натисни върху избрания от теб мост, за да се построи -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Висящ, Стоманен STR_BRIDGE_NAME_GIRDER_STEEL :Гредоред, Стоманен STR_BRIDGE_NAME_CANTILEVER_STEEL :Конзолен, Стоманен @@ -2802,16 +2767,40 @@ STR_MAPGEN_MAPSIZE :{BLACK}Разм STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Изберете големината на картата в полета. Броя на наличните полета ще е малко по-малък. STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Брой градове: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Имена на градовете +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Избор стила на имената на градовете STR_MAPGEN_DATE :{BLACK}Дата: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Брой индустрии: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Земегенератор: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Тип на терен: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Морско ниво: +STR_MAPGEN_SEA_LEVEL :{BLACK}Морско ниво: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Реки: STR_MAPGEN_SMOOTHNESS :{BLACK}Полегатост: STR_MAPGEN_VARIETY :{BLACK}Разнообразност: STR_MAPGEN_GENERATE :{WHITE}Генериране +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :английски (оригинални) +STR_MAPGEN_TOWN_NAME_FRENCH :френски +STR_MAPGEN_TOWN_NAME_GERMAN :германски +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :английски (допълнителни) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :латиноамерикански +STR_MAPGEN_TOWN_NAME_SILLY :глупави +STR_MAPGEN_TOWN_NAME_SWEDISH :шведски +STR_MAPGEN_TOWN_NAME_DUTCH :холандски +STR_MAPGEN_TOWN_NAME_FINNISH :финландски +STR_MAPGEN_TOWN_NAME_POLISH :полски +STR_MAPGEN_TOWN_NAME_SLOVAK :словашки +STR_MAPGEN_TOWN_NAME_NORWEGIAN :норвежки +STR_MAPGEN_TOWN_NAME_HUNGARIAN :унгарски +STR_MAPGEN_TOWN_NAME_AUSTRIAN :австрийски +STR_MAPGEN_TOWN_NAME_ROMANIAN :румънски +STR_MAPGEN_TOWN_NAME_CZECH :чешки +STR_MAPGEN_TOWN_NAME_SWISS :швейцарски +STR_MAPGEN_TOWN_NAME_DANISH :датски +STR_MAPGEN_TOWN_NAME_TURKISH :турски +STR_MAPGEN_TOWN_NAME_ITALIAN :италиански +STR_MAPGEN_TOWN_NAME_CATALAN :каталонски + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Краищата на картата да са: STR_MAPGEN_NORTHWEST :{BLACK}Северозапад @@ -2946,6 +2935,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Пред STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Продължи към предишен нормален sprite, Пропускайки всички псевдо/прерисувани/текстови sprite и ги облечи в края STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Показване на избрания sprite. Подредбата се пренебрегва при рисуването му. STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Преместване на sprite, променяйки X и Y координатите + +###length 2 + + STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Избери sprite STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Избери sprite от целия екран @@ -2956,7 +2949,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Внимание: {SILVER}{STRING} 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_VERSION_NUMBER :{1:STRING} няма да работи с версията на TTDPatch указана от OpenTTD. STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} е за {STRING} версията на TTD. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} е проектиран да работи с {STRING} @@ -3451,6 +3443,8 @@ STR_PURCHASE_INFO_ALL_BUT :Всичко о STR_PURCHASE_INFO_MAX_TE :{BLACK}Макс. теглеща сила: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Обхват: {GOLD}{COMMA} полета +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Списък с влакове - натисни върху влак за информация STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Списък с избор на МПС-та - натисни върху МПС за информация @@ -4078,12 +4072,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Един STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}ИИ Дебъг прозореца е на разположение само на сървъра # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}ИИ Настройки STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Иговия скрипт ще бъде зареден в следващата игра STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}ИИ-тата ще бъдат заредени в следващата игра STR_AI_CONFIG_HUMAN_PLAYER :Човешки играч STR_AI_CONFIG_RANDOM_AI :Случаен AI STR_AI_CONFIG_NONE :(нищо) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Максимален брой конкуренти: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Премести нагоре STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Премести маркирания AI нагоре в списъка @@ -4093,8 +4087,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Прем STR_AI_CONFIG_GAMESCRIPT :{SILVER}Игрови скрипт STR_AI_CONFIG_AI :{SILVER}AI-та -STR_AI_CONFIG_CHANGE :{BLACK}Избери {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :AI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Програмен език на играта STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Зареди друг скрипт @@ -4117,10 +4109,8 @@ STR_AI_LIST_CANCEL :{BLACK}Отме STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Не променяй AI -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Параметри +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Програмен език на играта STR_AI_SETTINGS_CLOSE :{BLACK}Затвори STR_AI_SETTINGS_RESET :{BLACK}Рестартиране STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4527,6 +4517,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Инте STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... машината е унищожена + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Никакви превозни средства няма да бъдат налични STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Промени своята NewGRF конфигурация STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Няма налични превозни средства все още @@ -4560,6 +4551,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Не м STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... прекалено далече от предходната цел STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... самолета няма достатъчен обхват +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Не може да добави разписание на превозно средство... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Превозни средства могат да чакат само на гари. diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index 84357953de695..18ccbb8167ce1 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}cv STR_UNITS_POWER_METRIC :{COMMA}{NBSP}cv STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}CV/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}CV/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}CV/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}CV/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}CV/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}CV/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -226,9 +236,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{G=Masculin}{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Cadena de filtrat: -STR_LIST_FILTER_OSKTITLE :{BLACK}Introdueix una cadena de filtrat -STR_LIST_FILTER_TOOLTIP :{BLACK}Introdueix una paraula clau per filtrar la llista de +STR_LIST_FILTER_TITLE :{BLACK}Filtre: +STR_LIST_FILTER_OSKTITLE :{BLACK}Introduïu una o més paraules per a filtrar la llista de +STR_LIST_FILTER_TOOLTIP :{BLACK}Introduïu una paraula clau o més per a filtrar la llista de STR_TOOLTIP_GROUP_ORDER :{BLACK}Selecciona l'agrupament de la càrrega STR_TOOLTIP_SORT_ORDER :{BLACK}Selecciona si l'ordre ha de ser descendent o ascendent @@ -377,9 +387,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Generaci STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Generació d'indústries STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Construcció de carreteres STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Construcció de vies de tramvia -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Planta arbres. Shift per sols mostrar el cost estimat. +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Planta arbres. Amb Ctrl, es selecciona una àrea diagonal. Amb Maj, no es realitza l'acció però es mostra el seu cost estimat. STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Situa un senyal -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Situa objecte. Shift per sols mostrar el cost estimat. +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Crea un objecte. Amb Ctrl, es selecciona una àrea diagonal. Amb Maj, es commuta entre construir o mostrar el cost estimat. # Scenario editor file menu ###length 7 @@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Surt # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Opcions de la partida STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Configuració -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Paràmetres dels scripts d'IA/partida +STR_SETTINGS_MENU_AI_SETTINGS :Configuració de la IA +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Configuració de l'script de partida STR_SETTINGS_MENU_NEWGRF_SETTINGS :Extensions NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opcions de transparència STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Mostra els noms de les poblacions @@ -966,36 +977,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rúpia índia ( STR_GAME_OPTIONS_CURRENCY_IDR :Rupia indonèsia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Conducció per l'esquerra -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Conducció per la dreta - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Estil dels noms de les poblacions: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Selecciona l'estil dels noms de poblacions - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Anglès -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francès -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Alemany -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Anglès (addicional) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Llatinoamericà -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Graciós -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Suec -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holandès -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finès -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polonès -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Eslovac -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Noruec -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hongarès -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austríac -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romanès -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Txec -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Suís -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danès -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turc -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italià -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Català - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Desa automàticament STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selecciona l'interval de desada automàtica de la partida @@ -1028,21 +1009,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Seleccio STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Controlador actual: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Mida de la interfície -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Escull la mida dels elements de la interfície +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Mida de la interfície +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Arrossegueu el botó lliscant per a triar la mida de la interfície. Mantingueu premut Ctrl per a un ajustament contigu. +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Detecta la mida automàticament +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marqueu aquesta opció si voleu que s'ajusti la mida de la interfície automàticament. -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(detecta automàticament) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Doble -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quàdruple +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Escala els bisells +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marqueu aquesta opció si voleu que s'escalin els bisells segons la mida de la interfície. -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Mida de la lletra -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Seleccioneu la mida de les fonts de la interfície. - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(detecta automàticament) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Doble -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quàdruple +STR_GAME_OPTIONS_GUI_SCALE_1X :x1 +STR_GAME_OPTIONS_GUI_SCALE_2X :x2 +STR_GAME_OPTIONS_GUI_SCALE_3X :x3 +STR_GAME_OPTIONS_GUI_SCALE_4X :x4 +STR_GAME_OPTIONS_GUI_SCALE_5X :x5 STR_GAME_OPTIONS_GRAPHICS :{BLACK}Gràfics @@ -1094,8 +1073,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Vista p STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10.000 lliures (£) en aquesta moneda STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Canvia el paràmetre de la moneda personalitzada -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Nombre màxim de competidors: {ORANGE}{COMMA} - STR_NONE :Cap STR_FUNDING_ONLY :Cap, excepte finançades STR_MINIMAL :Mínim @@ -1145,6 +1122,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Paisatge temperat +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Paisatge subàrtic +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Paisatge subtropical +STR_CLIMATE_TOYLAND_LANDSCAPE :Paisatge de joguines + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Molt pla STR_TERRAIN_TYPE_FLAT :Pla @@ -1164,7 +1147,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}No hi ha # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Configuració -STR_CONFIG_SETTING_FILTER_TITLE :{G=Femenin}{BLACK}Cadena de filtrat: +STR_CONFIG_SETTING_FILTER_TITLE :{G=Masculin}{BLACK}Filtre: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Desplega-ho tot STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Plega-ho tot STR_CONFIG_SETTING_RESET_ALL :{BLACK}Restableix tots els valors @@ -1224,6 +1207,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Dreta STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Préstec inicial màxim: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Quantitat màxima del préstec que pot demanar una companyia (sense tenir en compte la inflació) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Sense préstec {RED}Fa falta un script de partida que doni els fons inicials STR_CONFIG_SETTING_INTEREST_RATE :Taxa d'interès: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Tipus d'interès dels préstecs; també controla la inflació, si està activada @@ -1450,6 +1436,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Gruix de la lí STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Mostra el nom del NewGRF a la finestra de construcció de vehicles: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Afegeix una línia a la finestra de construcció de vehicles que mostri de quin NewGRF és el vehicle seleccionat. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Mostra les càrregues que poden portar els vehicles a les finestres de llistes {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Si s'activa, la càrrega transportable del vehicle apareixerà al damunt de les llistes dels vehicles. STR_CONFIG_SETTING_LANDSCAPE :Paisatge: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :El tipus de paisatge defineix escenaris amb diferents tipus de càrrega i requisits per al creixement de les poblacions. Els NewGRF i l'script de partida poden modificar-ne l'aparença i el comportament. @@ -1504,6 +1492,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Millorat STR_CONFIG_SETTING_ROAD_SIDE :Automòbils: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Escollir el costat de conducció +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Conducció per l'esquerra +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Conducció per la dreta + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotació del mapa d'alçades: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Antihorari @@ -1937,13 +1929,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Empra {STRING}{ STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Temps dedicat a cada recàlcul d'un component del graf de connexions. Quan un recàlcul s'inicia, el programa crea un fil que pot executar-se durant aquest nombre de dies. Com més curt el valor, més probable que el fil no hagi acabat quan s'espera. Aleshores el programa s'atura fins que el fil acaba ("ralentització"). Com més llarg el valor, més temps requereix l'actualització de la distribució quan les rutes canvien. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Mode de distribució per passatgers: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"simètric" vol dir que aproximadament el mateix nombre de passatgers aniran des de l'estació A a la B que de B a A. "asimètric" significa que un nombre arbitrari de passatgers poden anar en qualsevol dels dos sentits. "manual" vol dir que no s'aplicarà una distribució automàtica pels passatgers. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simètric" vol dir que aproximadament el mateix nombre de passatgers aniran des de l'estació A a la B que de B a A. "Asimètric" significa que un nombre arbitrari de passatgers poden anar en qualsevol dels dos sentits. "Manual" vol dir que no s'aplicarà una distribució automàtica pels passatgers. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Mode de distribució pel correu: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"simètric" vol dir que aproximadament la mateixa quantitat de correu serà enviada des de l'estació A a la B que de B a A. "asimètric" significa que una quantitat arbitrària de correu pot ser enviada en qualsevol dels dos sentits. "manual" vol dir que no s'aplicarà una distribució automàtica pel correu. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Simètric" vol dir que aproximadament la mateixa quantitat de correu serà enviada des de l'estació A a la B que de B a A. "Asimètric" significa que una quantitat arbitrària de correu pot ser enviada en qualsevol dels dos sentits. "Manual" vol dir que no s'aplicarà una distribució automàtica pel correu. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Mode de distribució per la classe de càrrega BLINDADA: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La classe de càrrega BLINDADA conté objectes de valor a la zona temperada, diamants a la subtropical o or al clima subàrtic. Els NewGRF poden canviar això. "simètric" significa que aproximadament la mateixa quantitat d'aquesta càrrega s'enviarà de l'estació A a la B que de B a A. "asimètric" vol dir que quantitats arbitràries d'aquesta càrrega poden ser enviades en qualsevol sentit. "manual" significa que no s'aplicarà cap distribució automàtica a aquesta càrrega. Es recomana indicar asimètric o manual en clima subàrtic, doncs els bancs no enviaran or de tornada a les mines. Pels climes temperat i subtropical podeu també seleccionar simètric, doncs els bancs enviaran objectes de valor de tornada al banc d'origen. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La classe de càrrega BLINDADA conté objectes de valor a la zona temperada, diamants a la subtropical o or al clima subàrtic. Els NewGRF poden canviar això. "Simètric" significa que aproximadament la mateixa quantitat d'aquesta càrrega s'enviarà de l'estació A a la B que de B a A. "Asimètric" vol dir que quantitats arbitràries d'aquesta càrrega poden ser enviades en qualsevol sentit. "Manual" significa que no s'aplicarà cap distribució automàtica a aquesta càrrega. Es recomana indicar asimètric o manual en clima subàrtic, doncs els bancs no enviaran or de tornada a les mines. Pels climes temperat i subtropical també podeu seleccionar simètric, doncs els bancs enviaran objectes de valor de tornada al banc d'origen. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Mode de distribució per altres classes de càrrega: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asimètric" vol dir que quantitats arbitràries de càrrega poden ser enviades en qualsevol sentit. "manual" significa que no s'aplicarà cap distribució automàtica a aquestes càrregues. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimètric" vol dir que quantitats arbitràries de càrrega poden ser enviades en qualsevol sentit. "Manual" significa que no s'aplicarà cap distribució automàtica a aquestes càrregues. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimètric @@ -2038,7 +2030,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Canvi de sentit STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Permetre als trens girar en un senyal, si esperaven allà durant molt temps ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomanat) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recomanat) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Canvia el valor de l'ajustament @@ -2081,7 +2073,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Taula de STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Configuració STR_INTRO_NEWGRF_SETTINGS :{BLACK}Extensions NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Contingut en línia -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Paràmetres dels scripts d'IA/partida +STR_INTRO_AI_SETTINGS :{BLACK}Configuració de la IA +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Configuració de l'script de partida STR_INTRO_QUIT :{BLACK}Surt STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Comença una partida nova. Ctrl+Clic salta la configuració del mapa @@ -2101,7 +2094,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Mostra l STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Mostra la finestra de configuració STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Mostra la configuració de les extensions NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Comprova si hi ha continguts nous i actualitzats per a descarregar -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Mostra els paràmetres dels scripts d'IA/partida +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Mostra les opcions d'IA +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Mostra la configuració de l'script de partida STR_INTRO_TOOLTIP_QUIT :{BLACK}Surt de l'OpenTTD. STR_INTRO_BASESET :{WHITE}Al joc de gràfics base seleccionat li falten {NUM} sprite{P "" s}.{}Si us plau, comproveu si hi ha actualitzacions disponibles. @@ -2133,12 +2127,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Canvia STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Canvia l'any actual STR_CHEAT_SETUP_PROD :{LTBLUE}Activa la modificació dels valors de producció: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Paisatge temperat -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Paisatge subàrtic -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Paisatge subtropical -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Paisatge de joguines - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Esquema de colors nou @@ -2371,7 +2359,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Companyia nova STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Crea una companyia nova i uniu-vos. STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Aquest ets tu. STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Aquest és l'hoste de la partida. -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} companyi{P a es} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} - {NUM}/{NUM} companyi{P a es} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}El nombre de clients connectats actualment, el nombre de companyies i el nombre màxim de companyies permeses per l'administrador del servidor. # Matches ConnectionType ###length 5 @@ -2498,13 +2487,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :s'espera que s' STR_NETWORK_MESSAGE_CLIENT_LEAVING :deixant STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} s'ha unit a la partida -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} s'ha unit a la partida (Client #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} s'ha unit a la companyia #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} s'ha unit a la partida (Client #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} s'ha unit a la companyia #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} s'ha unit als espectadors -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} ha començat una nova companyia (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} ha deixat la partida ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} ha començat una nova companyia (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} ha deixat la partida ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} ha canviat el seu nom a {STRING}. -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} ha donat {2:CURRENCY_LONG} a {1:STRING}. +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} ha donat {2:CURRENCY_LONG} a {1:STRING}. STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}El servidor ha tancat la sessió STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}El servidor està reiniciant...{}Espera un moment... STR_NETWORK_MESSAGE_KICKED :*** S'ha expulsat {STRING}. Motiu: {STRING} @@ -2618,6 +2607,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{G=Masculin}{TI STR_LINKGRAPH_LEGEND_SATURATED :{G=Masculin}{TINY_FONT}{BLACK}saturat STR_LINKGRAPH_LEGEND_OVERLOADED :{G=Masculin}{TINY_FONT}{BLACK}sobrecarregat +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} a transportar cada mes de {STATION} a {STATION} ({COMMA}{NBSP}% de capacitat){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} per a transportar de tornada ({COMMA}{NBSP}% de capacitat) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Temps de viatge mitjà: {NUM}{NBSP}di{P a es} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Marca l'àrea de cobertura STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Inactiu @@ -2626,6 +2620,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}No marca STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Marcar l'àrea de cobertura del lloc proposat STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Accepta: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Provisions: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Cost de manteniment: {GOLD}{CURRENCY_SHORT}/any # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Ajuntar estació @@ -2708,8 +2703,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Augmenta STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Selecciona Pont de Tren STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Selecciona Pont de Carretera STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Selecció de pont - clica sobre el pont triat per construir-lo -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Pont penjant d'acer STR_BRIDGE_NAME_GIRDER_STEEL :Pont biga d'acer STR_BRIDGE_NAME_CANTILEVER_STEEL :Pont en mènsula d'acer @@ -2813,11 +2810,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Creació STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Rebaixa una cantonada del terreny. Arrossegant rebaixa la primera cantonada seleccionada i anivella l'àrea seleccionada a la nova alçada de la cantonada. Ctrl selecciona l'àrea diagonalment. Shift commuta construeix/mostra el cost estimat STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Eleva una cantonada del terreny. Arrossegant eleva la primera cantonada selecciona i anivella l'àrea a la nova alçada de la cantonada. Ctrl selecciona l'àrea diagonalment. Shift commuta construeix/mostra el cost estimat STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Anivella el terreny a l'alçada de la primera cantonada seleccionada. Ctrl selecciona l'àrea diagonalment. Shift commuta construeix/mostra el cost estimat -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Compra un terreny per un ús posterior. Shift commuta construeix/mostra el cost estimat +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Compra terreny per a fer-lo servir més endavant. Amb Ctrl, es selecciona una àrea diagonal. Maj commuta entre construir i mostrar el cost estimat. # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Selecció d'objecte -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selecciona l'objecte a construir. Shift commuta construeix/mostra el cost estimat +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Seleccioneu l'objecte a construir. Amb Ctrl, es selecciona una àrea diagonal. Amb Maj, es commuta entre construir i mostrar el cost estimat. STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Selecciona la classe d'objecte a construir STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Previsualització de l'objecte STR_OBJECT_BUILD_SIZE :{BLACK}Mida: {GOLD}{NUM} x {NUM} cel·les @@ -2829,7 +2826,7 @@ STR_OBJECT_CLASS_TRNS :Transmissors STR_PLANT_TREE_CAPTION :{WHITE}Arbres STR_PLANT_TREE_TOOLTIP :{BLACK}Selecciona el tipus d'arbre a plantar. Si la casella ja conté un arbre, s'afegiran més arbres d'altres espècies independentment de quin estigui seleccionat STR_TREES_RANDOM_TYPE :{BLACK}Arbres de tipus aleatori -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Situar arbres de tipus aleatori. Shift commuta construeix/mostra el cost estimat +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Situa arbres de tipus aleatori. Amb Ctrl, es selecciona una àrea diagonal. Amb Maj., es commuta entre construir i mostrar el cost estimat. STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Planta arbres STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Planta arbres aleatòriament al paisatge STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2861,6 +2858,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Crea una STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Funda una població en un lloc aleatori STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Crea moltes poblacions aleatòries STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Omple el mapa amb poblacions situades aleatòriament +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Expandeix totes les poblacions +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Fes que totes les poblacions creixin una mica. STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nom de la població nova: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Introdueix el nom de la població @@ -2998,7 +2997,7 @@ STR_LAI_TREE_NAME_CACTUS_PLANTS :Plantes de Cact STR_LAI_STATION_DESCRIPTION_RAILROAD_STATION :Estació de Ferrocarril STR_LAI_STATION_DESCRIPTION_AIRCRAFT_HANGAR :Hangar d'Avions STR_LAI_STATION_DESCRIPTION_AIRPORT :Aeroport -STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Àrea de càrrega de camions +STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Moll de càrrega de camions STR_LAI_STATION_DESCRIPTION_BUS_STATION :Parada d'autobús STR_LAI_STATION_DESCRIPTION_SHIP_DOCK :Moll per vaixells STR_LAI_STATION_DESCRIPTION_BUOY :Boia @@ -3125,7 +3124,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalls STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No hi ha informació disponible STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Cadena de filtre: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtre: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Sobreescriu fitxer STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Esteu segur que voleu sobreescriure el fitxer? STR_SAVELOAD_DIRECTORY :{STRING} (carpeta) @@ -3139,6 +3138,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Mida del STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Selecciona la mida del mapa en cel·les. El nombre de cel·les disponibles serà lleugerament més petit STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Nombre de poblacions: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Estil dels noms de les poblacions: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Selecciona l'estil dels noms de poblacions STR_MAPGEN_DATE :{BLACK}Data: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Nombre d'indústries: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Alçada del cim més alt: @@ -3152,13 +3153,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Proporci STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Augmenta un 10 % la proporció de terreny desèrtic STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Redueix un 10 % la proporció de terreny desèrtic STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}{NBSP}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Generació de terrenys: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tipus de terreny: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Nivell de mar: +STR_MAPGEN_SEA_LEVEL :{BLACK}Nivell de mar: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Quantitat de rius: STR_MAPGEN_SMOOTHNESS :{BLACK}Suavitat: STR_MAPGEN_VARIETY :{BLACK}Varietat: STR_MAPGEN_GENERATE :{WHITE}Genera +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Configuració del NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Mostra la configuració de NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Configuració d'IA +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Mostra la configuració de la IA +STR_MAPGEN_GS_SETTINGS :{BLACK}Configuració de l'script de partida +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Mostra la configuració de l'script de partida. + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Anglès +STR_MAPGEN_TOWN_NAME_FRENCH :Francès +STR_MAPGEN_TOWN_NAME_GERMAN :Alemany +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Anglès (addicional) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Llatinoamericà +STR_MAPGEN_TOWN_NAME_SILLY :Graciós +STR_MAPGEN_TOWN_NAME_SWEDISH :Suec +STR_MAPGEN_TOWN_NAME_DUTCH :Holandès +STR_MAPGEN_TOWN_NAME_FINNISH :Finès +STR_MAPGEN_TOWN_NAME_POLISH :Polonès +STR_MAPGEN_TOWN_NAME_SLOVAK :Eslovac +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Noruec +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hongarès +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austríac +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romanès +STR_MAPGEN_TOWN_NAME_CZECH :Txec +STR_MAPGEN_TOWN_NAME_SWISS :Suís +STR_MAPGEN_TOWN_NAME_DANISH :Danès +STR_MAPGEN_TOWN_NAME_TURKISH :Turc +STR_MAPGEN_TOWN_NAME_ITALIAN :Italià +STR_MAPGEN_TOWN_NAME_CATALAN :Català # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Vores del mapa: @@ -3217,7 +3246,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Informac STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Arxius NewGRF actius STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Arxius NewGRF inactius STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Selecciona configuració: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Cadena de filtre: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtre: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Carrega la predefinició seleccionada STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Desa configuració STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Desa la llista actual com a predefinició @@ -3304,6 +3333,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Sprite a STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Procedeix cap a l'sprite normal anterior, saltant qualsevol sprite pseudo/recolor/font i passant del primer sprite a l'últim STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representació de l'sprite seleccionat actualment. L'alineació s'ignora quan es dibuixa aquest sprite STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Desplaça l'sprite un píxel en el sentit indicat. Amb Ctrl+Clic el desplaça 8 píxels. + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Modificador centrat +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centrat + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Punt de mira + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Restableix relatius STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Restableix els desplaçaments relatius actuals STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Desplaçament X: {NUM}, Desplaçament Y: {NUM} (Absolut) @@ -3318,18 +3354,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Alerta: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Error: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}S'ha produït un error fatal de NewGRF:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}S'ha produït un error relacionat amb els NewGRF:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}El NewGRF "{STRING}" ha retornat un error fatal:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}El NewGRF "{STRING}" ha retornat un error:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} no funcionarà amb la versió TTDPatch informada per l'OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} és per la versió {STRING} de TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} està dissenyat per ser utilitzat amb {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Paràmetre invàlid per {1:STRING}: paràmetre {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} ha de ser carregat abans de {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} ha de ser carregat després de {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} necessita l'OpenTTD versió {STRING} o superior +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} és per a la versió {2:STRING} del TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} està dissenyat per a fer-se servir amb {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Paràmetre no vàlid per a {1:STRING}: paràmetre {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} s'ha de carregar abans de {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} s'ha de carregar després de {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} necessita la versió {2:STRING} de l'OpenTTD o posterior STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :l'arxiu GRF dissenyat està pendent de traduir STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Hi ha massa arxius NewGRF carregats -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Carregant {1:STRING} com a NewGRF estàtic amb {STRING} podria causar desincronitzacions +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Si es carrega {1:STRING} com a NewGRF estàtic amb {2:STRING}, pot provocar desincronitzacions STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Sprite inesperat (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Propietat d'acció 0 desconeguda {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Intent d'utilitzar una ID invàlid (sprite {3:NUM}) @@ -3461,14 +3497,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Compra els dret STR_LOCAL_AUTHORITY_ACTION_BRIBE :Suborna les autoritats locals ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Inicia una petita campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins d'un radi petit al voltant del centre de la població.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Inicia una mitjana campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins un radi mitjà al voltant del centre de la població.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Inicia una gran campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins d'un radi gran al voltant del centre de la població.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Finança la reconstrucció de la xarxa local de carrers. Dificulta notablement el trànsit durant 6 mesos.{}Causa molèsties considerables al trànsit de vehicles de carretera durant 6 mesos.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Construeix una estàtua en honor a la teva companyia.{}Proporciona una millora permanent dels ratis d'estació de la població.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Finança la construcció de nous edificis comercials a la població.{}Proporciona una millora temporal del creixement d'aquesta població.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Compra per 1 any els drets exclusius de transport en la població. L'autoritat local només permetrà utilitzar les instal·lacions de la teva companyia de transports als passatgers i les mercaderies.{}L'autoritat local no permetrà que els passatgers i càrregues locals usin les estacions dels oponents.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Suborna les autoritats locals per incrementar el teu rati, a risc de greus penalitzacions si et pesquen.{}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inicia una petita campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins d'un radi petit al voltant del centre de la població.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inicia una mitjana campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins un radi mitjà al voltant del centre de la població.{}{PUSH_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inicia una gran campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins d'un radi gran al voltant del centre de la població.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Finança la reconstrucció de la xarxa local de carrers. Dificulta notablement el trànsit durant 6 mesos.{}Causa molèsties considerables al trànsit de vehicles de carretera durant 6 mesos.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Construeix una estàtua en honor a la teva companyia.{}Proporciona una millora permanent dels ratis d'estació de la població.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Finança la construcció de nous edificis comercials a la població.{}Proporciona una millora temporal del creixement d'aquesta població.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Compra per 1 any els drets exclusius de transport en la població. L'autoritat local només permetrà utilitzar les instal·lacions de la teva companyia de transports als passatgers i les mercaderies.{}L'autoritat local no permetrà que els passatgers i càrregues locals usin les estacions dels oponents.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Suborna les autoritats locals per incrementar el teu rati, a risc de greus penalitzacions si et pesquen.{}{POP_COLOUR}Cost: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Objectius @@ -3641,15 +3677,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Vaixells STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Interessos del préstec STR_FINANCES_SECTION_OTHER :{GOLD}Altres +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Benefici net +STR_FINANCES_PROFIT :{WHITE}Benefici STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Balanç bancari STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Fons propis STR_FINANCES_LOAN_TITLE :{WHITE}Préstec STR_FINANCES_INTEREST_RATE :{WHITE}Interès del préstec: {BLACK}{NUM}{NBSP}% STR_FINANCES_MAX_LOAN :{WHITE}Préstec màxim: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Demana {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Augmenta l'import del préstec Ctrl+Clic per demanar tants diners com sigui possible STR_FINANCES_REPAY_BUTTON :{BLACK}Amortitza {CURRENCY_LONG} @@ -3750,7 +3789,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produeix STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Necessita: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} esperant{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Canvia la producció (múltiple de 8, fins a 2040) @@ -3780,6 +3819,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Envia in STR_VEHICLE_LIST_REPLACE_VEHICLES :Substitueix vehicles STR_VEHICLE_LIST_SEND_FOR_SERVICING :Envia a fer revisió STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Benefici enguany: {CURRENCY_LONG} (darrer any: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Envia a la cotxera STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Envia a la cotxera @@ -3871,6 +3912,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Esforç STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Abast: {GOLD}{COMMA} cel·les STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipus d'aeronau: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Tots els tipus de càrrega +STR_CARGO_TYPE_FILTER_FREIGHT :Càrrega +STR_CARGO_TYPE_FILTER_NONE :Cap + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Llista de selecció de trens i vagons. Clica al vehicle per més informació. Ctrl+Click per a alternar entre mostrar/ocultar el vehicle ferroviari STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Llista de models de vehicles de carretera. Clica sobre el model per més informació. Amb Ctrl+Clic, commuta entre mostrar o ocultar el model. @@ -4039,7 +4085,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :{G=Masculin}avi STR_ENGINE_PREVIEW_SHIP :{G=Masculin}vaixell STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cost: {CURRENCY_LONG} Pes: {WEIGHT_SHORT}{}Velocitat: {VELOCITY} Potència: {POWER}{}Cost de circulació: {CURRENCY_LONG}/any{}Capacitat: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {CURRENCY_LONG} Pes: {WEIGHT_SHORT}{}Velocitat: {VELOCITY} Potència: {POWER} Màx. E.T.: {6:FORCE}{}Cost d'utilització: {4:CURRENCY_LONG}/any{}Capacitat: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {0:CURRENCY_LONG} Pes: {1:WEIGHT_SHORT}{}Velocitat: {2:VELOCITY} Potència: {3:POWER} Màx. E.T.: {6:FORCE}{}Cost d'utilització: {4:CURRENCY_LONG}/any{}Capacitat: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Vel. Màx: {VELOCITY}{}Capacitat: {CARGO_LONG}{}Cost d'utilització: {CURRENCY_LONG}/any STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Velocitat màx.: {VELOCITY}{}Tipus d'aeronau: {STRING}{}Capacitat: {CARGO_LONG}, {CARGO_LONG}{}Cost de circulació: {CURRENCY_LONG} per any STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Velocitat màx.: {VELOCITY}{}Tipus d'aeronau: {STRING}{}Capacitat: {CARGO_LONG}{}Cost de circulació: {CURRENCY_LONG} per any @@ -4198,12 +4244,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Pes: {LT STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Pes: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potència: {LTBLUE}{POWER}{BLACK} Vel. màx: {LTBLUE}{VELOCITY} {BLACK}E.T. màx.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Benefici d'aquest any: {LTBLUE}{CURRENCY_LONG} (darrer any: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Benefici aquest any: {LTBLUE}{CURRENCY_LONG} (l'any passat: {CURRENCY_LONG}) {BLACK}Rendiment mínim: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilitat: {LTBLUE}{COMMA}% {BLACK}Avaries des de la darrera revisió: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Fabricat: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacitat: {LTBLUE}Cap{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacitat: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacitat: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacitat: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacitat: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacitat: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transferir crèdits: {LTBLUE}{CURRENCY_LONG} @@ -4472,22 +4519,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Data de STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Seleccioneu una data com a punt de partida d'aquest horari. Amb Ctrl+Clic, distribueix els vehicles que comparteixen aquesta ruta a partir de la data establerta i la seva ordre relativa, sempre que la ruta tingui l'horari complet. STR_TIMETABLE_CHANGE_TIME :{BLACK}Canvia Temps -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Canvia la quantitat de temps que l'ordre marcada hauria de prendre +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Canvia el emps que l'ordre marcada hauria de prendre. Amb Ctrl+clic estableix el temps per a totes les ordres. STR_TIMETABLE_CLEAR_TIME :{BLACK}Esborra Temps -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Esborra la quantitat de temps de l'ordre marcada +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Esborra la quantitat de temps de l'ordre marcada. Amb Ctrl+clic, s'esborra el temps per a totes les ordres. STR_TIMETABLE_CHANGE_SPEED :{BLACK}Canvia el límit de velocitat -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Canvia la velocitat de viatge màxima de l'ordre seleccionada +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Canvia la velocitat de viatge màxima de l'ordre seleccionada. Amb Ctrl+clic s'estableix la velocitat per a totes les ordres. STR_TIMETABLE_CLEAR_SPEED :{BLACK}Esborra el límit de velocitat -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Esborra la velocitat de viatge màxima de l'ordre seleccionada +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Esborra la velocitat de viatge màxima de l'ordre seleccionada. Amb Ctrl+clic s'esborra la velocitat per a totes les ordres. STR_TIMETABLE_RESET_LATENESS :{BLACK}Restablir Retard -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Restableix el comptador de retards, de manera que el vehicle serà puntual +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Restableix el comptador de retards, de manera que el vehicle serà puntual. Amb Ctrl+clic, es restableix el grup sencer de manera que el vehicle més endarrerit passa a anar a hora i els altres arribaran abans d'hora. STR_TIMETABLE_AUTOFILL :{BLACK}Autoomple -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Omple automàticament l'horari amb valors del proper viatge (CTRL+clic per intentar mantenir els temps d'espera) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Omple automàticament l'horari amb valors del proper viatge. CTRL+clic per a intentar mantenir els temps d'espera. STR_TIMETABLE_EXPECTED :{BLACK}Esperat STR_TIMETABLE_SCHEDULED :{BLACK}Planificat @@ -4531,12 +4578,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Un dels STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}La finestra de depuració dels scripts d'IA/partida només està disponible al servidor. # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Configuració dels scripts de les IA/partida +STR_AI_CONFIG_CAPTION_AI :{WHITE}Configuració de la IA +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Configuració de l'script de partida STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Aquest és l'script que s'usarà a la propera partida. STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Aquesta llista conté les IA que es carregaran a la propera partida. STR_AI_CONFIG_HUMAN_PLAYER :Jugador humà STR_AI_CONFIG_RANDOM_AI :IA aleatòria STR_AI_CONFIG_NONE :(cap) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Nombre màxim de competidors: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Mou amunt STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Desplaça la IA seleccionada una posició cap amunt @@ -4544,12 +4593,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Mou aval STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Desplaça la IA seleccionada una posició cap avall. STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script de partida +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Paràmetres STR_AI_CONFIG_AI :{SILVER}IA -STR_AI_CONFIG_CHANGE :{BLACK}Selecciona {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :una IA -STR_AI_CONFIG_CHANGE_GAMESCRIPT :un script de partida +STR_AI_CONFIG_CHANGE_AI :{BLACK}Trieu una IA +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Tria un script de partida STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carrega un altre script STR_AI_CONFIG_CONFIGURE :{BLACK}Configura STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configura els paràmetres de l'script @@ -4577,10 +4625,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Captura STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Captura de pantalla del mapa d'alçades STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Captura de pantalla del minimapa -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}Paràmetres {STRING} -STR_AI_SETTINGS_CAPTION_AI :de la IA -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :de l'script de partida +# Script Parameters +STR_AI_SETTINGS_CAPTION :{WHITE}{STRING}Paràmetres +STR_AI_SETTINGS_CAPTION_AI :IA +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script de la partida STR_AI_SETTINGS_CLOSE :{BLACK}Tanca STR_AI_SETTINGS_RESET :{BLACK}Restableix STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4744,6 +4792,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... mass STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}No es poden generar indústries... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Aquí no es pot construir {STRING}... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Aquí no es pot construir aquest tipus d'indústria... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}No es pot fer la prospecció per a la indústria... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... massa prop d'altres indústries STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}...abans s'ha de fundar una població. STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... només un permès per població @@ -4758,6 +4807,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... el b STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... només es pot construir en estatges amb neu STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... només es pot construir en estatges sense neu +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}La fundació ha fallat la prospecció per mala sort. Proveu-ho de nou. +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}No hi havia llocs apropiats per a fer la prospecció per a aquesta indústria. STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}No hi havia llocs adequats per a indústries '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Canvia els paràmetres de generació de mapa per a obtenir-ne un de millor @@ -4925,6 +4976,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objecte STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... seu de la companyia en el camí STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}No pots comprar aquesta àrea de terreny... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... ja és propietat teva! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... s'ha assolit el límit de construcció d'objectes. # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}No es pot crear el grup... @@ -4997,6 +5049,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}No es po STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vehicle està destruït +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... no tots els vehicles són idèntics. + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}No hi haurà cap vehicle disponible STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Canvia la teva configuració dels NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Encara no hi ha vehicles disponibles @@ -5023,6 +5077,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Impossib STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... el vehicle no pot anar a totes les estacions STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... el vehicle no pot anar a aquesta estació STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... un vehicle que comparteix aquesta ordre no pot anar a aquesta estació +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... no tots els vehicles tenen les mateixes ordres. +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... no tots els vehicles comparteixen ordres. STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}No es pot compartir la llista d'ordres... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}No es pot deixar de compartir la llista d'ordres... @@ -5030,6 +5086,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}No es po STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... massa lluny del destí previ STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... l'avió no té prou autonomia +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}No hi ha cap estació ferroviària +STR_ERROR_NO_BUS_STATION :{WHITE}No hi ha cap estació d'autobusos +STR_ERROR_NO_TRUCK_STATION :{WHITE}No hi ha cap estació de camions +STR_ERROR_NO_DOCK :{WHITE}No hi ha cap port +STR_ERROR_NO_AIRPORT :{WHITE}No hi ha cap aeroport/heliport +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}No hi ha parades amb un tipus de carretera compatible +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}No hi ha parades amb un tipus de tramvia compatible +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}No hi ha parades que siguin adequades per a vehicles de carretera articulats.{}Aquest tipus de vehicles necessiten una estació de pas, no pas una estació final +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}L'avió no pot aterrar en aquest aeroport +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}L'helicòpter no pot aterrar en aquest aeroport +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}No hi ha cap punt de pas ferroviari +STR_ERROR_NO_BUOY :{WHITE}No hi ha cap boia + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Impossible establir l'horari del vehicle... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Els vehicles només poden esperar a les estacions diff --git a/src/lang/chuvash.txt b/src/lang/chuvash.txt index ba711623024b0..403d4c98318bc 100644 --- a/src/lang/chuvash.txt +++ b/src/lang/chuvash.txt @@ -163,6 +163,7 @@ STR_UNITS_POWER_SI :{COMMA}кВт + # Common window strings @@ -225,7 +226,7 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Вӗҫле # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Вӑййи майлаштару STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF майлаштару @@ -484,30 +485,6 @@ STR_NEWS_MESSAGE_CAPTION :{WHITE}Пӗлт ###length 42 STR_GAME_OPTIONS_CURRENCY_RUR :Вырӑсла тенкӗ (RUR) -###length 2 - - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Акӑлчан -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Францири -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Нимӗҫ -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Акӑлчан (Хушма) -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Акӑлчан (Кулӑшма) -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Шведла -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Голланд -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Финла -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Поляк -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Словак -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Венгрла -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Австри -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Рим -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Чехла -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Швеци -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Датчан -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Турккӑла -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Итали -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Катталун - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Хӑй управ # Autosave dropdown @@ -533,7 +510,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :расна - # Custom currency window @@ -544,7 +520,6 @@ STR_CURRENCY_SUFFIX :{LTBLUE}Суф STR_CURRENCY_PREVIEW :{LTBLUE}Малтанласа пӑхса тухни: {ORANGE}{CURRENCY_LONG} - STR_NONE :Ҫук STR_NUM_CUSTOM :Харпӑр хӑй STR_NUM_CUSTOM_NUMBER :Харпӑр хӑй ({NUM}) @@ -568,6 +543,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Виҫеллӗ климат +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Сивӗ климат +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Тропик климат +STR_CLIMATE_TOYLAND_LANDSCAPE :Вӑйӑ пахчи + ###length 7 ###length 4 @@ -597,6 +578,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_LEFT :Сулахай STR_CONFIG_SETTING_HORIZONTAL_POS_CENTER :Варринче STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Сылтӑмра +###setting-zero-is-special @@ -696,6 +678,8 @@ STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :Чӑн ###length 2 +###length 2 + @@ -891,12 +875,6 @@ STR_ABANDON_GAME_CAPTION :{WHITE}Вӑйй # Cheat window STR_CHEAT_CHANGE_DATE :{LTBLUE}Тӳрлет кун: {ORANGE}{DATE_SHORT} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Виҫеллӗ климат -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Сивӗ климат -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Тропик климат -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Вӑйӑ пахчи - # Livery window @@ -1056,6 +1034,8 @@ STR_CONTENT_DETAIL_VERSION :{SILVER}Вер # Linkgraph legend window and linkgraph legend in smallmap +# Linkgraph tooltip + # Base for station construction window(s) # Join station window @@ -1206,6 +1186,27 @@ STR_ABOUT_VERSION :{BLACK}OpenTTD STR_MAPGEN_MAPSIZE :{BLACK}Виҫа картти: STR_MAPGEN_BY :{BLACK}* +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Акӑлчан +STR_MAPGEN_TOWN_NAME_FRENCH :Францири +STR_MAPGEN_TOWN_NAME_GERMAN :Нимӗҫ +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Акӑлчан (Хушма) +STR_MAPGEN_TOWN_NAME_SILLY :Акӑлчан (Кулӑшма) +STR_MAPGEN_TOWN_NAME_SWEDISH :Шведла +STR_MAPGEN_TOWN_NAME_DUTCH :Голланд +STR_MAPGEN_TOWN_NAME_FINNISH :Финла +STR_MAPGEN_TOWN_NAME_POLISH :Поляк +STR_MAPGEN_TOWN_NAME_SLOVAK :Словак +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Венгрла +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Австри +STR_MAPGEN_TOWN_NAME_ROMANIAN :Рим +STR_MAPGEN_TOWN_NAME_CZECH :Чехла +STR_MAPGEN_TOWN_NAME_SWISS :Швеци +STR_MAPGEN_TOWN_NAME_DANISH :Датчан +STR_MAPGEN_TOWN_NAME_TURKISH :Турккӑла +STR_MAPGEN_TOWN_NAME_ITALIAN :Итали +STR_MAPGEN_TOWN_NAME_CATALAN :Катталун + # Strings for map borders at game generation @@ -1239,6 +1240,10 @@ STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT :Объект # Sprite aligner window +###length 2 + + + # NewGRF (self) generated warnings/errors STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING} @@ -1378,6 +1383,8 @@ STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ҫу ###length VEHICLE_TYPES +###length 3 + ###length VEHICLE_TYPES ###length VEHICLE_TYPES @@ -1578,7 +1585,6 @@ STR_ORDER_GO_TO_STATION :{STRING} {STATI -STR_AI_CONFIG_CHANGE_NONE : # Available AIs window @@ -1586,7 +1592,7 @@ STR_AI_LIST_VERSION :{LTBLUE}Вер -# AI Parameters +# Script Parameters STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -1694,6 +1700,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Ҫул + # Specific vehicle errors @@ -1701,6 +1708,8 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Ҫул # Order related errors +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors # Sign related errors diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index 32c4c74ac2b87..3e580b31ccfff 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -295,6 +295,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}KS STR_UNITS_POWER_METRIC :{COMMA}{NBSP}KS STR_UNITS_POWER_SI :{COMMA}{NBSP}kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -480,10 +481,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Izlaz # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Postavke igre STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Postavke -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Postavke UI-ja/Skripte igre STR_SETTINGS_MENU_NEWGRF_SETTINGS :Postavke za NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Postavke prozirnosti STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Prikaži imena gradova @@ -1045,36 +1045,6 @@ STR_GAME_OPTIONS_CURRENCY_CNY :Kineski Renminb STR_GAME_OPTIONS_CURRENCY_HKD :Hongkonški Dolar (HKD) STR_GAME_OPTIONS_CURRENCY_INR :Indijska Rupija (INR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Vozi na lijevoj strani -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Vozi na desnoj strani - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Imena gradova: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Odaberi stil za imena gradova - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Engleski (original) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francuski -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Njemački -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Engleski (dodatno) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latinoamerički -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Blesavo -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Švedski -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Nizozemski -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finski -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Poljski -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovački -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norveški -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Mađarski -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austrijski -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumunjski -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Češki -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Švicarski -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danski -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turski -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Talijanski -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalonski - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatsko spremanje STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Odaberi interval između automatskih spremanja igre @@ -1101,19 +1071,8 @@ STR_GAME_OPTIONS_RESOLUTION_ITEM :{NUM}x{NUM} STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Veličina sučelja -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Odaberite koju ćete veličinu elementa sučelja koristiti -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normalno -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dvostruka veličina -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Četvorostruka veličina -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Veličina fonta -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Odaberite veličinu fonta za sučelje - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normalno -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dvostruka veličina -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Četvorostruka veličina @@ -1160,8 +1119,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Prikaz: STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 funti (£) u vašoj valuti STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Promijeni parametre proizvoljne valute -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Najveći broj natjecatelja: {ORANGE}{COMMA} - STR_NONE :Ništa STR_FUNDING_ONLY :Samo financiranje STR_MINIMAL :Najmanje @@ -1211,6 +1168,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Blagi krajolik +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subarktički krajolik +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Suptropski krajolik +STR_CLIMATE_TOYLAND_LANDSCAPE :Krajolik 'zemlja igračaka' + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Vrlo ravno STR_TERRAIN_TYPE_FLAT :Ravno @@ -1285,6 +1248,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Desno STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Najveći početni zajam: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Najveći iznos koji tvrtka može pozajmiti (ne uzimajući inflaciju u obzir) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Kamatna stopa: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Kamatna stopa zajmova; također kontrolira i inflaciju ako je uključena @@ -1553,6 +1517,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Unaprijeđen STR_CONFIG_SETTING_ROAD_SIDE :Cestovna vozila: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Odaberite stranu vožnje +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Vozi na lijevoj strani +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Vozi na desnoj strani + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotacija visinske karte: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Obrnuto od smjera kazaljke na satu @@ -2055,7 +2023,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatsko okre STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Dozvoli vlakovima okretanje kod signala ako tamo čekaju duže vrijeme ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Preporučljivo) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Preporučljivo) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Promijeni vrijednost postavke @@ -2097,7 +2065,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Tablica STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Postavke STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Postavke STR_INTRO_ONLINE_CONTENT :{BLACK}Provjeri online sadržaj -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Postavke UI-ja/Skripte igre STR_INTRO_QUIT :{BLACK}Izlaz STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Započni novu igru. Ctrl+klik preskače konfiguriranje karte @@ -2117,7 +2084,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Prikaži STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Prikaži postavke STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Prikaži postavke NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Provjeri novi i nadograđeni sadržaj za preuzimanje -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Prikaži postavke UI-ja/Skripte igre STR_INTRO_TOOLTIP_QUIT :{BLACK}Izzađi it 'OpenTTD'-a STR_INTRO_BASESET :{BLACK}Trenutno odabranom osnovnom grafičkom setu nedostaje {NUM} sprite{P "" a a}. Potražite nadogradnju grafičkog seta. @@ -2148,12 +2114,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Promije STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Promijeni tekuću godinu STR_CHEAT_SETUP_PROD :{LTBLUE}Omogući izmjeni produkcijskih vrijednosti: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Blagi krajolik -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subarktički krajolik -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Suptropski krajolik -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Krajolik 'zemlja igračaka' - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} -Boja @@ -2576,6 +2536,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}zasićen STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}prekrcan +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Označavanje područja pokrivanja STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Isključeno @@ -2664,8 +2626,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Povećaj STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Odaberi željeznički most STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Odaberi cestovni most STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Izbor mosta - klikni na most koji želiš izgraditi -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Viseći, čelični STR_BRIDGE_NAME_GIRDER_STEEL :Noseći, čelični STR_BRIDGE_NAME_CANTILEVER_STEEL :Konzolni, čelični @@ -3082,20 +3042,44 @@ STR_MAPGEN_MAPSIZE :{BLACK}Veličin STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Odaberi veličinu mape u poljima. Broj dostupnih polja biti će malo manji STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Broj gradova: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Imena gradova: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Odaberi stil za imena gradova STR_MAPGEN_DATE :{BLACK}Datum: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Broj industrija: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Najviši vrh: STR_MAPGEN_SNOW_COVERAGE_UP :{BLACK}Povećaj pokrivenost snijega za deset posto STR_MAPGEN_SNOW_COVERAGE_DOWN :{BLACK}Smanji pokrivenost snijega za deset posto STR_MAPGEN_DESERT_COVERAGE :{BLACK}Pustinjska pokrivenost: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Izrađivač zemljišta: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Vrsta terena: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Razina mora: +STR_MAPGEN_SEA_LEVEL :{BLACK}Razina mora: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Rijeke: STR_MAPGEN_SMOOTHNESS :{BLACK}Graduacija: STR_MAPGEN_VARIETY :{BLACK}Distribucija raznovrsnosti: STR_MAPGEN_GENERATE :{WHITE}Izradi +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Engleski (original) +STR_MAPGEN_TOWN_NAME_FRENCH :Francuski +STR_MAPGEN_TOWN_NAME_GERMAN :Njemački +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Engleski (dodatno) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latinoamerički +STR_MAPGEN_TOWN_NAME_SILLY :Blesavo +STR_MAPGEN_TOWN_NAME_SWEDISH :Švedski +STR_MAPGEN_TOWN_NAME_DUTCH :Nizozemski +STR_MAPGEN_TOWN_NAME_FINNISH :Finski +STR_MAPGEN_TOWN_NAME_POLISH :Poljski +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovački +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norveški +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Mađarski +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austrijski +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumunjski +STR_MAPGEN_TOWN_NAME_CZECH :Češki +STR_MAPGEN_TOWN_NAME_SWISS :Švicarski +STR_MAPGEN_TOWN_NAME_DANISH :Danski +STR_MAPGEN_TOWN_NAME_TURKISH :Turski +STR_MAPGEN_TOWN_NAME_ITALIAN :Talijanski +STR_MAPGEN_TOWN_NAME_CATALAN :Katalonski + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Rubovi Karte: STR_MAPGEN_NORTHWEST :{BLACK}Sjeverozapad @@ -3238,6 +3222,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Prethodn STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Otiđi na prethodni normalni sprite, preskačući svaki pseudo/prebojani/font sprite i {BLACK}Otiđi na sljedeći normalni sprite, preskačući svaki pseudo/prebojani/font sprite i nakon dolaska na prvi prebaci na zadnjeg STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Prikaz trenutno odabranog spritea. Poravnjanje se ignorira kod crtanja ovog spritea. STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Pomakni sprite mijenjajući X i Y pomake. Ctrl+Click za micanje po 8 jedinica odjednom. + +###length 2 + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Poništi relativne STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Poništi trenutne relativne pomake STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X pomak: {NUM}, Y pomak: {NUM} (Apsolutni) @@ -3252,7 +3240,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Upozorenje: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Greška: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Kobno: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Dogodila se kobna pogreška u NewGRF-u:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} neće raditi sa TTDPatch verzijom prijavljenom u OpenTTD STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} je za {STRING} verziju TTD-a. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} je napravljen da se koristi sa {STRING} @@ -3787,6 +3774,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK} Najveć STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Domet: {GOLD}{COMMA} polja STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Vrsta zrakoplova: {GOLD}{STRING} +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Popis vlakova za odabir. Klikni na vozilo za informacije. Ctrl+klik za uključivanje ili isključivanje prikaza vrste vozila STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Popis cestovnih vozila za odabir. Klikni na vozilo za informacije. Ctrl+klik za uključivanje ili isključivanje prikaza vrste cestovnog vozila @@ -4438,12 +4427,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Jedna od STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Prozor za debugiranje UI-ja/Skripte igre je dopušten samo za poslužitelj # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Konfiguracija UI-ja/Skripte igre STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Skripta Igre koja će biti učitana u sljedećoj igri STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}UI-jevi koji će biti učitani u sljedećoj igri STR_AI_CONFIG_HUMAN_PLAYER :Ljudski igrač STR_AI_CONFIG_RANDOM_AI :Nasumična UI STR_AI_CONFIG_NONE :(nijedan) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Najveći broj natjecatelja: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Pomakni gore STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Pomakni odabrani UI gore na listi @@ -4453,8 +4442,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Pomakni STR_AI_CONFIG_GAMESCRIPT :{SILVER}Skripta Igre STR_AI_CONFIG_AI :{SILVER}UI-jevi -STR_AI_CONFIG_CHANGE :{BLACK}Odaberi {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :UI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Skripta Igre STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Učitaj drugu skriptu @@ -4484,10 +4471,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Slika ci STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Slika visinske mape STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Slika mini-mape -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametri +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :UI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Skripta Igre STR_AI_SETTINGS_CLOSE :{BLACK}Zatvori STR_AI_SETTINGS_RESET :{BLACK}Resetiraj STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4901,6 +4886,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Nije mog STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vozilo je uništeno + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Neće biti dostupno nijedno vozilo STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Promijenite konfiguraciju NewGRF-a STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Još nema dostupnih vozila @@ -4934,6 +4920,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Nije mog STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... predaleko od prethodnog odredišta STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... avion nema dovoljni domet +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Nije moguće zadati vozni red za vozilo... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Vozila mogu čekati samo na postajama. diff --git a/src/lang/czech.txt b/src/lang/czech.txt index 24df1b1ef8135..93600de2f49bc 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -275,6 +275,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -301,8 +311,8 @@ STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Filtrovat řetězec: -STR_LIST_FILTER_OSKTITLE :{BLACK}Vložte filtr -STR_LIST_FILTER_TOOLTIP :{BLACK}Vložte klíčové slovo pro filtr seznamu +STR_LIST_FILTER_OSKTITLE :{BLACK}Vložte jedno nebo více klíčových slov pro filtr seznamu +STR_LIST_FILTER_TOOLTIP :{BLACK}Vložte jedno nebo více klíčových slov pro filtr seznamu STR_TOOLTIP_GROUP_ORDER :{BLACK}Vyber pořadí seskupení STR_TOOLTIP_SORT_ORDER :{BLACK}Vyber způsob řazeni (sestupně/vzestupně) @@ -451,9 +461,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Generov STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Generování průmyslu STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Výstavba silniční sítě STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Výstavba tramvajové tratě -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Vysadit stromy. Shift zobrazí odhad ceny +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Vysadit stromy. Ctrl vybírá území úhlopříčně. Shift zobrazí odhad ceny STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Umístit popisek -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Umisťte objekt. Shift zobrazí odhad ceny +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Umisťte objekt. Pro zobrazení odhadu ceny podrž Shift. Ctrl vybírá oblast diagonálně # Scenario editor file menu ###length 7 @@ -466,10 +476,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Ukončit # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Možnosti hry STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Nastavení -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Nastavení AI / hry +STR_SETTINGS_MENU_AI_SETTINGS :Nastavení AI +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Nastavení herních skriptů STR_SETTINGS_MENU_NEWGRF_SETTINGS :Nastavení grafik STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Nastavení průhlednosti STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Zobrazení jmen měst @@ -988,8 +999,8 @@ STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE :{BIG_FONT}{BLAC STR_NEWS_SERVICE_SUBSIDY_OFFERED :{BIG_FONT}{BLACK}Nabídka dotace:{}{}Doprava {STRING} z {STRING} do {STRING} bude {NUM} rok dotována místní správou! ###length 4 STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF :{BIG_FONT}{BLACK}Dotace přidělena společnosti {STRING}!{}{}Doprava {STRING.gen} z{NBSP}{STRING.gen} do {STRING.gen} bude po {NUM} rok{P “” ů ů} vynášet 150{NBSP}% normální ceny -STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLACK}Dotace přidělena společnosti {STRING}!{}{} Doprava {STRING} z{NBSP}{STRING} do {STRING} bude po {NUM} rok{P “” “” ů} vynášet dvojnásobek normální ceny! -STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}Dotace přidělena společnosti {STRING}.{}{}Doprava {STRING.gen} z{NBSP}{STRING.gen} do {STRING.gen} bude po {NUM} rok{P “” ů ů} vynášet trojnásobek normální ceny! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLACK}Dotace přidělena společnosti {STRING}!{}{} Doprava {STRING} z{NBSP}{STRING} do {STRING} bude po {NUM} rok{P "" "" ů} vynášet dvojnásobek normální ceny! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}Dotace na přepravu přidělena společnosti {STRING}!{}{}Přeprava {STRING.gen} z {STRING.gen} do {STRING.gen} bude po {NUM} rok{P “” y ů} vynášet trojnásobek normální sazby! STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE :{BIG_FONT}{BLACK}Dotace přidělena společnosti {STRING}.{}{}Doprava {STRING.gen} z{STRING.gen} do {STRING.gen} bude po {NUM} rok{P “” ů ů} vynášet čtyřnásobek normální ceny! STR_NEWS_ROAD_REBUILDING :{BIG_FONT}{BLACK}{TOWN} zažívá dopravní chaos!{}{}Program přestavby ulic sponzorovaný {STRING} přináší motoristům 6 měsíců utrpení! @@ -1052,36 +1063,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indická rupie STR_GAME_OPTIONS_CURRENCY_IDR :Indonéská rupie (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malajsijský Ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Vlevo -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Vpravo - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Názvy měst -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Výběr stylu jmen měst - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Anglická (původní) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francouzská -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Německá -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Anglická (další) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latinskoamerická -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Anglická (legrační) -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Švédská -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holandská -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finská -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polská -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovenská -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norská -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Maďarská -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Rakouská -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumunská -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Česká -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Švýcarská -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dánská -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turecká -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italská -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalánská - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatické ukládání STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Volba intervalu mezi automatickým ukládáním hry @@ -1114,21 +1095,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Zaškrtn STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Aktuální ovladač: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Velikost rozhraní -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Zvolit velikost prvků uživatelského rozhraní +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Velikost uživatelského rozhraní +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Přetažením posuvníku změníš velikost rozhraní. Drž Ctrl pro plynulé přizpůsobení +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Automaticky detekovat velikost +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Zaškrtni pro automatické nastavení velikosti uživatelského rozhraní -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(zjistit automaticky) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normální -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dvojnásobná velikost -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Čtyřnásobná velikost +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Škálovat úkosy +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Zaškrtni toto políčko pro škálování úkosů dle velikosti uživatelského rozhraní -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Velikost písma -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Zvolit velikost písma - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(zjistit automaticky) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Běžné -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dvojnásobná velikost -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Čtyřnásobná velikost +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafiky @@ -1180,8 +1159,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Náhled STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 liber (£) ve vlastní měně STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Změnit parametry vlastní měny -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maximální počet protivníků: {ORANGE}{COMMA} - STR_NONE :žádný STR_FUNDING_ONLY :Pouze dotace STR_MINIMAL :Nejmenší @@ -1231,6 +1208,12 @@ STR_SUBSIDY_X2 :2x STR_SUBSIDY_X3 :3x STR_SUBSIDY_X4 :4x +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :krajina mírného pásma +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :subarktická krajina +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :subtropická kraina +STR_CLIMATE_TOYLAND_LANDSCAPE :Země hraček + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :velmi plochá STR_TERRAIN_TYPE_FLAT :plochá @@ -1244,13 +1227,13 @@ STR_TERRAIN_TYPE_CUSTOM_VALUE :Vlastní výšk STR_CITY_APPROVAL_LENIENT :Shovívavý STR_CITY_APPROVAL_TOLERANT :tolerantní STR_CITY_APPROVAL_HOSTILE :zaujatý -STR_CITY_APPROVAL_PERMISSIVE :nezaujatý +STR_CITY_APPROVAL_PERMISSIVE :Nezaujatý (bez vlivu na počínání společnosti) STR_WARNING_NO_SUITABLE_AI :{WHITE}Žádná vhodná AI není k dispozici...{}Některé AI lze stáhnout pomocí služby "Stahovat součásti" # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Nastavení -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrovat podle: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrovat: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Rozbalit vše STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Sbalit vše STR_CONFIG_SETTING_RESET_ALL :{BLACK}Vymazat všechny hodnoty @@ -1310,6 +1293,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :vpravo STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maximální půjčka: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Jak moc si může společnost půjčit (bez ohledu na inflaci) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Žádná půjčka {RED}Vyžaduje herní skript pro získání základního kapitálu. STR_CONFIG_SETTING_INTEREST_RATE :Výše úroků: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Výše úroků z půjček; rovněž ovlivňuje inflaci, pokud je zapnuta @@ -1345,7 +1331,7 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Pokud je zapnut STR_CONFIG_SETTING_DISASTERS :Katastrofy: {STRING} STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Katastrofy, které mohou občas zablokovat či zničit vozidla nebo infrastrukturu -STR_CONFIG_SETTING_CITY_APPROVAL :Postoj městské rady k úpravám v oblasti: {STRING} +STR_CONFIG_SETTING_CITY_APPROVAL :Postoj městské správy k úpravám v oblasti: {STRING} STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Vyber jak moc hluku a změn prostředí poškozuje hodnocení společnosti u města a tak dále komplikuje budoucí stavbu na jeho území STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :Maximální výška mapy: {STRING} @@ -1536,6 +1522,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Tloušťka čá STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Zobrazovat název NewGRF v okně nákupu vozidel: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Přidá řádek do okna nákupu vozidel informující, ze které NewGRF vybrané vozidlo pochází. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Zobrazit druhy nákladu, které vozidlo může přepravovat, v oknech seznamů {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Pokud je povoleno, zobrazí se nad ním v seznamech vozidel přepravitelný náklad vozidla STR_CONFIG_SETTING_LANDSCAPE :Klima: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Klima určuje základy herního scénáře s rozdílnými druhy nákladu a požadavky na růst měst. Nové GRaFiky a Herní Skripty umožní ještě jemnější kontrolu @@ -1590,6 +1578,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :vylepšený STR_CONFIG_SETTING_ROAD_SIDE :Silniční vozidla: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Zvol na jaké straně vozovky jezdí vozidla +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Vlevo +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Vpravo + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Otočení výškové mapy: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Doleva @@ -2023,13 +2015,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Zaber si {STRIN STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Čas vyhrazený pro každý přepočet části grafu spojení. Pokud přepočet začne, je vytvořeno nové vlákno, které má dovoleno běžet po zvolený počet dnů. Čím nižší hodnotu nastavíš tím je pravděpodobnější, že vlákno nebude dokončeno kdy má. Pokud se tak stane, hra se zastaví ("lagne") dokud dokončeno nebude. Čím vyšší hodnotu nastavíš, tím déle bude trvat aktualizace grafu pokud se trasy změní. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Mód distribuce pro cestující: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Rovnoměrný" znamená, že téměř stejné množství cestujících chce cestovat ze stanice A do stanice B, jako ze stanice B do A. "Nerovnoměrný znamená", že libovolné množství cestujících může cestovat v jakýchkoliv směrech. "manuální" znamená, že zde nebude žádná automatická distribuce pro cestující. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Rovnoměrný" znamená, že téměř stejné množství cestujících chce cestovat ze stanice A do stanice B, jako ze stanice B do A. "Nerovnoměrný" znamená, že libovolné množství cestujících může cestovat v jakémkoliv směru. "Manuální" znamená, že zde nebude žádná automatická distribuce pro cestující. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Mód distribuce pro poštu: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Rovnoměrný" znamená, že téměř stejné množství pošty bude odesláno ze stanice A do stanice B, jako ze stanice B do A. "Nerovnoměrný znamená", že libovolné množství pošty může být odesláno v jakýchkoliv směrech. "manuální" znamená, že zde nebude žádná automatická distribuce pro poštu. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Rovnoměrný" znamená, že téměř stejné množství pošty bude odesláno ze stanice A do stanice B, jako ze stanice B do A. "Nerovnoměrný" znamená, že libovolné množství pošty může být odesláno v jakémkoli směru. "Manuální" znamená, že zde nebude žádná automatická distribuce pro poštu. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Mód distribuce pro náklady pancéřových vozů: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Pancéřované vozy převážejí ceniny v mírném, diamanty v subtropickém nebo zlato v subarktickém klimatu. Nové grafiky však toho mohou změnit. "Rovnoměrný" znamená, že téměř stejné množství nákladu bude odesláno ze stanice A do stanice B, jako ze stanice B do A. "Nerovnoměrný znamená", že libovolná množství nákladu mohou být odeslána v jakýchkoliv směrech. "manuální" znamená, že zde nebude žádná automatická distribuce pro tyto druhy nákladu. Je doporučeno nastavit "nerovnoměrný" nebo "manuální" při hraní v subarktickém klimatu, neboť banky neposílají do dolů žádné zlato. Pro mírné a subtropické klima můžeš nastavit "rovnoměrné", neboť banky odesílají zpět do původní banky nějaký náklad cenin. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Pancéřované vozy převážejí ceniny v mírném, diamanty v subtropickém nebo zlato v subarktickém klimatu. Nové grafiky však toho mohou změnit. "Rovnoměrný" znamená, že téměř stejné množství nákladu bude odesláno ze stanice A do stanice B, jako ze stanice B do A. "Nerovnoměrný" znamená, že libovolná množství nákladu mohou být odeslána v jakémkoliv směru. "Manuální" znamená, že zde nebude žádná automatická distribuce pro tyto druhy nákladu. Je doporučeno nastavit "nerovnoměrný" nebo "manuální" při hraní v subarktickém klimatu, neboť banky neposílají do dolů žádné zlato. Pro mírné a subtropické klima můžeš nastavit "rovnoměrné", neboť banky odesílají zpět do původní banky nějaký náklad cenin. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Módy distribuce pro ostatní třídy nákladu: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Rovnoměrný" znamená, že téměř stejné množství nákladu bude odesláno ze stanice A do stanice B, jako ze stanice B do A. "Nerovnoměrný znamená", že libovolná množství nákladu mohou být odeslána v jakýchkoliv směrech. "manuální" znamená, že zde nebude žádná automatická distribuce pro tyto druhy nákladu. Pravděpodobně chceš nastavit "nerovnoměrná" nebo "manuální"." +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Nerovnoměrný" znamená, že libovolná množství nákladu mohou být odeslána v jakémkoli směru. "manuální" znamená, že zde nebude žádná automatická distribuce pro tyto druhy nákladu. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuální STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :nerovnoměrný @@ -2124,7 +2116,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatické ot STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Povoluje vlakům otočit se na semaforech, pokud čekají příliš dlouho ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(doporučený) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(doporučený) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Změnit hodnotu nastavení @@ -2167,7 +2159,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Nejlepš STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Nastavení STR_INTRO_NEWGRF_SETTINGS :{BLACK}Nastavení grafik STR_INTRO_ONLINE_CONTENT :{BLACK}Stahovat součásti -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Nastavení AI / hry +STR_INTRO_AI_SETTINGS :{BLACK}Nastavení AI +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Nastavení herních skriptů STR_INTRO_QUIT :{BLACK}Ukončit STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Hrát novou hru. Pomocí Ctrl přeskočíš nastavení mapy @@ -2185,9 +2178,10 @@ STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Země hr STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Zobrazit možnosti hry STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Zobrazit tabulku nejlepších výsledků STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Nastavení zobrazení -STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Ukázat nastavení NewGRF +STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Zobrazit nastavení NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Ukázat, jaký nový nebo upravený obsah se dá stáhnout -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Zobrazit nastavení AI a hry +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Zobrazit nastavení AI +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Zobrazit nastavení herních skriptů STR_INTRO_TOOLTIP_QUIT :{BLACK}Ukončit 'OpenTTD' STR_INTRO_BASESET :{BLACK}V aktuálně zvolené základní sadě grafiky chybí {NUM} sprit{P "" y ů}. Zkuste, prosím, vyhledat aktualizovanou základní sadu. @@ -2219,12 +2213,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Změnit STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Změnit rok STR_CHEAT_SETUP_PROD :{LTBLUE}Povolit změnu produkce průmyslu: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :krajina mírného pásma -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :subarktická krajina -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :subtropická kraina -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Země hraček - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - barevné schéma @@ -2457,7 +2445,7 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nová společn STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Vytvořit novou společnost a připojit se do ní STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Tohle jsi ty STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Toto je hostitel hry -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" i i} / {NUM} společnost{P “” i i} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Počet momentálně připojených hráčů, počet společností a maximální počet společností povolený administrátorem serveru # Matches ConnectionType ###length 5 @@ -2585,12 +2573,12 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :čekám na aktu STR_NETWORK_MESSAGE_CLIENT_LEAVING :odpojování STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} se připojil do hry STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} se připojil do hry (klient č. {2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} se přidává ke společnosti č. {2:NUM} +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} se přidal ke společnosti č. {2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} se stává pozorovatelem -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} zakládá novou společnost (č. {2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} opouští hru ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} zakládá novou společnost (č. {2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} opouští hru ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} si změnil jméno na {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} poslal(a) {2:CURRENCY_LONG} společnosti {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} poslal(a) {2:CURRENCY_LONG} společnosti {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server ukončil relaci STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server se restartuje...{}Počkejte prosím... STR_NETWORK_MESSAGE_KICKED :*** {STRING} byl vyhozen. Důvod: ({STRING}) @@ -2704,6 +2692,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}nasycený STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}přetížení +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} nákladu měsíčně k přepravě z {STATION} do {STATION} ({COMMA}% z kapacity){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} má být přepraveno zpět ({COMMA}% z kapacity) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Průměrná doba cesty: {NUM}{NBSP}{P "den" "dny" "dnů"} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Zvýraznění oblasti pokrytí STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Vypnuto @@ -2712,6 +2705,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Nezvýra STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Zvýraznit oblast pokrytí STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Přijímá: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Poskytuje: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Náklady na údržbu: {GOLD}{CURRENCY_SHORT}/rok # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Spojování stanic @@ -2794,8 +2788,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Zvýšit STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Zvolit železniční most STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Zvolit silniční most STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Výběr mostů - staví se kliknutím na obrázek mostu -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Zavěšený, ocelový STR_BRIDGE_NAME_GIRDER_STEEL :Trámový, ocelový STR_BRIDGE_NAME_CANTILEVER_STEEL :Konzolový, ocelový @@ -2899,11 +2895,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Úpravy STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Snížit roh země. Tažení sníží první vybraný roh a vybranou oblast na jeho novou výšku. Ctrl vybírá diagonální oblast. Stisknutý Shift pro zobrazení odhadu ceny STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Zvýšit roh země. Tažení zvyšuje první vybraný roh a vybranou oblast na jeho novou výšku. Ctrl vybírá diagonální oblast. Stisknutý Shift pro zobrazení odhadu ceny STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Srovnat terén na výšku prvního vybraného rohu. Ctrl vybírá diagonální oblast. Stisknutý Shift pro zobrazení odhadu ceny -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Zakoupit pozemek pro budoucí užití. Stisknutý Shift pro zobrazení odhadu ceny +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Zakoupit pozemek pro budoucí užití. Držet Shift pro zobrazení odhadu ceny # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Výběr objektu -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Vyberte objekt, který se má postavit. Stisknutý Shift pro zobrazení odhadu ceny +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Vyberte objekt, který se má postavit. Ctrl vybírá diagonální oblast. Shift zobrazí odhad ceny STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Vyberte třídu objektu, který chcete postavit STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Náhled objektu STR_OBJECT_BUILD_SIZE :{BLACK}Velikost: {GOLD}{NUM}{NBSP}x{NBSP}{NUM} @@ -2915,7 +2911,7 @@ STR_OBJECT_CLASS_TRNS :Vysílače STR_PLANT_TREE_CAPTION :{WHITE}Stromy STR_PLANT_TREE_TOOLTIP :{BLACK}Zvol druh stromu na vysazení. Pokud se na políčku už nějaký strom nachází, přidá se k němu několik různých druhů bez ohledu na výběr druhu STR_TREES_RANDOM_TYPE :{BLACK}Různé stromy -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Umístit nahodné stromy. Stisknutý Shift pro zobrazení odhadu ceny +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Umístit nahodné stromy. Ctrl vybírá území úhlopříčně. Stisknutý Shift pro zobrazení odhadu ceny STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Náhodné stromy STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Umístit stromy náhodně po krajině STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normální @@ -2947,6 +2943,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Náhodn STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Vybuduj město na náhodné pozici STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Hodně náhodných měst STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Pokryje krajinu mnoha náhodnými městy +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Rozbalit všechna města +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Nechte všechna města mírně růst STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Název města: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Zadej název města @@ -3231,6 +3229,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Velikost STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Vybrat velikost mapy ve čtvercích. Počet dostupných čtverců bude o neco nižší STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Množství měst: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Názvy měst +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Výběr stylu jmen měst STR_MAPGEN_DATE :{BLACK}Datum: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Množství průmyslu: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Nejvyšší vrchol: @@ -3244,13 +3244,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Pokrytí STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Zvětšit pokrytí pouštěmi o deset procent STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Zmenšit pokrytí pouštěmi o deset procent STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Generátor krajiny: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Typ krajiny: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Četnost jezer: +STR_MAPGEN_SEA_LEVEL :{BLACK}Četnost jezer: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Řeky: STR_MAPGEN_SMOOTHNESS :{BLACK}Členitost krajiny: STR_MAPGEN_VARIETY :{BLACK}Rozmanitost terénu: STR_MAPGEN_GENERATE :{WHITE}Vytvořit +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Nastavení NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Zobrazit nastavení NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Nastavení AI +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Zobrazit nastavení AI +STR_MAPGEN_GS_SETTINGS :{BLACK}Nastavení herních skriptů +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Zobrazit nastavení herních skriptů + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Anglická (původní) +STR_MAPGEN_TOWN_NAME_FRENCH :Francouzská +STR_MAPGEN_TOWN_NAME_GERMAN :Německá +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Anglická (další) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latinskoamerická +STR_MAPGEN_TOWN_NAME_SILLY :Anglická (legrační) +STR_MAPGEN_TOWN_NAME_SWEDISH :Švédská +STR_MAPGEN_TOWN_NAME_DUTCH :Holandská +STR_MAPGEN_TOWN_NAME_FINNISH :Finská +STR_MAPGEN_TOWN_NAME_POLISH :Polská +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovenská +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norská +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Maďarská +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Rakouská +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumunská +STR_MAPGEN_TOWN_NAME_CZECH :Česká +STR_MAPGEN_TOWN_NAME_SWISS :Švýcarská +STR_MAPGEN_TOWN_NAME_DANISH :Dánská +STR_MAPGEN_TOWN_NAME_TURKISH :Turecká +STR_MAPGEN_TOWN_NAME_ITALIAN :Italská +STR_MAPGEN_TOWN_NAME_CATALAN :Katalánská # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Okraje mapy: @@ -3396,6 +3424,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Předcho STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Jít na předchozí normální sprite (s grafikou), přičemž se přeskakují pseudo-/barvící/znakové sprity a při dosažení začátku se jde na konec STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Zobrazení vybraného spritu. Posun se při jeho vykreslení neuvažoval STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Posouvání spritu změnou souřadnic X a Y. Ctrl+kliknutí posouvá o osm jednotek najednou. + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Posunutí vystředění +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprit vycentrován + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Zaměřovač + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Resetovat STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Resetovat aktuání relativní posunutí STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Posunutí v ose X: {NUM}, Posunutí v ose Y: {NUM} (Absolutní) @@ -3410,15 +3445,15 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Varování: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Chyba: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Závažná chyba: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Vyskytla se kritická chyba v NewGRF:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Došlo k chybě v NewGRF:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}V NewGRF "{STRING}" se vyskytla kritická chyba:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}V NewGRF "{STRING}" došlo k chybě{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} nebude fungovat s verzí TTDPatche, kterou OpenTTD hlásí -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} je pro TTD verzi {STRING} +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} je pro TTD verzi {2:STRING} STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} je navržen pro práci s {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Neplatný parametr pro {1:STRING}: parametr {STRING} ({NUM}) +STR_NEWGRF_ERROR_INVALID_PARAMETER :Neplatný parametr pro {1:STRING}: parametr {2:STRING} ({3:NUM}) STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} musí být nahráván před {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} musí být nahráván po {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} potřebuje verzi OpenTTD {STRING} nebo vyšší +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} musí být nahráván po {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} potřebuje verzi OpenTTD {2:STRING} nebo vyšší STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :grafika, která se měla přeložit STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Je nahráno příliš mnoho grafik STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Nahrání {1:STRING} jako statické grafiky spolu s {STRING} může způsobit chybu synchronizace @@ -3553,14 +3588,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Koupit výhradn STR_LOCAL_AUTHORITY_ACTION_BRIBE :Podplatit místní správu ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Zahájit malou reklamní kampaň, která přiláká více cestujících a nákladu.{}Poskytuje dočasné zvýšení hodnocení přepravy v blízkém okolí městského centra.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Zahájit středně velkou reklamní kampaň, která přiláká více cestujících a nákladu.{}Poskytuje dočasné zvýšení hodnocení přepravy ve středně širokém okolí městského centra.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Zahájit velkou reklamní kampaň, která přiláká více cestujících a nákladu.{}Poskytuje dočasné zvýšení hodnocení přepravy v širokém okolí městského centra.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Dotovat rekonstrukci sítě místních ulic.{}Způsobí problémy v dopravě po dobu až 6ti měsíců.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Postavit sochu jako poctu tvé společnosti.{}Poskytuje trvalý bonus k hodnocení stanic v tomto městě.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Dotovat stavbu nových obchodních budov ve městě.{}Poskytuje dočasné zvýšení rychlosti růstu města.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Koupit 1 roční výhradní přepravní práva z tohoto města. Místní správa nedovolí dovolí cestujícím ani nákladu používat stanice tvých konkurentů.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Podplatit místní správu pro zvýšení hodnocení společnosti. Riziko trestu v případě přistižení.{}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Zahájit malou reklamní kampaň, která přiláká více cestujících a nákladu.{}Poskytuje dočasné zvýšení hodnocení přepravy v blízkém okolí městského centra.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Zahájit středně velkou reklamní kampaň, která přiláká více cestujících a nákladu.{}Poskytuje dočasné zvýšení hodnocení přepravy ve středně širokém okolí městského centra.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Zahájit velkou reklamní kampaň, která přiláká více cestujících a nákladu.{}Poskytuje dočasné zvýšení hodnocení přepravy v širokém okolí městského centra.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Dotovat rekonstrukci sítě místních ulic.{}Způsobí problémy v dopravě po dobu až 6 měsíců.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Postavit sochu jako poctu tvé společnosti.{}Poskytuje permanentní bonus k hodnocení stanic v tomto městě.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Dotovat stavbu nových obchodních budov ve městě.{}Poskytuje dočasné zvýšení rychlosti růstu města.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Koupit roční výhradní přepravní práva pro toto město. Místní správa nedovolí dovolí cestujícím ani nákladu používat stanice konkurentů.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Podplatit místní správu pro zvýšení hodnocení společnosti. Riziko trestu v případě přistižení.{}{POP_COLOUR}Cena: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Cíle @@ -3722,7 +3757,7 @@ STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Kapitál STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Výstavba STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Nové dopravní prostředky STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Vlaky -STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Provoz silničních vozidel +STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Silniční vozidla STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Provoz letadel STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Provoz lodí STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Infrastruktura @@ -3733,15 +3768,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Lodě STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Úroky z půjček STR_FINANCES_SECTION_OTHER :{GOLD}Další +STR_FINANCES_TOTAL_CAPTION :{WHITE}Celkem STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Čistý zisk +STR_FINANCES_PROFIT :{WHITE}Zisk STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Stav na účtu STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Vlastní Prostředky STR_FINANCES_LOAN_TITLE :{WHITE}Půjčka STR_FINANCES_INTEREST_RATE :{WHITE}Úrok z půjčky: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maximální půjčka: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Půjčit {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Půjčit si více STR_FINANCES_REPAY_BUTTON :{BLACK}Vrátit {CURRENCY_LONG} @@ -3842,7 +3880,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produkuj STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Vyžaduje: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} ček{P á ají á}{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Změnit produkci (násobky 8, až do 2040) @@ -3871,7 +3909,9 @@ STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}Upravit STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Poslat příkazy všem vozidlům v tomto seznamu STR_VEHICLE_LIST_REPLACE_VEHICLES :Vyměňování vozidel STR_VEHICLE_LIST_SEND_FOR_SERVICING :Provést údržbu -STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Zisk tento rok: {CURRENCY_LONG} (minulý rok: {CURRENCY_LONG}) +STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Letošní zisk: {CURRENCY_LONG} (vloni: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Poslat do depa STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Poslat do depa @@ -3963,6 +4003,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. ta STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Dosah: {GOLD}{COMMA} polí STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Typ letadla: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Všechny druhy nákladu +STR_CARGO_TYPE_FILTER_FREIGHT :Náklad +STR_CARGO_TYPE_FILTER_NONE :Žádný + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Seznam vlaků - pro informace klikni na vlak. Ctrl+kliknutí způsobí přepínání skrytí typů lokomotiv a vagónů. STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Seznam silničních vozidel - klikni na vozidlo pro informace. Ctrl+kliknutí způsobí přepínání skrytí typu silničního vozidla. @@ -4293,12 +4338,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Hmotnost STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Hmotnost: {LTBLUE}{WEIGHT_SHORT} {BLACK}Výkon: {LTBLUE}{POWER}{BLACK} Max. rychlost: {LTBLUE}{VELOCITY} {BLACK}Max. tažná síla: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Letošní zisk: {LTBLUE}{CURRENCY_LONG} (vloni: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Letošní zisk: {LTBLUE}{CURRENCY_LONG} (vloni: {CURRENCY_LONG}) {BLACK}Min. výkon: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Spolehlivost: {LTBLUE}{COMMA}% {BLACK}Poruch od posledního servisu: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Koupeno: {LTBLUE}{NUM}{BLACK} Cena: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Kapacita: {LTBLUE}nic{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapacita: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapacita: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapacita: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Podíl za převoz: {LTBLUE}{CURRENCY_LONG} @@ -4564,25 +4610,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Tento j STR_TIMETABLE_STATUS_START_AT :{BLACK}Tento jízdní řád začne v {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Datum začátku -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Vyber počáteční datum tohoto jízdního řádu. Ctrl+Klik nastaví počáteční datum jízdního řádu všem vozidlům sdílejícím příkazy vzhledem k jejich pořadí +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Vyber počáteční datum tohoto jízdního řádu. Ctrl+Klik rovnoměrně rozloží odjezdy jednotlivých vozidel sdílejích příkazy s ohledem na současný jízdní řád. STR_TIMETABLE_CHANGE_TIME :{BLACK}Změnit čas -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Změnit čas pro splnění jízdního příkazu +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Změnit čas pro splnění jízdního příkazu. Ctrl+klik změní čas pro všechny příkazy. STR_TIMETABLE_CLEAR_TIME :{BLACK}Smazat čas -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Zrušit čas pro splnění jízdního příkazu +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Zrušit čas pro splnění jízdního příkazu. Ctrl+klik zruší čas pro všechny příkazy STR_TIMETABLE_CHANGE_SPEED :{BLACK}Změnit rychlostní limit -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Změnit maximální cestovní rychlost u vybraného příkazu +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Změnit maximální cestovní rychlost u vybraného příkazu. Ctrl+klik nastaví rychlost pro všechny příkazy STR_TIMETABLE_CLEAR_SPEED :{BLACK}Odstranit rychlostní limit -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Odstranit maximální cestovní rychlost u vybraného příkazu +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Odstranit maximální cestovní rychlost u vybraného příkazu. Ctrl+klik odstraní maximální rychlosti u všech příkazů STR_TIMETABLE_RESET_LATENESS :{BLACK}Zapomenout zpoždění -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Smazat zpoždění, takže vozidlo pojede na čas +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Smazat zpoždění, takže vozidlo pojede na čas. Ctrl+Click smaže zpoždění celé skupině, takže poslední vozidlo pojede na čas a ostatní brzy. STR_TIMETABLE_AUTOFILL :{BLACK}Automaticky -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Automaticky vyplň rozvrh hodnotami z následující cesty (Ctrl+klik pro zachování vyčkávací doby) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Automaticky vyplň rozvrh hodnotami z následující cesty. Ctrl+klik pro zachování vyčkávací doby. STR_TIMETABLE_EXPECTED :{BLACK}Očekávaný STR_TIMETABLE_SCHEDULED :{BLACK}Plánovaný @@ -4626,12 +4672,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Někter STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Okno na ladění AI / herních skriptů je dostupné pouze na serveru # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Nastavení AI / hry +STR_AI_CONFIG_CAPTION_AI :{WHITE}Nastavení AI +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Možnosti herních skriptů STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Herní skripty, které budou načteny v příští hře STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AI, které budou načteny v příští hře STR_AI_CONFIG_HUMAN_PLAYER :Lidský hráč STR_AI_CONFIG_RANDOM_AI :Náhodná AI STR_AI_CONFIG_NONE :(žádný) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maximální počet protivníků: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Přesunout nahoru STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Přesunout vybranou AI v seznamu výše @@ -4639,12 +4687,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Přesuno STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Přesunout vybranou AI v seznamu níže STR_AI_CONFIG_GAMESCRIPT :{SILVER}Herní skript +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametry STR_AI_CONFIG_AI :{SILVER}AI -STR_AI_CONFIG_CHANGE :{BLACK}Vybrat {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Herní skript +STR_AI_CONFIG_CHANGE_AI :{BLACK}Vybrat AI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Vybrat herní skript STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Načíst další skript STR_AI_CONFIG_CONFIGURE :{BLACK}Nastavit STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Nastavit parametry skriptu @@ -4672,10 +4719,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Snímek STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Snímek výškové mapy STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Snímek (náhledové) mapy světa -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametry -STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :herní skript +STR_AI_SETTINGS_CAPTION_AI :{WHITE}Parametry AI +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Herní skript STR_AI_SETTINGS_CLOSE :{BLACK}Zavřít STR_AI_SETTINGS_RESET :{BLACK}Obnovit nastavení STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4839,6 +4886,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... př STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nelze vygenerovat žádný průmysl... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Zde nelze postavit {STRING} ... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Zde nelze postavit tento druh průmyslu... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Není možné založit průmysl ... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... příliš blízko k jinému průmyslu STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... je nutné nejprve vystavět město STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... je povolena jen jedna na město @@ -4853,6 +4901,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... les STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... může být postaven pouze nad sněžnou čarou STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... může být postaven pouze pod sněžnou čarou +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Smůla, financování průzkumu se nezdařilo; zkus to znovu +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Na mapě nebyla žádná vhodná místa pro založení tohoto typu průmyslu STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Na mapě nebyla žádná vhodná místa pro '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Pro získání lepší mapy změňte parametry jejího generování @@ -5027,6 +5077,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}V cestě STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... v cestě je ředitelství společnosti STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Nelze zakoupit tento pozemek... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... již vlastníš! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... dosažen limit pro výstavbu objektů # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Nelze vytvořit skupinu... @@ -5099,6 +5150,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Nelze zm STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vozidlo bylo zničeno +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... všechna vozidla nejsou identická + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Žádná vozidla nejsou dostupná STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Zmeň nastavení NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Zatím nejsou dostupná žádná vozidla @@ -5125,6 +5178,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Nelze p STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... prostředek se nedostane do všech stanic STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... do této stanice se prostředek nedostane STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... do této stanice se prostředek sdílející tento příkaz nedostane +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... ne všechna vozidla mají stejné příkazy +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... ne všechna vozidla sdílí příkazy STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Nelze sdílet seznam příkazů... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Nelze zastavit sdílení seznamu příkazů... @@ -5132,6 +5187,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Nelze ko STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... příliš daleko od předcházejícího cíle STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... letadlo nemá dostatečný dolet +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Není zde žádná železniční stanice +STR_ERROR_NO_BUS_STATION :Není zde žádná autobusová stanice +STR_ERROR_NO_TRUCK_STATION :Není zde žádná nákladní rampa +STR_ERROR_NO_DOCK :{WHITE}Není zde žádný přístav +STR_ERROR_NO_AIRPORT :{WHITE}Zde není žádné letiště +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Nejsou zde žádné zastávky kompatibilní s tímto druhem silnice +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Zde není žádná zastávka kompatibilní s tímto typem tramvaje +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Nejsou zde žádné stanice vhodné pro kloubové silniční vozidla.{}Kloubové silniční vozidla vyžadují průjezdnou stanici. +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Toto letadlo nemůže přistát na tomto letišti +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Tato helikoptéra nemůže přistát na tomto letišti +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Zde není žádný kolejový směrovač +STR_ERROR_NO_BUOY :{WHITE}Zde není žádná bójka + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Tomuto vozidlu nejde nastavit jízdní řád... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Vozidla mohou čekat jen ve stanicích diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 002463ff81049..da7c5ea5db686 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}hk STR_UNITS_POWER_METRIC :{COMMA}hk STR_UNITS_POWER_SI :{COMMA}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -226,8 +236,8 @@ STR_UNITS_HEIGHT_SI :{COMMA} m # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Filtrer udtryk: -STR_LIST_FILTER_OSKTITLE :{BLACK}Indtast filter-udtryk -STR_LIST_FILTER_TOOLTIP :{BLACK}Indtast nøgleord til at filtrere listen efter +STR_LIST_FILTER_OSKTITLE :{BLACK}Indtast filterstreng +STR_LIST_FILTER_TOOLTIP :{BLACK}Angiv et nøgleord, som listen skal filtreres efter STR_TOOLTIP_GROUP_ORDER :{BLACK}Vælg grupperingssortering STR_TOOLTIP_SORT_ORDER :{BLACK}Vælg sorteringsorden (faldende/stigende) @@ -376,9 +386,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Bygenere STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industrigenerering STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Bygning af vej STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Sporvejskonstruktion -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant træer. Shift skifter mellem at bygge og vise prisoverslag. +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant træer. Ctrl vælger området diagonalt. Skift skifter bygning/viser omkostningsestimat STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Placér skilt -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Placér objekt. Shift viser tidsestimat +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Placer objekt. Skift viser bygnings omkostningsestimat # Scenario editor file menu ###length 7 @@ -391,15 +401,16 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Afslut # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Opsætning STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Indstillinger -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/spilscript-indstillinger +STR_SETTINGS_MENU_AI_SETTINGS :AI indstillinger +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Indstillinger for spilscript STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF indstillinger STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Gennemsigtighedsvalg STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Bynavne vist STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :Stationsnavne vist -STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Waypointnavne vist +STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :Rutepunkt-navne vist STR_SETTINGS_MENU_SIGNS_DISPLAYED :Viste skilte STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS :Modstander skilte og navne vist STR_SETTINGS_MENU_FULL_ANIMATION :Fuld animation @@ -497,7 +508,7 @@ STR_ABOUT_MENU_AI_DEBUG :Computerspiller STR_ABOUT_MENU_SCREENSHOT :Skærmbillede (Ctrl-S) STR_ABOUT_MENU_SHOW_FRAMERATE :Vis spilhastighed STR_ABOUT_MENU_ABOUT_OPENTTD :Om 'OpenTTD' -STR_ABOUT_MENU_SPRITE_ALIGNER :Spritejustering +STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite justering STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Slå afgrænsningsrammerne til/fra STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Slå farvning af beskidte blokke til/fra @@ -704,7 +715,7 @@ STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Klik på STR_HIGHSCORE_TOP_COMPANIES_WHO_REACHED :{BIG_FONT}{BLACK}Bedste virksomheder, som har nået {NUM} STR_HIGHSCORE_TOP_COMPANIES_NETWORK_GAME :{BIG_FONT}{BLACK}Selskabsoversigt i {NUM} STR_HIGHSCORE_POSITION :{BIG_FONT}{BLACK}{COMMA}. -STR_HIGHSCORE_PERFORMANCE_TITLE_BUSINESSMAN :Forretningsdriver +STR_HIGHSCORE_PERFORMANCE_TITLE_BUSINESSMAN :Forretningsmand STR_HIGHSCORE_PERFORMANCE_TITLE_ENTREPRENEUR :Entreprenør STR_HIGHSCORE_PERFORMANCE_TITLE_INDUSTRIALIST :Industrialist STR_HIGHSCORE_PERFORMANCE_TITLE_CAPITALIST :Kapitalist @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indisk rupi (IN STR_GAME_OPTIONS_CURRENCY_IDR :Indonesisk Rupiah (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaysisk Ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Kør i venstre side -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Kør i højre side - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Bynavne: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Vælg stil for bynavne - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Engelske -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Franske -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Tyske -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Engelske (ekstra) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latin-Amerikanske -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Fjollede -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Svenske -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Hollandske -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finske -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polske -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovakiske -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norske -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungarske -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Østrigske -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumænske -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tjekkiske -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Schweiziske -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danske -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Tyrkiske -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italienske -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalanske - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatisk gemning STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Vælg interval imellem automatisk gemning @@ -1025,22 +1006,21 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Indstill STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Afmærk dette felt for at v-synkronisere skærmen. Ændringer af indstillingen er først effektiv efter spillet er genstartet. Fungerer kun med hardware-acceleration aktiveret. +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Nuværende fører: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}grænseflade størrelse -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Vælg den grænseflade størrelse du ønsker at benytte +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Interface størrelse +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Træk skyderen for at indstille grænsefladestørrelsen. Hold Ctrl nede for kontinuerlig justering +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Automatisk registrering af størrelse +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marker dette felt for automatisk at registrere grænsefladestørrelse -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(auto-bestem) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dobbelt størrelse -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quad (4x) størrelse +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Skalere facetter +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marker dette afkrydsningsfelt for at skalere facetter efter grænsefladestørrelse -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Skriftstørrelse -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Vælg skriftstørrelsen du ønsker i grænsefladen - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(auto-bestem) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dobbelt størrelse -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quad (4x) størrelse +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafik @@ -1092,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Eksempe STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 pund (£) i din valuta STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Skift brugerdefinerede møntfodsparametre -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimalt antal modstandere: {ORANGE}{COMMA} - STR_NONE :Ingen STR_FUNDING_ONLY :Kun finansiering STR_MINIMAL :Minimal @@ -1143,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Tempereret klima +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Arktisk klima +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Tropisk klima +STR_CLIMATE_TOYLAND_LANDSCAPE :Legetøjsland + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Meget fladt STR_TERRAIN_TYPE_FLAT :Fladt @@ -1153,9 +1137,10 @@ STR_TERRAIN_TYPE_CUSTOM :Brugerdefineret STR_TERRAIN_TYPE_CUSTOM_VALUE :Brugerdefineret højde ({NUM}) ###length 4 +STR_CITY_APPROVAL_LENIENT :Lempelig STR_CITY_APPROVAL_TOLERANT :Tolerant STR_CITY_APPROVAL_HOSTILE :Fjendtlig -STR_CITY_APPROVAL_PERMISSIVE :Passiv +STR_CITY_APPROVAL_PERMISSIVE :Passiv (ingen indvirkning på virksomhedens handlinger) STR_WARNING_NO_SUITABLE_AI :{WHITE}Der blev ikke fundet en egnet computer-spiller...{}Du kan downloade flere forskellige computer-spillere gennem 'Online Indhold'. @@ -1221,6 +1206,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Højre STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maksimum startlån: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maksimumbeløb et selskab kan låne (uden at tage inflation i betragtning) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :No loan {RED}Kræver, at Game Script leverer indledende midler STR_CONFIG_SETTING_INTEREST_RATE :Lånerente: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Lånerente; kontrollerer også inflationen hvis aktiveret @@ -1256,8 +1244,8 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Hvis aktiveret, STR_CONFIG_SETTING_DISASTERS :Katastrofer: {STRING} STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Slå katastrofer, som lejlighedsvis kan blokere eller ødelægge køretøjer eller infrastruktur, til og fra -STR_CONFIG_SETTING_CITY_APPROVAL :Byrådets holdning til omstrukturering: {STRING} -STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Vælg hvor meget selskaber støj og miljømæssige skader påvirker byvurdering og fremtidige byggeretigheder i området +STR_CONFIG_SETTING_CITY_APPROVAL :Byrådets holdning til områdeomlægning: {STRING} +STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Vælg, hvor meget støj- og miljøskader fra virksomheder påvirker deres byvurdering og yderligere byggehandlinger i byen STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :Højdegrænse for kortet: {STRING} STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_HELPTEXT :Indstil den maksimale højde af kortets landskab. Med "(auto)" bliver en god værdi valgt efter landskabsgenerering @@ -1447,6 +1435,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Bredde af linje STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Vis navn på NewGRF i byg fartøj vinduet: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Tilføjer en linje til byg fartøj vinduet som viser, hvilken NewGRF det valgte fartøj stammer fra. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Vis de laster, køretøjerne kan bære i listevinduerne {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Hvis det er aktiveret, vises køretøjets transportable last over det på køretøjslisterne STR_CONFIG_SETTING_LANDSCAPE :Landskab: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landskaber definerer grundlæggende gameplay-scenarier med forskellige godstyper og krav for byers vækst. NewGRF og spilscripts giver dog mulighed for yderligere styring. @@ -1501,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Forbedret STR_CONFIG_SETTING_ROAD_SIDE :Vejkøretøjer: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Vælg køre side +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Kør i venstre side +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Kør i højre side + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotér højdekort: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Mod uret @@ -1527,7 +1521,13 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Grøn STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Mørkegrøn STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violet +STR_CONFIG_SETTING_LINKGRAPH_COLOURS :Overlejringsfarver til lastflow: {STRING} +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_HELPTEXT :Indstil det farveskema, der bruges til laststrømsoverlejringen. ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :Grøn til rød (original) +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Grøn til blå +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Grå til rød +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :Gråtoner STR_CONFIG_SETTING_SCROLLMODE :Visningsport bevægelse: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Virkemåde for bevægelse af kortet @@ -1928,13 +1928,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Tag {STRING} da STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tid taget for hver genberegning af et forbindelsesgrafkomponent. Når en genberegning startes, skabes en tråd som er tilladt at køre dette antal dage. Jo kortere du sætter denne indstilling, jo mere sandsynligt er det at tråden ikke er færdig når det er meningen. Så stopper spillet indtil den er ("lag"). Jo længere du sætter denne indstilling, jo længere tager det for distributionen at blive opdateret når ruter ændres. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distributionsmodel for passagerer: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symmetrisk" betyder at omtrent det samme antal passagerer vil rejse fra en station A til en station B som fra B til A. "asymmetrisk" betyder at vilkårlige antal passagerer kan rejse i hver retning. "manuel" betyder at ingen automatisk distribution vil finde sted for passagerer. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetrisk" betyder, at omtrent det samme antal passagerer vil gå fra en station A til en station B som fra B til A. "Asymmetrisk" betyder, at vilkårlige antal passagerer kan gå i begge retninger. "Manuel" betyder, at der ikke finder nogen automatisk distribution sted for passagerer. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Distributionsmodel for post: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"symmetrisk" betyder at omtrent den samme mængde post vil blive sendt fra en station A til en station B som fra B til A. "asymmetrisk" betyder at vilkårlige mængder post kan blive sendt i hver retning. "manuel" betyder at ingen automatisk distribution vil finde sted for post. -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Distributionsmodel for PANSRET lastklasse: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :PANSRET lastklassen indeholder værdigenstande i det tempererede klima, diamanter i det subtropiske klima, eller guld i det subarktiske klima. NewGRF kan ændre dette. "symmetrisk" betyder at omtrent den samme mængde af denne last vil blive sendt fra en station A til en station B som fra B til A. "asymmetrisk" betyder at vilkårlige mængder af denne last kan blive sendt i hver retning. "manuel" betyder at ingen automatisk distribution vil finde sted for denne last. Det anbefales at sætte denne indstilling til assymetrisk eller manuel når der spilles subarktisk, da banker ikke sender guld tilbage til guldminer. For tempereret og subtropisk kan du også vælge symmetrisk, da banker vil sende værdigenstande tilbage til oprindelsesbanken for et læs værdigenstande. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"symmetrisk" betyder, at der sendes omtrent den samme mængde post fra en station A til en station B som fra B til A. "asymmetrisk" betyder, at vilkårlige mængder post kan sendes i begge retninger. "Manuel" betyder, at der ikke finder automatisk distribution sted for post. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Distributionsmodel for PANSRET last-klasse: {STRING} +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :PANSRET last-klasse indeholder værdigenstande i tempereret, diamanter i det subtropiske eller guld i det subarktiske klima. NewGRF'er kan ændre det. "Symmetrisk" betyder, at omtrent den samme mængde af denne last vil blive sendt fra en station A til en station B som fra B til A. "Asymmetrisk" betyder, at vilkårlige mængder af denne last kan sendes i begge retninger. "Manuel" betyder, at der ikke finder nogen automatisk distribution sted for den pågældende last. Det anbefales at indstille dette til asymmetrisk eller manuel, når du spiller subarktisk eller subtropisk, da banker kun modtager gods i disse klimaer. For tempereret kan du også vælge symmetrisk, da banker sender værdigenstande tilbage til oprindelsesbanken. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Distributionsmodel for andre lastklasser: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"symmetrisk" betyder at omtrent den samme mængde last vil blive sendt fra en station A til en station B som fra B til A. "asymmetrisk" betyder at vilkårlige mængder last kan blive sendt i hver retning. "manuel" betyder at ingen automatisk distribution vil finde sted for disse laster. Du vil nok ønske at sætte dette til "asymmetrisk" eller manuel. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asymmetrisk" betyder, at vilkårlige mængder last kan sendes i begge retninger. "manuel" betyder, at der ikke finder nogen automatisk distribution sted for disse laster. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuel STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asymmetrisk @@ -2029,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Vend automatisk STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Tillad tog at vende ved et signal, hvis det har ventet i lang tid ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Anbefalet) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Anbefalet) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Skift indstillingsværdi @@ -2072,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK} Topresu STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Indstillinger STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF indstillinger STR_INTRO_ONLINE_CONTENT :{BLACK}Tjek Online Indhold -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI/Spilscript indstillinger +STR_INTRO_AI_SETTINGS :{BLACK}AI Indstillinger +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Indstillinger for spilscript STR_INTRO_QUIT :{BLACK}Afslut STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Start et nyt spil. Ctrl+Klik springer kortindstillingerne over. @@ -2092,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Hvis top STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Skærm indstillinger STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Vis NewGRF-indstillinger STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Tjek for nyt og opdateret indhold til download -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Vis computerspiller/spilscript indstillinger +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Vis AI indstillinger +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Vis indstillinger for spilscript STR_INTRO_TOOLTIP_QUIT :{BLACK}Afslut 'OpenTTD' STR_INTRO_BASESET :{BLACK} Det aktuelt valgte base grafiksæt mangler {NUM} sprite {P "" s}. Se venligst efter opdateringer til basesættet. @@ -2112,7 +2114,7 @@ STR_ABANDON_SCENARIO_QUERY :{YELLOW}Er du s # Cheat window STR_CHEATS :{WHITE}Snydefunktioner STR_CHEATS_TOOLTIP :{BLACK}Checkbokse viser, om du har brugt denne snydefunktion før -STR_CHEATS_NOTE :{BLACK}Bemærk: Al anvendelse af disse indstillinger bliver registreret i det gemte spil +STR_CHEATS_NOTE :{BLACK}Bemærk: Alle anvendelser af disse indstillinger bliver registreret i det gemte spil STR_CHEAT_MONEY :{LTBLUE}Forøg kassebeholdning med {CURRENCY_LONG} STR_CHEAT_CHANGE_COMPANY :{LTBLUE}Spiller som firmaet: {ORANGE}{COMMA} STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magisk bulldozer (nedriv ting, som normalt ikke kan fjernes): {ORANGE}{STRING} @@ -2124,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Ændre STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Skift år STR_CHEAT_SETUP_PROD :{LTBLUE}Aktiver modifikation af produktion: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Tempereret klima -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Arktisk klima -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Tropisk klima -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Legetøjsland - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Farvetema @@ -2362,7 +2358,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nyt selskab) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Etabler et nyt selskab og tilslut dig det STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Dette er dig STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Dette er værten for dette spil -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" er} / {NUM} selskab{P "" er} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" er} - {NUM}/{NUM} selska{P b er} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Antallet af aktuelt tilsluttede klienter, antal virksomheder og maksimalt antal virksomheder tilladt af serveradministratoren # Matches ConnectionType ###length 5 @@ -2522,7 +2519,7 @@ STR_CONTENT_SEARCH_EXTERNAL :{BLACK}Søg på STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP :{BLACK}Søgeresultat ikke tilgængeligt på OpenTTD's indholdstjeneste for websteder som ikke er associeret med OpenTTD STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}Du forlader OpenTTD! STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER :{WHITE}Betingelserne for download af indhold fra eksterne websteder varierer.{}Du må referere til de eksterne sites for vejledning i hvordan indholdet skal installeres i OpenTTD.{} Ønsker du at fortsætte? -STR_CONTENT_FILTER_TITLE :{BLACK}Tag/navngiv filter: +STR_CONTENT_FILTER_TITLE :{BLACK}søge filter: STR_CONTENT_OPEN_URL :{BLACK}Besøg hjemmeside STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Besøg hjemmesiden for dette indhold STR_CONTENT_DOWNLOAD_CAPTION :{BLACK}Download @@ -2590,7 +2587,7 @@ STR_TRANSPARENT_SIGNS_TOOLTIP :{BLACK}Skift ge STR_TRANSPARENT_TREES_TOOLTIP :{BLACK}Skift gennemsigtighed for træer. CTRL+Klik for at låse værdi. STR_TRANSPARENT_HOUSES_TOOLTIP :{BLACK}Skift gennemsigtighed for huse. CTRL+Klik for at låse værdi. STR_TRANSPARENT_INDUSTRIES_TOOLTIP :{BLACK}Skift gennemsigtighed for industrier. CTRL+Klik for at låse værdi. -STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Skift gennemsigtighed for konstruktioner som stationer, remiser og waypoint. Ctrl+klik låser. +STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Skift gennemsigtighed for konstruktioner som stationer, remiser og rutepunkt. Ctrl+klik låser. STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Skift gennemsigtighed for broer. CTRL+Klik for at låse værdi. STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Skift gennemsigtighed for strukturer som fyrtårne og antenner. CTRL+Klik for at låse værdi. STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Slå transparens til/fra for køreledninger. CTRL+klik for at låse. @@ -2609,6 +2606,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}mættet STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}overbelastet +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} transporteres pr. måned fra {STATION} to {STATION} ({COMMA}% of capacity){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} transporteres tilbage ({COMMA}% of capacity) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Gennemsnitlig rejsetid: {NUM}{NBSP}dag{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Vis dækningsområde STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Fra @@ -2617,13 +2619,14 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Marker i STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Marker dækningsområdet af den foreslåede placering STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Accepterer: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Forsyner: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Vedligeholdelsesomkostninger: {GOLD}{CURRENCY_SHORT}/yr # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Sammenkæd station STR_JOIN_STATION_CREATE_SPLITTED_STATION :{YELLOW}Byg en separat station -STR_JOIN_WAYPOINT_CAPTION :{WHITE}Forbind waypoint -STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT :{YELLOW}Byg et separat waypoint +STR_JOIN_WAYPOINT_CAPTION :{WHITE}Forbind rutepunkt +STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT :{YELLOW}Byg et separat rutepunkt # Generic toolbar STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE :{BLACK}Deaktiveret da der aktuelt ikke er nogen fartøjer tilgængelige for denne infrastruktur @@ -2637,12 +2640,12 @@ STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Magnetskinnekon STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Byg jernbane. Ctrl skifter mellem at bygge og fjerne elementer. Shift skifter mellem at bygge og vise prisoverslag. STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Byg jernbane med auto-jernbane-værktøj. Ctrl skifter mellem at bygge og fjerne elementer. Shift skifter mellem at bygge og vise prisoverslag. STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Byg en remise (til køb og servicering af tog). Shift skifter mellem at bygge og vise prisoverslag. -STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Ombyg jernbane til waypoint. Ctrl muliggør sammenslutning af waypoint. Shift skifter mellem at bygge og vise prisoverslag. +STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Ombyg jernbane til rutepunkt. Ctrl muliggør sammenslutning af rutepunkt. Shift skifter mellem at bygge og vise prisoverslag. STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Byg en banegård. Ctrl muliggør sammenslutning af stationer. Shift skifter mellem at bygge og vise prisoverslag. STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Byg jernbanesignaler. Ctrl skifter mellem semaforer og lyssignaler.{}Hvis musen trækkes langs en lige strækning, bygges signaler med jævne mellemrum. Hold Ctrl nede for at bygge signaler indtil næste kryds.{}Ctrl+klik skifter mellem at åbne eller ikke åbne signalvælgeren. Shift skifter mellem at bygge og vise prisoverslag. STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Byg jernbanebro. Shift skifter mellem at bygge og vise prisoverslag. STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Byg jernbanetunnel. Shift skifter mellem at bygge og vise prisoverslag. -STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Skift mellem at bygge og fjerne jernbaneskinner, signaler, waypoints og stationer. Hold Ctrl nede for også at fjerne togspor fra waypoints og stationer. +STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Skift mellem at bygge og fjerne jernbaneskinner, signaler, rutepunkter og stationer. Hold Ctrl nede for også at fjerne togspor fra rutepunkter og stationer. STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Ombyg/opgradér typen af jernbane. Shift skifter mellem at bygge og vise prisoverslag. STR_RAIL_NAME_RAILROAD :Jernbane @@ -2655,8 +2658,8 @@ STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION :{WHITE}Retning STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP :{BLACK}Vælg orientering af remise # Rail waypoint construction window -STR_WAYPOINT_CAPTION :{WHITE}Waypoint -STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Vælg udseende af waypoint +STR_WAYPOINT_CAPTION :{WHITE}Rutepunkt +STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Vælg udseende af rutepunkt # Rail station construction window STR_STATION_BUILD_RAIL_CAPTION :{WHITE}Valg af banegård @@ -2673,7 +2676,7 @@ STR_STATION_BUILD_STATION_CLASS_TOOLTIP :{BLACK}Vælg hv STR_STATION_BUILD_STATION_TYPE_TOOLTIP :{BLACK}Vælg hvilken stationstype du vil bygge STR_STATION_CLASS_DFLT :Standard station -STR_STATION_CLASS_WAYP :Waypoints +STR_STATION_CLASS_WAYP :Rutepunkt # Signal window STR_BUILD_SIGNAL_CAPTION :{WHITE}Signalvælger @@ -2687,7 +2690,7 @@ STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP :{BLACK}Ensrette STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Standardsignal (elektrisk){}Dette er den mest almindelige type signal, og tillader kun et tog ad gangen på den samme signalblok STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}Indgangssignal (elektrisk){}Grønt så længe der er et eller flere grønne udgangssignaler fra den efterfølgende sporsektion. Ellers vises rødt. STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Udgangssignal (elektrisk){}Fungerer som et normalt signal, men er nødvendigt for at vise den korrekte farve ved indgangs- og kombisignaler. -STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Kombisignal (elektrisk){}Kombisignalet fungerer både som indgangs- og udgangssignal. Dette muliggør opbygning af store forgreninger af signaler. +STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Kombi signal (elektrisk){}Kombi signalet fungerer både som indgangs- og udgangssignal. Dette muliggør opbygning af store forgreninger af signaler. STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Togvejssignal (elektrisk){}Et togvejssignal tillader, at mere en et tog ad gangen kan køre inden for en signalblok, hvis toget kan reservere en togvej til et sikkert sted at stoppe. Togvejssignaler kan passeres fra bagsiden. STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Ensrettet togvejssignal (elektrisk){}Et togvejssignal tillader, at mere en et tog ad gangen kan køre inden for en signalblok, hvis toget kan reservere en togvej til et sikkert sted at stoppe. Ensrettede togvejssignaler kan ikke passeres fra bagsiden. STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Signalombygning{}Når denne er valgt, vil klik på et eksisterende signal ombygge det til den valgte signaltype og -variant. Ctrl vil skifte den eksisterende signalvariant. Shift skifter mellem at bygge og vise prisoverslag. @@ -2699,8 +2702,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Forøg t STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Vælg jernbanebro STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Vælg vejbro STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Valg af bro - klik på din foretrukne brotype for at bygge den -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Hængebro, stål STR_BRIDGE_NAME_GIRDER_STEEL :Bjælkebro, stål STR_BRIDGE_NAME_CANTILEVER_STEEL :Gerberbro, stål @@ -2808,7 +2813,7 @@ STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Køb lan # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Objekt valg -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Vælg objektet der skal bygges. Shift skifter mellem at bygge og vise prisoverslag. +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Vælg objektet der skal bygges. Shift skifter mellem at bygge og vise prisoverslag STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Vælg hvilken objekttype du vil bygge STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Forvisning af objektet STR_OBJECT_BUILD_SIZE :{BLACK}Størrelse: {GOLD}{NUM} x {NUM} felter @@ -2852,6 +2857,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Tilfæld STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Grundlæg et tilfældigt sted STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Mange tilfældige byer STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Dæk kortet med tilfældigt placerede byer +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Udvid alle byer +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Få alle byer til at vokse lidt STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Bynavn: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Indtast bynavn @@ -2993,7 +3000,7 @@ STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA :Fragtcentral STR_LAI_STATION_DESCRIPTION_BUS_STATION :Rutebilstation STR_LAI_STATION_DESCRIPTION_SHIP_DOCK :Havn STR_LAI_STATION_DESCRIPTION_BUOY :Bøje -STR_LAI_STATION_DESCRIPTION_WAYPOINT :Waypoint +STR_LAI_STATION_DESCRIPTION_WAYPOINT :Rutepunkt STR_LAI_WATER_DESCRIPTION_WATER :Vand STR_LAI_WATER_DESCRIPTION_CANAL :Kanal @@ -3116,7 +3123,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Spil Det STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Ingen information til rådighed STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter-udtryk: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter udtryk: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Overskriv fil STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Er du sikker på du vil overskrive den eksisterende fil? STR_SAVELOAD_DIRECTORY :{STRING} (Mappe) @@ -3130,6 +3137,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kortstø STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Vælg kortets størrelse i fliser. Antallet af tilgængelige fliser vil være en anelse mindre STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Antal byer: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Bynavne: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Vælg stil for bynavne STR_MAPGEN_DATE :{BLACK}Dato: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Antal industrier: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Højeste bjergtop: @@ -3143,13 +3152,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Ørkend STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Forøger ørkendækningen med ti procent STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Sænker ørkendækningen med ti procent STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Terrængenerator: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terræntype: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Havniveau +STR_MAPGEN_SEA_LEVEL :{BLACK}Havniveau STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Floder: STR_MAPGEN_SMOOTHNESS :{BLACK}Blødhed: STR_MAPGEN_VARIETY :{BLACK}Varietet af distributionen: STR_MAPGEN_GENERATE :{WHITE}Generer +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF indstillinger +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Vis indstillinger for NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}AI indstillinger +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Vis AI indstillinger +STR_MAPGEN_GS_SETTINGS :{BLACK}Indstillinger for spilscript +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Vis indstillinger for spilscript + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Engelske +STR_MAPGEN_TOWN_NAME_FRENCH :Franske +STR_MAPGEN_TOWN_NAME_GERMAN :Tyske +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Engelske (ekstra) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latin-Amerikanske +STR_MAPGEN_TOWN_NAME_SILLY :Fjollede +STR_MAPGEN_TOWN_NAME_SWEDISH :Svenske +STR_MAPGEN_TOWN_NAME_DUTCH :Hollandske +STR_MAPGEN_TOWN_NAME_FINNISH :Finske +STR_MAPGEN_TOWN_NAME_POLISH :Polske +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovakiske +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norske +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungarske +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Østrigske +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumænske +STR_MAPGEN_TOWN_NAME_CZECH :Tjekkiske +STR_MAPGEN_TOWN_NAME_SWISS :Schweiziske +STR_MAPGEN_TOWN_NAME_DANISH :Danske +STR_MAPGEN_TOWN_NAME_TURKISH :Tyrkiske +STR_MAPGEN_TOWN_NAME_ITALIAN :Italienske +STR_MAPGEN_TOWN_NAME_CATALAN :Catalanske # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kortkanter: @@ -3258,12 +3295,12 @@ STR_NEWGRF_SETTINGS_INCOMPATIBLE :{RED}Ikke kompa # NewGRF save preset window STR_SAVE_PRESET_CAPTION :{WHITE}Gem forudindstilling STR_SAVE_PRESET_LIST_TOOLTIP :{BLACK} Liste over tilgængelige presets, skal du vælge en til at kopiere det til gemte navn nedenfor -STR_SAVE_PRESET_TITLE :{BLACK}Indtast et navn til den forudindstillede +STR_SAVE_PRESET_TITLE :{BLACK}Indtast et navn til det forudindstillede STR_SAVE_PRESET_EDITBOX_TOOLTIP :{BLACK}Aktuelt valgte navn til den forudindstillede at gemme STR_SAVE_PRESET_CANCEL :{BLACK}Annuller STR_SAVE_PRESET_CANCEL_TOOLTIP :{BLACK}Du må ikke ændre den forudindstillede STR_SAVE_PRESET_SAVE :{BLACK}Gem -STR_SAVE_PRESET_SAVE_TOOLTIP :{BLACK}Gem forudindstilling til den aktuelle valgte navn +STR_SAVE_PRESET_SAVE_TOOLTIP :{BLACK}Gem forudindstilling til det valgte navn # NewGRF parameters window STR_NEWGRF_PARAMETERS_CAPTION :{WHITE}Ændre NewGRF parameterne @@ -3295,6 +3332,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Forrige STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Fortsæt til den forrige normal sprite, spring pseudo/omfarvning/font-sprites over og omløb fra starten til slutningen STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Repræsentation af den markerede sprite. Justeringen ignoreres når denne sprite tegnes. STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Flyt spriten rundt for at ændre X- og Y-forskydningen. Ctrl+Klik for at flytte spriten otte enheder af gangen + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Forskudt centreret +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centreret + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Crosshair + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Nulstil relativ STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Nulstil den nuværende relative forskydning STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X-forskydning: {NUM}, Y-forskydning: {NUM} (Absolut) @@ -3309,13 +3353,13 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Advarsel: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Fejl: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatalt: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}En fatal NewGRF-fejl er opstået:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Der er opstået en NewGRF-fejl:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}NewGRF "{STRING}" har returneret med en fatal fejl:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF "{STRING}" har returneret en fejl:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} virker ikke med TTDPatch-versionen rapporteret af OpenTTD. -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} er beregnet til {STRING}-versionen af TTD. +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} er beregnet til {STRING}-version af TTD STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} er designet til brug sammen med {STRING} STR_NEWGRF_ERROR_INVALID_PARAMETER :Ugyldig parameter for {1:STRING}: parameter {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} skal indlæses før {STRING}. +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} skal indlæses inden {STRING}. STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} skal indlæses efter {STRING}. STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} kræver OpenTTD version {STRING} eller højere. STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF filen, som den er lavet til at oversætte, @@ -3452,14 +3496,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Køb eksklusive STR_LOCAL_AUTHORITY_ACTION_BRIBE :Bestik de lokale myndigheder ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW} Start en lille reklamekampagne for at tiltrække flere passagerer og last til dine stationer.{}Giver en midlertidig forbedring af stationsbedømmelsen i en lille radius omkring bymidten.{}Pris: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Start en mellem reklamekampagne, for at tiltrække flere passagerer og last til dine stationer.{}Giver en midlertidig forbedring af stationsbedømmelsen i en mellemstor radius omkring bymidten.{}Pris: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Start en stor reklamekampagne, for at tiltrække flere passagerer og last til dine stationer.{}Giver en midlertidig forbedring af stationsbedømmelsen i en stor radius omkring bymidten.{}Pris: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Finansiér vejfornyelse i midtbyen.{}Forårsager store forstyrrelser for vejtrafikken i de næste 6 måneder.{}Pris: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Byg en statue til ære for dit selskab.{}Giver en permanent forbedring af stationsbedømmelser i denne by.{}Pris: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Finansiér opførelse af nye bygninger i byen.{}Giver en midlertidig forøgelse af byens væksthastighed.{}Pris: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Køb et års eksklusive rettigheder til transport i byen.{}De lokale myndigheder vil forbyde passagerer og last at bruge dine konkurrenters stationer.{}Prist: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Bestik de lokale myndigheder til at hæve din bedømmelse, med risiko for en stor straf hvis det bliver opdaget.{}Pris: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW} Start en lille reklamekampagne for at tiltrække flere passagerer og last til dine stationer.{}Giver en midlertidig forbedring af stationsbedømmelsen i en lille radius omkring bymidten.{}{POP_COLOUR}Pris: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Start en mellem reklamekampagne, for at tiltrække flere passagerer og last til dine stationer.{}Giver en midlertidig forbedring af stationsbedømmelsen i en mellemstor radius omkring bymidten.{}{POP_COLOUR}Pris: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Start en stor reklamekampagne, for at tiltrække flere passagerer og last til dine stationer.{}Giver en midlertidig forbedring af stationsbedømmelsen i en stor radius omkring bymidten.{}{POP_COLOUR}Pris: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Finansiér vejfornyelse i midtbyen.{}Forårsager store forstyrrelser for vejtrafikken i de næste 6 måneder.{}{POP_COLOUR}Pris: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Byg en statue til ære for dit selskab.{}Giver en permanent forbedring af stationsbedømmelser i denne by.{}{POP_COLOUR}Pris: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Finansiér opførelse af nye bygninger i byen.{}Giver en midlertidig forøgelse af byens væksthastighed.{}{POP_COLOUR}Pris: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Køb et års eksklusive rettigheder til transport i byen.{}De lokale myndigheder vil forbyde passagerer og last at bruge dine konkurrenters stationer.{}{POP_COLOUR}Pris: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Bestik de lokale myndigheder til at hæve din bedømmelse, med risiko for en stor straf hvis det bliver opdaget.{}{POP_COLOUR}Pris: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Mål @@ -3600,36 +3644,50 @@ STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}Forhindr # Waypoint/buoy view window STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT} -STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Centrer skærmen over vejpunktets lokalitet. Ctrl+Klik åbner et nyt vindue ved waypointets lokalitet. -STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}Omdøb waypoint +STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Centrer skærmen over vejpunktets lokalitet. Ctrl+Klik åbner et nyt vindue ved rutepunktets lokalitet. +STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}Omdøb rutepunkt STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Centrér skærmen ved bøjens placering. Ctrl+klik åbner et nyt vindue ved bøjens placering STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}Ændre navnet på bøjen -STR_EDIT_WAYPOINT_NAME :{WHITE}Omdøb waypoint +STR_EDIT_WAYPOINT_NAME :{WHITE}Omdøb rutepunkt # Finances window STR_FINANCES_CAPTION :{WHITE}{COMPANY} Finanser {BLACK}{COMPANY_NUM} STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}Indtægt +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Driftsudgifter +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Kapitaludgifter ###length 13 -STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Konstruktion +STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Byggeri STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Nye køretøjer STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Togdriftsomkostning STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Køretøjsdriftsomkostning STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Flydriftsomkostning STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Skibsdriftsomkostning +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Infrastruktur +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Tog +STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}Vejkøretøjer +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Luftfartøj +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Skibe STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Renter STR_FINANCES_SECTION_OTHER :{GOLD}Andet -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} -STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} +STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Overskud STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Bank balance +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Egenkapital STR_FINANCES_LOAN_TITLE :{WHITE}Lån +STR_FINANCES_INTEREST_RATE :{WHITE}Renter på lån: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maks. lån: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Lån {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Forøg lånet. Ctrl+Klik låner så meget som muligt STR_FINANCES_REPAY_BUTTON :{BLACK}Tilbagebetal {CURRENCY_LONG} @@ -3760,6 +3818,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Send ins STR_VEHICLE_LIST_REPLACE_VEHICLES :Udskift køretøjer STR_VEHICLE_LIST_SEND_FOR_SERVICING :Send til eftersyn STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Afkast i år: {CURRENCY_LONG} (sidste år: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Send til remise STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Send til værksted @@ -3851,6 +3911,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Maks. tr STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Rækkevidde: {GOLD}{COMMA} felter STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Fly type: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Alle fragttyper +STR_CARGO_TYPE_FILTER_FREIGHT :Fragt +STR_CARGO_TYPE_FILTER_NONE :Ingen + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Togvalgsliste - klik på et køretøj for mere information STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Liste over køretøjstyper - klik på køretøj for information @@ -3891,7 +3956,7 @@ STR_BUY_VEHICLE_AIRCRAFT_RENAME_BUTTON :{BLACK}Omdøb STR_BUY_VEHICLE_TRAIN_RENAME_TOOLTIP :{BLACK}Omdøb tog-/togvognstypen STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_TOOLTIP :{BLACK}Omdøb køretøjstypen STR_BUY_VEHICLE_SHIP_RENAME_TOOLTIP :{BLACK}Omdøb skibstypen -STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}Ømdøb flytypen +STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}Omdøb flytypen ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_HIDE_TOGGLE_BUTTON :{BLACK}skjule @@ -3903,7 +3968,7 @@ STR_BUY_VEHICLE_AIRCRAFT_HIDE_TOGGLE_BUTTON :{BLACK}skjul STR_BUY_VEHICLE_TRAIN_SHOW_TOGGLE_BUTTON :{BLACK}Vis STR_BUY_VEHICLE_ROAD_VEHICLE_SHOW_TOGGLE_BUTTON :{BLACK}Vis STR_BUY_VEHICLE_SHIP_SHOW_TOGGLE_BUTTON :{BLACK}Vis -STR_BUY_VEHICLE_AIRCRAFT_SHOW_TOGGLE_BUTTON :{BLACK}Display +STR_BUY_VEHICLE_AIRCRAFT_SHOW_TOGGLE_BUTTON :{BLACK}Vis ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Toggle skjule / vise af tog type @@ -4178,6 +4243,7 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Vægt: { STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Vægt: {LTBLUE}{WEIGHT_SHORT} {BLACK}Effekt: {LTBLUE}{POWER}{BLACK} Maks. hast.: {LTBLUE}{VELOCITY} {BLACK}Maks. trækkraft: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Overskud i år: {LTBLUE}{CURRENCY_LONG} (sidste år: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Årets resultat: {LTBLUE}{CURRENCY_LONG} (sidste år: {CURRENCY_LONG}) {BLACK}Mindste ydeevne: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Pålidelighed: {LTBLUE}{COMMA}% {BLACK}Nedbrud siden sidste service: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Bygget: {LTBLUE}{NUM}{BLACK} Værdi: {LTBLUE}{CURRENCY_LONG} @@ -4342,7 +4408,7 @@ STR_ORDER_GO_TO_NEAREST_DEPOT :Gå til nærmes STR_ORDER_GO_TO_NEAREST_HANGAR :Flyv til nærmeste hangar STR_ORDER_CONDITIONAL :Betinget ordrespring STR_ORDER_SHARE :Del ordrer -STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Indsæt en ny ordre før den markerede, eller i slutningen af ordrelisten. Ctrl laver stationsordrer med 'Vilkårlig fuld last', waypoint ordrer med 'Uden stop', og depotordrer med 'Service'. 'Deleordrer' eller Ctrl lader dette køretøj dele ordrer med det valgte køretøj. At klikke på et køretøj kopierer ordrer fra det pågældende køretøj. En depot ordre deaktiverer automatisk servicering af køretøjet +STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Indsæt en ny ordre før den markerede, eller i slutningen af ordrelisten. Ctrl laver stationsordrer med 'Vilkårlig fuld last', rutepunkt ordrer med 'Uden stop', og depotordrer med 'Service'. 'Deleordrer' eller Ctrl lader dette køretøj dele ordrer med det valgte køretøj. At klikke på et køretøj kopierer ordrer fra det pågældende køretøj. En depot ordre deaktiverer automatisk servicering af køretøjet STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Vis alle transportmidler, der deler denne ruteplan @@ -4452,19 +4518,19 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Startdat STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Vælg en dato som starttidspunkt for denne køreplan. Ctrl+Klik sætter starttidspunkt for denne køreplan, og distribuerer alle køretøjer der deler denne ordre ligeligt baseret på deres relative rækkefølge, hvis ordren er fuldstændigt tidsplanlagt STR_TIMETABLE_CHANGE_TIME :{BLACK}Ændre tid -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Ændre hvor lang tid den markerede ordre skal tage +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Ændre den tid, som den fremhævede rækkefølge skal tage. Ctrl+Click angiver tidspunktet for alle ordrer STR_TIMETABLE_CLEAR_TIME :{BLACK}Nulstil tid STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Nulstil tiden for den markerede ordre STR_TIMETABLE_CHANGE_SPEED :{BLACK}Ændr hastighedsbegrænsning -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Ændr den maksimale rejsehastighed for den markerede ordre +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Ændre den maksimale rejsehastighed for den fremhævede rækkefølge STR_TIMETABLE_CLEAR_SPEED :{BLACK}Nulstil hastighedsbegrænsning STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Nulstil den maksimale rejsehastighed for den markerede ordre STR_TIMETABLE_RESET_LATENESS :{BLACK}Nulstil forsinkelse -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Nulstil forsinkelses-tæller, så transportmidlet kommer til tiden +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Nulstil forsinkelsestælleren, så køretøjet kommer til tiden STR_TIMETABLE_AUTOFILL :{BLACK}Auto-udfyld STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Udfyld automatisk tidsplanen med tider for den næste tur (CTRL-klik for at forsøge at bevare ventetider) @@ -4511,12 +4577,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}En af de STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Computerspiller/script-debugvindue er kun tilgængeligt for serveren # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Konfiguration af computerspiller/spilscript +STR_AI_CONFIG_CAPTION_AI :{WHITE}AI konfiguration +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Konfiguration af spilscript STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Spilscriptet der vil bliver indlæst i næste spil -STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AIer der vil bliver loaded i næste spil +STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AI`er der vil bliver indlæst i næste spil STR_AI_CONFIG_HUMAN_PLAYER :Menneskelig spiller STR_AI_CONFIG_RANDOM_AI :Tilfældig computerspiller STR_AI_CONFIG_NONE :(ingen) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maksimalt antal modstandere: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Flyt op STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Flyt valgte computerspiller op i listen @@ -4524,12 +4592,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Flyt ned STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Flyt valgte computerspiller ned i listen STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spilscript -STR_AI_CONFIG_AI :{SILVER}KI'er +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametre +STR_AI_CONFIG_AI :{SILVER}AI'er -STR_AI_CONFIG_CHANGE :{BLACK}Vælg {STRING} -STR_AI_CONFIG_CHANGE_NONE :Ingen ændringer -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Spilscript +STR_AI_CONFIG_CHANGE_AI :{BLACK}Vælg AI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Vælg Spilscript STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Indlæs et andet script STR_AI_CONFIG_CONFIGURE :{BLACK}Konfigurer computerspiller STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Konfigurer parametre for script'et @@ -4544,7 +4611,7 @@ STR_AI_LIST_AUTHOR :{LTBLUE}Skaber: STR_AI_LIST_VERSION :{LTBLUE}Version: {ORANGE}{NUM} STR_AI_LIST_URL :{LTBLUE}URL: {ORANGE}{STRING} -STR_AI_LIST_ACCEPT :{BLACK}Accepter +STR_AI_LIST_ACCEPT :{BLACK}Godkend STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Vælg markeret script STR_AI_LIST_CANCEL :{BLACK}Afbryd STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Skift ikke script'et @@ -4557,10 +4624,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Fuldt ko STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Højdekort skærmbillede STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minikort skærmbillede -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametre STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spilscript +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spil Script STR_AI_SETTINGS_CLOSE :{BLACK}Luk STR_AI_SETTINGS_RESET :{BLACK}Nulstil STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4724,6 +4791,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... for STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Kan ikke lave industrier... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Kan ikke bygge {STRING} her... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Kan ikke bygge denne industritype her... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Kan ikke se industri STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... for tæt på en anden industribygning STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... det er nødvendigt at bygge en by først STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... kun en tilladt per by @@ -4738,6 +4806,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... skov STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE} ... kan kun bygges over snegrænsen STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE} ... kan kun bygges under snegrænsen +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Finansieringen mislykkedes. Prøv igen +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Der er ingen egnede steder at placere denne industri STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Der var ingen egnede steder for '{STRING}' industrier STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Skift kort generations parametre for at få et bedre kort @@ -4783,15 +4853,15 @@ STR_ERROR_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Det er n STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Det er nødvendigt at rive lufthavnen ned først # Waypoint related errors -STR_ERROR_WAYPOINT_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Støder op til mere end et eksisterende waypoint -STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT :{WHITE}For tæt på et andet waypoint +STR_ERROR_WAYPOINT_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}Støder op til mere end et eksisterende rutepunkt +STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT :{WHITE}For tæt på et andet rutepunkt -STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT :{WHITE}Kan ikke bygge waypoint for tog her... +STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT :{WHITE}Kan ikke bygge rutepunkt for tog her... STR_ERROR_CAN_T_POSITION_BUOY_HERE :{WHITE}Kan ikke placere en bøje her... -STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME :{WHITE}Kan ikke omdøbe waypoint... +STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME :{WHITE}Kan ikke omdøbe rutepunkt... -STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT :{WHITE}Kan ikke fjerne waypoint for tog her... -STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST :{WHITE}Jernbanewaypoint skal fjernes først +STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT :{WHITE}Kan ikke fjerne rutepunkt for tog her... +STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST :{WHITE}Jernbane-rutepunkt skal fjernes først STR_ERROR_BUOY_IN_THE_WAY :{WHITE}... der er en bøje i vejen STR_ERROR_BUOY_IS_IN_USE :{WHITE}... bøjen er i brug af et andet firma! @@ -4905,6 +4975,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Der er e STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... selskabets hovedkontor i vejen STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Kan ikke købe dette landområde... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... du ejer det allerede! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... grænse for objekt-konstruktion nået # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Kan ikke oprette gruppe... @@ -4977,6 +5048,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Kan ikke STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... fartøjet er ødelagt +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... Ikke alle køretøjer er identiske + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Ingen køretøjer vil være tilgængelige overhovedet STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Skift din NewGRF-konfiguration STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Ingen køretøjer er tilgængelige endnu @@ -5003,6 +5076,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Kan ikke STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... køretøj kan ikke køre til alle stationer STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... køretøj kan ikke køre til denne station STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... et køretøj, der deler denne ordre, kan ikke køre til den station +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... ikke alle køretøjer har de samme ordrer +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... Ikke alle køretøjer deler ordrer STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Kan ikke dele ordreliste... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Kan ikke ophøre med at dele ordrer-liste... @@ -5010,6 +5085,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Kan ikke STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... for langt fra forrige destination STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... fly har ikke nok rækkevidde +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Der er ingen togstation her +STR_ERROR_NO_BUS_STATION :{WHITE}Der er ingen bus station her +STR_ERROR_NO_TRUCK_STATION :{WHITE}Der er ingen lastbilstation her +STR_ERROR_NO_DOCK :{WHITE}Der er ingen skibsdok +STR_ERROR_NO_AIRPORT :{WHITE}Der er ingen Lufthavn/Helikopterplads +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Der er ingen stop med en kompatibel vejtype +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Der er ingen stop med en kompatibel sporvognstype +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Der er ingen stop, der er egnede til leddelte vejkøretøjer.{}Leddelte vejkøretøjer kræver et gennemkørselsstop, ikke et slutstop +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Dette fly kan ikke lande på denne heliport +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Denne helikopter kan ikke lande i denne lufthavn +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Der er ikke noget Jernbane vejpunkt +STR_ERROR_NO_BUOY :{WHITE}Der er ingen bøje + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kan ikke lave køreplan for transportmiddel... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Transportmidler kan kun vente ved stationer. @@ -5440,8 +5529,8 @@ STR_FORMAT_BUOY_NAME :{TOWN} Bøje STR_FORMAT_BUOY_NAME_SERIAL :{TOWN} Bøje #{COMMA} ###length 2 -STR_FORMAT_WAYPOINT_NAME :{TOWN} Waypoint -STR_FORMAT_WAYPOINT_NAME_SERIAL :{TOWN} Waypoint #{COMMA} +STR_FORMAT_WAYPOINT_NAME :{TOWN} Rutepunkt +STR_FORMAT_WAYPOINT_NAME_SERIAL :{TOWN} Rutepunkt #{COMMA} ###length 6 STR_FORMAT_DEPOT_NAME_TRAIN :{TOWN} Tog Depot diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 191973626f2e2..3285d54ce01b2 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}pk STR_UNITS_POWER_METRIC :{COMMA}{NBSP}pk STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}pk/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}pk/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}pk/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}pk/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}pk/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -225,9 +235,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filtertekst: -STR_LIST_FILTER_OSKTITLE :{BLACK}Filtertekst invoeren -STR_LIST_FILTER_TOOLTIP :{BLACK}Voer een woord in waarop de lijst wordt gefilterd +STR_LIST_FILTER_TITLE :{BLACK}Filter: +STR_LIST_FILTER_OSKTITLE :{BLACK}Voer een of meer woorden in waarop de lijst wordt gefilterd +STR_LIST_FILTER_TOOLTIP :{BLACK}Voer een of meer woorden in waarop de lijst wordt gefilterd STR_TOOLTIP_GROUP_ORDER :{BLACK}Selecteer de volgorde voor groeperen STR_TOOLTIP_SORT_ORDER :{BLACK}Selecteer de sorteerrichting (aflopend-oplopend) @@ -376,9 +386,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Stadsont STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industrieontwikkeling STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Wegenbouw STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Tramsporen bouwen -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Bomen planten. Shift schakelt tussen planten/inschatting van de kosten +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Bomen planten. Ctrl selecteert het gebied diagonaal. Shift schakelt tussen planten/inschatting van de kosten STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Bord plaatsen -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Object plaatsen. Shift schakelt tussen bouwen/inschatting van de kosten +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Object plaatsen. Ctrl selecteert een diagonaal gebied. Shift+klik wisselt tussen bouwen/verwachte kosten weergeven. # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Afsluiten # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Spelopties STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Instellingen -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI-/spelscriptinstellingen +STR_SETTINGS_MENU_AI_SETTINGS :AI-instellingen +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Spelscript-instellingen STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF-instellingen STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Doorzichtigheidsopties STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Plaatsnamen weergeven @@ -855,10 +866,10 @@ STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL :{BIG_FONT}{BLAC STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_COAL :{BIG_FONT}{BLACK}Nieuwe kolenader gevonden bij {INDUSTRY}!{}Men verwacht productieverdubbeling! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_OIL :{BIG_FONT}{BLACK}Nieuwe oliebronnen gevonden bij {INDUSTRY}!{}Men verwacht productieverdubbeling! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM :{BIG_FONT}{BLACK}Verbeterde landbouwmethoden bij {INDUSTRY} zorgen voor een verwachte productieverdubbeling! -STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH :{BIG_FONT}{BLACK}{STRING} productie van {INDUSTRY} stijgt met {COMMA}%! +STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH :{BIG_FONT}{BLACK}Productie van {STRING} door {INDUSTRY} stijgt met {COMMA}%! STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL :{BIG_FONT}{BLACK}Productie van {INDUSTRY} verlaagd met 50% STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM :{BIG_FONT}{BLACK}Insectenplaag zorgt voor ravage bij {INDUSTRY}!{}Productie gezakt met 50% -STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH :{BIG_FONT}{BLACK}{STRING} productie van {INDUSTRY} daalt met {COMMA}%! +STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH :{BIG_FONT}{BLACK}Productie van {STRING} door {INDUSTRY} daalt met {COMMA}%! ###length VEHICLE_TYPES STR_NEWS_TRAIN_IS_WAITING :{WHITE}{VEHICLE} wacht in remise @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indiase rupee ( STR_GAME_OPTIONS_CURRENCY_IDR :Indonesische roepia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Maleisische Ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Links rijden -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Rechts rijden - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Plaatsnamen: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Stijl voor plaatsnamen kiezen - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Engels (Origineel) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Frans -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Duits -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Engels (Extra) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latijns-Amerikaans -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Zot -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Zweeds -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Nederlands -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Fins -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Pools -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slowaaks -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Noors -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hongaars -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Oostenrijks -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Roemeens -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tsjechisch -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Zwitsers -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Deens -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turks -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiaans -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalaans - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatisch opslaan STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Tijdsduur kiezen tussen automatisch opgeslagen spellen @@ -1011,7 +992,7 @@ STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Taal sel STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM}% voltooid) STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Volledig scherm -STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Vink dit vakje aan om OpenTTD in het volledige scherm te spelen +STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Vink dit vakje aan om OpenTTD op volledig scherm te spelen STR_GAME_OPTIONS_RESOLUTION :{BLACK}Schermresolutie STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}Selecteer de schermresolutie @@ -1025,25 +1006,23 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}De inste STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Selecteer dit vakje om het scherm verticaal te synchroniseren. De wijziging gaat pas in nadat je het spel opnieuw hebt opgestart. Werkt alleen als hardwareversnelling is ingeschakeld -STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Huidige chauffeur: {STRING} +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Huidige driver: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Menupuntgrootte -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Kiest de grootte van bedieningselementen +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Grootte gebruikersscherm +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Sleep de schuif om de grootte van het gebruikersscherm in te stellen. Hou Ctrl ingedrukt voor geleidelijke aanpassing +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Grootte automatisch detecteren +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Vink dit vakje aan om de grootte van het gebruikersscherm automatisch te detecteren -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(automatische detectie) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normaal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dubbele grootte -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :4x Grootte +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Randen schalen +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Vink dit vakje aan om randen te schalen op grootte van gebruikersscherm -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Lettergrootte -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Hiermee kies je hoe groot de letters op het scherm moeten zijn +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(auto-detect)Status: Vermist -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normaal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dubbele grootte -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Viervoudige grootte - -STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafische elementen +STR_GAME_OPTIONS_GRAPHICS :{BLACK}Weergave STR_GAME_OPTIONS_REFRESH_RATE :{BLACK}Verversingssnelheid weergeven STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP :{BLACK}Selecteer de gewenste schermverversingssnelheid @@ -1051,16 +1030,16 @@ STR_GAME_OPTIONS_REFRESH_RATE_ITEM :{NUM}Hz STR_GAME_OPTIONS_REFRESH_RATE_WARNING :{WHITE}Verversingssnelheden boven 60 Hz kunnen de prestaties beïnvloeden. STR_GAME_OPTIONS_BASE_GRF :{BLACK}Basisset voor graphics -STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Kiest de te gebruiken basisset voor grafische elementen +STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Selecteer de te gebruiken basisset voor grafische elementen STR_GAME_OPTIONS_BASE_GRF_STATUS :{RED}{NUM} ontbrekend{P "" e}/beschadigd{P "" e} bestand{P "" en} STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP :{BLACK}Aanvullende informatie over de basisset voor graphics STR_GAME_OPTIONS_BASE_SFX :{BLACK}Basisset voor geluidseffecten -STR_GAME_OPTIONS_BASE_SFX_TOOLTIP :{BLACK}Kiest de te gebruiken basisset voor geluidseffecten +STR_GAME_OPTIONS_BASE_SFX_TOOLTIP :{BLACK}Selecteer de te gebruiken basisset voor geluidseffecten STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP :{BLACK}Aanvullende informatie over de basisset voor geluidseffecten STR_GAME_OPTIONS_BASE_MUSIC :{BLACK}Basisset voor muziek -STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP :{BLACK}Kiest de te gebruiken basisset voor muziek +STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP :{BLACK}Selecteer de te gebruiken basisset voor muziek STR_GAME_OPTIONS_BASE_MUSIC_STATUS :{RED}{NUM} beschadigd{P "" e} bestand{P "" en} STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP :{BLACK}Aanvullende informatie over the basisset voor muziek @@ -1093,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Voorbee STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10.000 pond (£) in jouw munteenheid STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Aangepaste valutaparameters wijzigen -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maximaal aantal tegenstanders: {ORANGE}{COMMA} - STR_NONE :Geen STR_FUNDING_ONLY :Alleen gefinancierd STR_MINIMAL :Minimaal @@ -1144,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Gematigd landschap +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subarctisch landschap +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Subtropisch landschap +STR_CLIMATE_TOYLAND_LANDSCAPE :Speelgoedlandschap + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Zeer vlak STR_TERRAIN_TYPE_FLAT :Vlak @@ -1163,7 +1146,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}Geen bru # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Instellingen -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtertekst: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Alles uitvouwen STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Alles inklappen STR_CONFIG_SETTING_RESET_ALL :{BLACK}Alle waarden terugstellen @@ -1223,6 +1206,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Rechts STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maximale beginlening: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximaal bedrag dat een bedrijf kan lenen (zonder rekening te houden met de inflatie) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Geen lening {RED}Spelscript vereist voor aanvankelijk saldo STR_CONFIG_SETTING_INTEREST_RATE :Rente van lening: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Percentage rente op lening; bepaald ook het inflatiecijfer wanneer ingeschakeld @@ -1250,7 +1236,7 @@ STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Bouwkosten: {ST STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Het niveau van bouw- en aankoopkosten instellen STR_CONFIG_SETTING_RECESSIONS :Recessies: {STRING} -STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Wanneer dit is ingeschakeld, kunnen om de paar jaar recessies optreden. Tijdens een recessie is alle productie aanzienlijk lager (deze keert terug naar het vorige niveau als de recessie voorbij is). +STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Wanneer dit is ingeschakeld kunnen om de paar jaar recessies optreden. Tijdens een recessie is alle productie aanzienlijk lager (deze keert terug naar het vorige niveau als de recessie voorbij is). STR_CONFIG_SETTING_TRAIN_REVERSING :Niet toestaan dat treinen keren in stations: {STRING} STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Indien ingeschakeld zullen treinen niet omkeren in niet-eind stations, zelfs als er een kortere weg naar hun volgende bestemming is bij omkeren @@ -1275,7 +1261,7 @@ STR_CONFIG_SETTING_CATCHMENT :Meer realistisc STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Verzorgingsgebieden met verschillende groottes voor verschillende typen stations en luchthavens STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Stations van het bedrijf kunnen leveren aan industrieën met bijbehorend neutraal station: {STRING} -STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Wanneer dit is ingeschakeld, kunnen industrieën met bijbehorende stations (zoals olievelden) ook worden voorzien door stations van het bedrijf die in de buurt zijn gebouwd. Wanneer dit is uitgeschakeld, kunnen deze industrieën alleen worden voorzien door het bijbehorende station. Eventuele stations van het bedrijif in de buurt kunnen niet aan ze leveren; ook levert het bijbehorende station alleen aan de industrie zelf. +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Wanneer dit is ingeschakeld kunnen industrieën met bijbehorende stations (zoals olievelden) ook worden voorzien door stations van het bedrijf die in de buurt zijn gebouwd. Wanneer dit is uitgeschakeld kunnen deze industrieën alleen worden voorzien door het bijbehorende station. Eventuele stations van het bedrijif in de buurt kunnen niet aan ze leveren; ook levert het bijbehorende station alleen aan de industrie zelf. STR_CONFIG_SETTING_EXTRADYNAMITE :Verwijderen van meer stedelijke wegen, bruggen en tunnels toestaan: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Maakt het gemakkelijker om door de stad beheerde infrastructuur en gebouwen te verwijderen. @@ -1332,7 +1318,7 @@ STR_CONFIG_SETTING_MULTIPINDTOWN :Meerdere vergel STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :Normaal staat een stad niet meer dan één industrie van ieder type toe. Wanneer je deze optie inschakelt, accepteren steden meerdere industrieën van één soort. STR_CONFIG_SETTING_SIGNALSIDE :Seinen weergeven: {STRING} -STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :Kiest aan welke kant van het spoor seinen worden geplaatst +STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :Selecteer aan welke kant van het spoor seinen worden geplaatst ###length 3 STR_CONFIG_SETTING_SIGNALSIDE_LEFT :Links STR_CONFIG_SETTING_SIGNALSIDE_DRIVING_SIDE :Aan de rij zijde @@ -1449,6 +1435,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Breedte van de STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Naam van NewGRF weergeven in venster voor voertuigen bouwen: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Voeg een regel toe aan het venster voor voertuigen bouwen die aangeeft uit welke NewGRF het geselecteerde voertuig komt. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Mogelijke lading van voertuigen weergeven in lijstvensters {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Wanneer ingeschakeld, verschijnt de mogelijke lading van het voertuig erboven in voertuiglijsten STR_CONFIG_SETTING_LANDSCAPE :Landschap: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landschappen definiëren standaard spelscenario's met verschillende vracht- en stadsgroei-eisen. NewGRF en spelscripts kunnen daarentegen fijnere controle bieden. @@ -1480,7 +1468,7 @@ STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT :Bepaalt de hoev STR_CONFIG_SETTING_DESERT_COVERAGE_VALUE :{NUM}% STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Ruwheid van het terrein: {STRING} -STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT :(Alleen TerraGenesis) Kiest de frequentie van heuvels: gladde landschappen hebben minder, meer wijdverspreide heuvels. Ruwe landschappen hebben veel heuvels, die repetitief kunnen lijken. +STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT :(Alleen TerraGenesis) Selecteer de frequentie van heuvels: gladde landschappen hebben minder, meer wijdverspreide heuvels. Ruwe landschappen hebben veel heuvels, die repetitief kunnen lijken. ###length 4 STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Erg glad STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_SMOOTH :Glad @@ -1491,10 +1479,10 @@ STR_CONFIG_SETTING_VARIETY :Variëteit dist STR_CONFIG_SETTING_VARIETY_HELPTEXT :(Alleen TerraGenesis) Bepaalt of de kaart zowel bergachtige als vlakke gebieden bevat. Aangezien dit de kaart alleen platter maakt, moeten andere instellingen worden ingesteld op bergachtig. STR_CONFIG_SETTING_RIVER_AMOUNT :Hoeveelheid rivieren: {STRING} -STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT :Kiest hoeveel rivieren er gegenereerd worden +STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT :Selecteer hoeveel rivieren er gegenereerd worden STR_CONFIG_SETTING_TREE_PLACER :Algoritme voor plaatsing van bomen: {STRING} -STR_CONFIG_SETTING_TREE_PLACER_HELPTEXT :Kiest de verdeling van de bomen op de kaart: 'Origineel' plant bomen gelijkmatig verspreid, 'Verbeterd' plant in groepen. +STR_CONFIG_SETTING_TREE_PLACER_HELPTEXT :Selecteer de verdeling van de bomen op de kaart: 'Origineel' plant bomen gelijkmatig verspreid, 'Verbeterd' plant in groepen. ###length 3 STR_CONFIG_SETTING_TREE_PLACER_NONE :Geen STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :Origineel @@ -1503,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Verbeterd STR_CONFIG_SETTING_ROAD_SIDE :Wegvoertuigen: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Rijzijde voor verkeer kiezen +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Links rijden +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Rechts rijden + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Draaiing van hoogtekaart: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Tegen de klok in @@ -1703,7 +1695,7 @@ STR_CONFIG_SETTING_AI_BUILDS_SHIPS :Schepen voor de STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :Het inschakelen van deze instelling maakt het het bouwen van schepen onmogelijk voor een computerspeler STR_CONFIG_SETTING_AI_PROFILE :Standaard instellingenprofiel: {STRING} -STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Hiermee kies je welk instellingsprofiel moet worden gebruikt bij willekeurige AI's of als startwaardes wanneer een nieuwe AI of spelscript wordt toegevoegd. +STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Hiermee selecteer je welk instellingsprofiel moet worden gebruikt bij willekeurige AI's of als startwaardes wanneer een nieuwe AI of spelscript wordt toegevoegd. ###length 3 STR_CONFIG_SETTING_AI_PROFILE_EASY :Makkelijk STR_CONFIG_SETTING_AI_PROFILE_MEDIUM :Gemiddeld @@ -1719,7 +1711,7 @@ STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :De hoeveelheid STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Onderhoudstermijnen in procenten: {STRING} -STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Kiest of onderhoud van de voertuigen wordt geactiveerd door verstreken tijd sinds het laatste onderhoud of door het zakken van de betrouwbaarheid met een bepaald percentage van de maximale betrouwbaarheid +STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Selecteer of onderhoud van de voertuigen wordt geactiveerd door verstreken tijd sinds het laatste onderhoud of door het zakken van de betrouwbaarheid met een bepaald percentage van de maximale betrouwbaarheid STR_CONFIG_SETTING_SERVINT_TRAINS :Standaardonderhoudstermijn voor treinen: {STRING} STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :Standaardonderhoudstermijn instellen voor nieuwe treinen als er geen expliciete onderhoudstermijn is ingesteld voor het voertuig @@ -1830,7 +1822,7 @@ STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Automatisch arm STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Stelt het jaar in waarin elektrische seinen worden gebruikt voor sporen. Eerder dan dit jaar worden niet-elektrische seinen gebruikt (die exact op dezelfde manier werken, maar een verschillend uiterlijk hebben). STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Door seintypen bladeren: {STRING} -STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Selecteer welke soorten seinen worden gebruikt wanneer je Ctrl + klikt op een bouwsein met het seingereedschap +STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Selecteer welke soorten seinen worden gebruikt wanneer je Ctrl+klikt op een bouwsein met het seingereedschap ###length 2 STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :Alleen routeseinen STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :Alles zichtbaar @@ -1851,15 +1843,15 @@ STR_CONFIG_SETTING_TOWN_LAYOUT_3X3_GRID :3x3-raster STR_CONFIG_SETTING_TOWN_LAYOUT_RANDOM :Willekeurig STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :Steden mogen wegen bouwen: {STRING} -STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Steden toestaan om wegen te bouwen ten behoeve van groei. Schakel deze optie uit als je niet wilt dat gemeenten zelf wegen bouwen. +STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Steden toestaan om wegen te bouwen ten behoeve van groei. Schakel deze optie uit als je niet wilt dat steden zelf wegen bouwen. STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Steden mogen gelijkvloerse kruisingen bouwen: {STRING} -STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Door deze optie in te schakelen, kunnen steden gelijkvloerse kruisingen bouwen. +STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Door deze optie in te schakelen kunnen steden gelijkvloerse kruisingen bouwen STR_CONFIG_SETTING_NOISE_LEVEL :Geluidsniveaucontrole door steden voor vliegvelden toestaan: {STRING} STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Als je deze instelling uitschakelt, mogen er twee luchthavens per stad zijn. Als je deze instelling ingeschakelt, wordt het aantal luchthavens in een stad beperkt door de lawaaitolerantie van de stad; deze is afhankelijk van de bevolking en de grootte en afstand van de luchthaven. STR_CONFIG_SETTING_TOWN_FOUNDING :Steden stichten in spel: {STRING} -STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Wanneer deze instelling is ingeschakeld, kunnen spelers nieuwe steden stichten tijdens het spel. +STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Wanneer deze instelling is ingeschakeld kunnen spelers nieuwe steden stichten tijdens het spel ###length 3 STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Verboden STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Toestaan @@ -1922,8 +1914,8 @@ STR_CONFIG_SETTING_TOWN_GROWTH_NORMAL :Normaal STR_CONFIG_SETTING_TOWN_GROWTH_FAST :Snel STR_CONFIG_SETTING_TOWN_GROWTH_VERY_FAST :Heel snel -STR_CONFIG_SETTING_LARGER_TOWNS :Verhouding van gemeenten die uitgroeien tot steden: {STRING} -STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :Aantal steden die een stad worden, dus een stad die groter begint en sneller groeit +STR_CONFIG_SETTING_LARGER_TOWNS :Verhouding van dorpen die uitgroeien tot steden: {STRING} +STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :Aantal dorpen dat een stad wordt, dus die groter begint en sneller groeit STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 op {COMMA} ###setting-zero-is-special STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Geen @@ -1940,9 +1932,9 @@ STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :'Symmetrisch' b STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Distributiemodus voor post: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :'Symmetrisch' betekent dat ongeveer dezelfde hoeveelheid post wordt verzonden van station A naar station B als van B naar A. 'Asymmetrisch' betekent dat willekeurige hoeveelheden post in beide richtingen worden verzonden. 'Handmatig' betekent dat er geen automatische distributie plaatsvindt voor post. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Distributiemodus voor de GEPANTSERDE ladingsklasse: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :De GEPANTSERDE ladingsklasse bevat waardevolle spullen in het gematigde klimaat, diamanten in het subtropische klimaat of goud in het subarctische klimaat. NewGRF's kunnen dat veranderen. 'Symmetrisch' betekent dat ongeveer dezelfde hoeveelheid lading wordt verzonden van een station A naar station B als van B naar A. 'Asymmetrisch' betekent dat deze vracht willekeurig in beide richtingen kan worden verzonden. 'Handmatig' betekent dat er geen automatische distributie zal plaatsvinden voor die lading. Het wordt aanbevolen om dit op 'Asymmetrisch' of 'Handmatig' te zetten bij het spelen in subarctisch klimaat omdat banken geen goud terugsturen naar goudmijnen. Voor gematigd en subtropisch klimaat kun je ook 'Symmetrisch' kiezen omdat banken waardevolle spullen terug kunnen sturen naar de oorspronkelijke bank. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :De GEPANTSERDE ladingsklasse bevat waardevolle spullen in het gematigde klimaat, diamanten in het subtropische klimaat of goud in het subarctische klimaat. NewGRF's kunnen dat veranderen. 'Symmetrisch' betekent dat ongeveer dezelfde hoeveelheid lading wordt verzonden van een station A naar station B als van B naar A. 'Asymmetrisch' betekent dat deze vracht willekeurig in beide richtingen kan worden verzonden. 'Handmatig' betekent dat er geen automatische distributie zal plaatsvinden voor die lading. Het wordt aanbevolen om dit op 'Asymmetrisch' of 'Handmatig' te zetten bij het spelen in subarctisch of subtropisch klimaat omdat banken daar alleen vracht kunnen accepteren, niet versturen. Voor gematigd klimaat kun je ook 'Symmetrisch' kiezen omdat banken kostbaarheden terug kunnen sturen naar de oorspronkelijke bank. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Distributiemodus voor andere vrachtsoorten: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :'Symmetrisch' betekent dat willekeurige hoeveelheden lading in beide richtingen kunnen worden gestuurd. 'Handmatig' betekent dat er geen automatische distributie plaatsvindt voor die lading. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :'Asymmetrisch' betekent dat willekeurige hoeveelheden lading in beide richtingen kunnen worden gestuurd. 'Handmatig' betekent dat er geen automatische distributie plaatsvindt voor die lading. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :Handmatig STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :Asymmetrisch @@ -2037,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatisch omd STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Treinen mogen keren bij een sein als ze hier lang staan wachten ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Aanbevolen) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Aanbevolen) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Instelwaarde wijzigen @@ -2080,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Scoretab STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Instellingen STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF-instellingen STR_INTRO_ONLINE_CONTENT :{BLACK}Online inhoud zoeken -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI-/spelscriptinstellingen +STR_INTRO_AI_SETTINGS :{BLACK}AI-instellingen +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Spelscript-instellingen STR_INTRO_QUIT :{BLACK}Afsluiten STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Start een nieuw spel. Ctrl+klik slaat de kaartconfiguratie over @@ -2100,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Scoretab STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Scherminstellingen STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF-instellingen weergeven STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Zoeken naar nieuwe en aangepaste inhoud om te downloaden -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}AI-/spelscriptinstellingen weergeven +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}AI-instellingen weergeven +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Spelscript-instellingen weergeven STR_INTRO_TOOLTIP_QUIT :{BLACK}'OpenTTD' afsluiten STR_INTRO_BASESET :{BLACK}De huidige gekozen set grafische elementen mist {NUM} sprite{P "" s}. Controleer of er updates zijn voor deze basisset. @@ -2132,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Datum w STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Huidig jaar wijzigen STR_CHEAT_SETUP_PROD :{LTBLUE}Productiewaarden aanpassen toestaan: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Gematigd landschap -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subarctisch landschap -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Subtropisch landschap -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Speelgoedlandschap - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - kleurenschema @@ -2146,9 +2134,9 @@ STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Kleurens STR_LIVERY_ROAD_VEHICLE_TOOLTIP :{BLACK}Kleurenschema's voor wegvoertuigen weergeven STR_LIVERY_SHIP_TOOLTIP :{BLACK}Kleurenschema's voor schepen weergeven STR_LIVERY_AIRCRAFT_TOOLTIP :{BLACK}Kleurenschema's voor vliegtuigen weergeven -STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Kies de hoofdkleur voor het geselecteerde schema. Ctrl+klik zal deze kleur instellen voor elk schema -STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Kies de secundaire kleur voor het geselecteerde schema. Met ctrl+klik stel je deze kleur in voor alle schema's. -STR_LIVERY_PANEL_TOOLTIP :{BLACK}Kies een kleurenschema om te wijzigen of meerdere schema's met Ctrl+klik. Vink de keuzevakjes aan-uit om het schema aan-uit te zetten +STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Selecteer de hoofdkleur voor het geselecteerde schema. Ctrl+klik zal deze kleur instellen voor elk schema +STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Selecteer de secundaire kleur voor het geselecteerde schema. Met Ctrl+klik stel je deze kleur in voor alle schema's +STR_LIVERY_PANEL_TOOLTIP :{BLACK}Selecteer een kleurenschema om te wijzigen of meerdere schema's met Ctrl+klik. Vink de keuzevakjes aan-uit om het schema aan-uit te zetten ###length 23 STR_LIVERY_DEFAULT :Standaard kleurenschema @@ -2308,7 +2296,7 @@ STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}Zichtbaa STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP :{BLACK}Bepaalt of andere mensen je server kunnen zien in de openbare lijst STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} speler{P "" s} STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Maximumaantal spelers: -STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}Kies het maximaal aantal toegestane spelers. Niet alle posities hoeven gebruikt te worden. +STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}Selecteer het maximaal aantal toegestane spelers. Niet alle posities hoeven gebruikt te worden STR_NETWORK_START_SERVER_COMPANIES_SELECT :{BLACK}{NUM} bedr{P ijf ijven} STR_NETWORK_START_SERVER_NUMBER_OF_COMPANIES :{BLACK}Maximumaantal bedrijven: STR_NETWORK_START_SERVER_NUMBER_OF_COMPANIES_TOOLTIP :{BLACK}Beperk de server tot een bepaald aantal bedrijven @@ -2370,7 +2358,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nieuw bedrijf) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Een nieuw bedrijf maken en meedoen STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Dit ben jij STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Dit is de host van het spel -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klant{P "" en} / {NUM} bedrij{P f ven} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} speler{P "" s} - {NUM}/{NUM} bedrij{P f ven} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Het aantal momenteel verbonden clients, het aantal bedrijven en het maximale aantal toegestane bedrijven door de serverbeheerder # Matches ConnectionType ###length 5 @@ -2497,13 +2486,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :wacht op bijwer STR_NETWORK_MESSAGE_CLIENT_LEAVING :vertrekt STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} heeft zich bij het spel gevoegd -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} heeft zich bij het spel gevoegd (Speler #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} heeft zich gevoegd bij bedrijf nr. {2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} heeft zich bij het spel gevoegd (Speler #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} heeft zich gevoegd bij bedrijf nr. {2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} kijkt nu toe -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} heeft een nieuw bedrijf opgericht (nr. {2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} heeft het spel verlaten ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} heeft een nieuw bedrijf opgericht (nr. {2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} heeft het spel verlaten ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} heeft diens naam gewijzigd in {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} gaf {2:CURRENCY_LONG} aan {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} gaf {2:CURRENCY_LONG} aan {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}De server heeft de sessie gesloten STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}De server wordt opnieuw gestart...{}Wacht alstublieft... STR_NETWORK_MESSAGE_KICKED :*** {STRING} is eruit geschopt. Reden: ({STRING}) @@ -2539,7 +2528,7 @@ STR_CONTENT_TOTAL_DOWNLOAD_SIZE :{SILVER}Totale STR_CONTENT_DETAIL_TITLE :{SILVER}INFO OVER INHOUD ###length 5 -STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED :{SILVER}Je hebt ervoor gekozen om dit niet te downloaden +STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED :{SILVER}Je hebt er niet voor gekozen om dit te downloaden STR_CONTENT_DETAIL_SUBTITLE_SELECTED :{SILVER}Je hebt ervoor gekozen om dit te downloaden STR_CONTENT_DETAIL_SUBTITLE_AUTOSELECTED :{SILVER}Deze afhankelijkheid is geselecteerd om te downloaden STR_CONTENT_DETAIL_SUBTITLE_ALREADY_HERE :{SILVER}Dit heb je al @@ -2617,6 +2606,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}Verzadigd STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}Overbelast +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} voor retourtransport per maand van {STATION} naar {STATION} ({COMMA}% van capaciteit){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} voor retourtransport ({COMMA}% van capaciteit) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Gemiddelde reistijd: {NUM}{NBSP}dag{P "" en} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Dekkingsgebied markeren STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Uit @@ -2625,6 +2619,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Markeer STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Markeer het dekkingsgebied van de voorgestelde locatie STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Accepteert: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Biedt aan: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Onderhoudskosten: {GOLD}{CURRENCY_SHORT}/jaar # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Station samenvoegen @@ -2669,7 +2664,7 @@ STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Type rou # Rail station construction window STR_STATION_BUILD_RAIL_CAPTION :{WHITE}Stationskeuze STR_STATION_BUILD_ORIENTATION :{BLACK}Richting -STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP :{BLACK}Kies richting van treinstation +STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP :{BLACK}Selecteer richting van treinstation STR_STATION_BUILD_NUMBER_OF_TRACKS :{BLACK}Aantal sporen STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP :{BLACK}Selecteer het aantal sporen voor het treinstation STR_STATION_BUILD_PLATFORM_LENGTH :{BLACK}Perronlengte @@ -2704,11 +2699,13 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Dichthei STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Dichtheid van seinen bij slepen vergroten # Bridge selection window -STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Kies type spoorbrug -STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Kies type wegbrug +STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Selecteer type spoorbrug +STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Selecteer type wegbrug STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Brugkeuze - klik op de gewenste brug om die te bouwen -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Hangend, staal STR_BRIDGE_NAME_GIRDER_STEEL :Ligger, staal STR_BRIDGE_NAME_CANTILEVER_STEEL :Vrijdragend, staal @@ -2737,8 +2734,8 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Bouw weg STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Bouw brug voor tramsporen. Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Wegtunnel bouwen. Shift schakelt tussen bouwen/inschatting van de kosten. STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Tramtunnel bouwen. Shift schakelt tussen bouwen/inschatting van de kosten. -STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Kies tussen bouwen en verwijderen bij wegenbouw -STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Kies tussen bouwen en verwijderen bij tramspooraanleg +STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Wissel tussen bouwen en verwijderen bij wegenbouw +STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Wissel tussen bouwen en verwijderen bij tramspooraanleg STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Converteer/opwaardeer het type weg. Shift schakelt tussen bouwen/inschatting van de kosten. STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Converteer/opwaardeer het type tram. Shift schakelt tussen bouwen/inschatting van de kosten. @@ -2786,7 +2783,7 @@ STR_TOOLBAR_AIRCRAFT_BUILD_AIRPORT_TOOLTIP :{BLACK}Vliegvel # Airport construction window STR_STATION_BUILD_AIRPORT_CAPTION :{WHITE}Keuze van vliegveld -STR_STATION_BUILD_AIRPORT_TOOLTIP :{BLACK}Kies grootte en type van vliegveld +STR_STATION_BUILD_AIRPORT_TOOLTIP :{BLACK}Selecteer grootte en type van het vliegveld STR_STATION_BUILD_AIRPORT_CLASS_LABEL :{BLACK}Vliegveldklasse STR_STATION_BUILD_AIRPORT_LAYOUT_NAME :{BLACK}Layout {NUM} @@ -2812,12 +2809,12 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Terreina STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Verlaag een hoek van het land. Slepen verlaagt de eerste geselecteerde hoek en brengt het geselecteerde gebied naar de hoogte van die hoek. Ctrl selecteert het gebied diagonaal. Shift maakt een inschatting van de kosten STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Verhoog een hoek van het land. Slepen verhoogt de eerste geselecteerde hoek en brengt het geselecteerde gebied naar de hoogte van die hoek. Ctrl selecteert het gebied diagonaal. Shift maakt een inschatting van de kosten STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Land egaliseren op hoogte van eerst geselecteerde hoek. Ctrl selecteert een diagonaal gebied. Shift+klik wisselt tussen bouwen/verwachte kosten weergeven. -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Land kopen voor toekomstig gebruik. Shift+klik wisselt tussen bouwen/verwachte kosten weergeven. +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Land kopen voor toekomstig gebruik. Ctrl selecteert een diagonaal gebied. Shift+klik wisselt tussen bouwen/verwachte kosten weergeven. # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Keuze van object -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Object selecteren voor bouwen. Shift+Klik wisselt tussen bouwen/verwachte kosten weergeven. -STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Hiermee kies je de klasse van het te bouwen object +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selecteer object om te bouwen. Ctrl selecteert een diagonaal gebied. Shift+klik wisselt tussen bouwen/verwachte kosten weergeven. +STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Hiermee selecteer je de klasse van het te bouwen object STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Bekijk het object STR_OBJECT_BUILD_SIZE :{BLACK}Grootte: {GOLD}{NUM} x {NUM} tegels @@ -2826,9 +2823,9 @@ STR_OBJECT_CLASS_TRNS :Zendmasten # Tree planting window (last eight for SE only) STR_PLANT_TREE_CAPTION :{WHITE}Bomen -STR_PLANT_TREE_TOOLTIP :{BLACK}Kies een soort boom om te planten. Als de tegel al bomen bevat, komen er meer bomen van verschillende typen bij, onafhankelijk van het geselecteerde type. +STR_PLANT_TREE_TOOLTIP :{BLACK}Selecteer een soort boom om te planten. Als de tegel al bomen bevat, komen er meer bomen van verschillende typen bij, onafhankelijk van het geselecteerde type STR_TREES_RANDOM_TYPE :{BLACK}Willekeurige soorten bomen -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Willekeurig bomen planten. Shift+klik wisselt tussen bouwen/verwachte kosten. +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Willekeurig bomen planten. Ctrl selecteert het gebied diagonaal. Shift+klik wisselt tussen bouwen/verwachte kosten. STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Willekeurige bomen STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Hiermee plant je bomen willekeurig over het landschap STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normaal @@ -2860,6 +2857,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Willekeu STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Hiermee sticht je een stad op een willekeurige locatie STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Veel willekeurige steden STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Verspreid willekeurig geplaatste steden over de kaart +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Alle steden uitbreiden +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Laat alle steden een klein beetje groeien STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Plaatsnaam: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Plaatsnaam invoeren @@ -2886,7 +2885,7 @@ STR_FOUND_TOWN_SELECT_LAYOUT_RANDOM :{BLACK}Willekeu # Fund new industry window STR_FUND_INDUSTRY_CAPTION :{WHITE}Nieuwe industrie financieren -STR_FUND_INDUSTRY_SELECTION_TOOLTIP :{BLACK}Kiest de gewenste industrie in de lijst +STR_FUND_INDUSTRY_SELECTION_TOOLTIP :{BLACK}Selecteer de gewenste industrie in de lijst STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES :{BLACK}Willekeurige industrieën maken STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP :{BLACK}Bedek de kaart met willekeurig geplaatste industrieën STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_CAPTION :{WHITE}Willekeurige industrieën maken @@ -3076,7 +3075,7 @@ STR_FRAMERATE_GL_SHIPS :{BLACK} Scheeps STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Vliegtuigtikken: STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Wereldtikken: STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Vertraging koppelinggrafiek: -STR_FRAMERATE_DRAWING :{WHITE}Grafische weergave: +STR_FRAMERATE_DRAWING :{BLACK}Grafische weergave: STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Wereldkijkvensters: STR_FRAMERATE_VIDEO :{BLACK}Video-uitvoer: STR_FRAMERATE_SOUND :{BLACK}Geluid mengen: @@ -3124,7 +3123,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Speldeta STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Geen informatie beschikbaar STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtertekenreeks: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Bestand overschrijven STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Weet je zeker dat je het bestaande bestand wilt overschrijven? STR_SAVELOAD_DIRECTORY :{STRING} (Map) @@ -3138,6 +3137,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kaartgro STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Selecteer het formaat van de kaart in tegels. Het aantal beschikbare tegels zal iets kleiner zijn STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Aantal steden: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Plaatsnamen: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Stijl voor plaatsnamen kiezen STR_MAPGEN_DATE :{BLACK}Datum: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Aantal industrieën: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Hoogste berg: @@ -3151,13 +3152,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Woestijn STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Vergroot het woestijnoppervlak met tien procent STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Verkleint het woestijnoppervlak met tien procent STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Landgenerator: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terreintype: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Zeeniveau: +STR_MAPGEN_SEA_LEVEL :{BLACK}Zeeniveau: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Rivieren: STR_MAPGEN_SMOOTHNESS :{BLACK}Gladheid: STR_MAPGEN_VARIETY :{BLACK}Landschapsvariatie: STR_MAPGEN_GENERATE :{WHITE}Maken +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF-instellingen +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}NewGRF-instellingen weergeven +STR_MAPGEN_AI_SETTINGS :{BLACK}AI-instellingen +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}AI-instellingen weergeven +STR_MAPGEN_GS_SETTINGS :{BLACK}Spelscript-instellingen +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Spelscript-instellingen weergeven + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Engels (Origineel) +STR_MAPGEN_TOWN_NAME_FRENCH :Frans +STR_MAPGEN_TOWN_NAME_GERMAN :Duits +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Engels (Extra) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latijns-Amerikaans +STR_MAPGEN_TOWN_NAME_SILLY :Zot +STR_MAPGEN_TOWN_NAME_SWEDISH :Zweeds +STR_MAPGEN_TOWN_NAME_DUTCH :Nederlands +STR_MAPGEN_TOWN_NAME_FINNISH :Fins +STR_MAPGEN_TOWN_NAME_POLISH :Pools +STR_MAPGEN_TOWN_NAME_SLOVAK :Slowaaks +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Noors +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hongaars +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Oostenrijks +STR_MAPGEN_TOWN_NAME_ROMANIAN :Roemeens +STR_MAPGEN_TOWN_NAME_CZECH :Tsjechisch +STR_MAPGEN_TOWN_NAME_SWISS :Zwitsers +STR_MAPGEN_TOWN_NAME_DANISH :Deens +STR_MAPGEN_TOWN_NAME_TURKISH :Turks +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiaans +STR_MAPGEN_TOWN_NAME_CATALAN :Catalaans # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kaartranden: @@ -3216,7 +3245,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Gedetail STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Actieve NewGRF-bestanden STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Inactieve NewGRF-bestanden STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Voorkeursinstelling selecteren: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtertekst: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}De geselecteerde voorkeursinstelling laden STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Voorkeursinstelling opslaan STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Bewaar de huidige lijst als voorkeursinstelling @@ -3303,12 +3332,19 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Vorige s STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Doorgaan met de vorige normale sprite, alle pseudo-/herkleur-/lettertype-sprites overslaan; bij het einde terug naar het begin STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Voorbeeld van de huidige sprite. De uitlijning wordt genegeerd bij het weergeven van deze sprite. STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Sprite verplaatsen, dit verandert X en Y offsets. Ctr+klik om de sprite 8 eenheden per keer te verplaatsen. + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Op offset gecentreerd +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Op sprite gecentreerd + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Richtkruis + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Relatief herstellen STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Herstel de huidige relatieve offsets STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X-offset: {NUM}, Y-offset: {NUM} (absoluut) STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}X-offset: {NUM}, Y-offset: {NUM} (relatief) STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Sprite kiezen -STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Kies een sprite van een willekeurige plaats op het scherm +STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Selecteer een sprite ergens op het scherm STR_SPRITE_ALIGNER_GOTO_CAPTION :{WHITE}Ga naar sprite @@ -3317,18 +3353,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Waarschuwing: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Fout: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatale fout: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Een fatale NewGRF-fout is ontstaan:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Er is een NewGRF-fout opgetreden:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}De NewGRF "{STRING}" heeft een fatale fout veroorzaakt:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}De NewGRF "{STRING}" heeft een fout veroorzaakt:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} werkt niet met de TTDPatch-versie die is opgegeven door OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} is voor versie {STRING} van TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} is ontwikkeld voor {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Ongeldige parameter voor {1:STRING}: parameter {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} moet geladen zijn voor {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} moet geladen zijn na {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} heeft OpenTTD-versie {STRING} of beter nodig +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} is voor versie {2:STRING} van TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} is ontwikkeld voor {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Ongeldige parameter voor {1:STRING}: parameter {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} moet geladen zijn voor {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} moet geladen zijn na {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} heeft OpenTTD-versie {2:STRING} of beter nodig STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :het GRF-bestand die het probeert te vertalen STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Er zijn te veel NewGRFs geladen -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Laden van {1:STRING} als statische NewGRF met {STRING} kan desynchronisatiefouten (desyncs) veroorzaken +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Laden van {1:STRING} als statische NewGRF met {2:STRING} kan desynchronisatiefouten (desyncs) veroorzaken STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Onverwachte sprite (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Onbekende Action 0-eigenschap {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Poging om ongeldige id te gebruiken (sprite {3:NUM}) @@ -3460,14 +3496,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Exclusieve tran STR_LOCAL_AUTHORITY_ACTION_BRIBE :Gemeentebestuur omkopen ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Begin een kleine reclamecampagne om meer passagiers en vracht naar jouw transportdiensten te trekken.{}Zorgt voor een tijdelijk hogere stationswaardering in een klein gebied rondom het centrum.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Begin een middelgrote reclamecampagne om meer passagiers en vracht naar jouw transportdiensten te trekken.{}Zorgt voor een tijdelijk hogere stationswaardering in een middelgroot gebied rondom het centrum.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Begin een grote reclamecampagne om meer passagiers en vracht naar jouw transportdiensten te trekken.{}Zorgt voor een tijdelijk hogere stationswaardering in een groot gebied rondom het centrum.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Financier een reconstructie van het wegennetwerk.{}Veroorzaakt tot 6 maanden lang een aanzienlijke verstoring van het wegverkeer.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Een standbeeld bouwen ter ere van jouw bedrijf.{}Zorgt voor een blijvend hogere stationswaardering in deze stad.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}De bouw van nieuwe gebouwen in de stad financieren.{}Zorgt voor een tijdelijk hogere groei van deze stad.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}1 jaar exclusieve transportrechten kopen in deze plaats.{}Het gemeentebestuur staat alleen passagiers en vracht toe bij jouw stations.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Koop het plaatselijk gezag om om je reputatie te verhogen met het risico op een strenge sanctie wanneer je gepakt wordt.{}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Begin een kleine reclamecampagne om meer passagiers en vracht naar jouw transportdiensten te trekken.{}Zorgt voor een tijdelijk hogere stationswaardering in een klein gebied rondom het centrum.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Begin een middelgrote reclamecampagne om meer passagiers en vracht naar jouw transportdiensten te trekken.{}Zorgt voor een tijdelijk hogere stationswaardering in een middelgroot gebied rondom het centrum.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Begin een grote reclamecampagne om meer passagiers en vracht naar jouw transportdiensten te trekken.{}Zorgt voor een tijdelijk hogere stationswaardering in een groot gebied rondom het centrum.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Financier een reconstructie van het wegennetwerk.{}Veroorzaakt tot 6 maanden lang een aanzienlijke verstoring van het wegverkeer.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Bouw een standbeeld ter ere van jouw bedrijf.{}Zorgt voor een blijvend hogere stationswaardering in deze stad.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Financier de bouw van nieuwe gebouwen in de stad.{}Zorgt voor een tijdelijk hogere groei van deze stad.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}1 jaar exclusieve transportrechten kopen in deze plaats.{}Het gemeentebestuur staat alleen passagiers en vracht toe bij jouw stations.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Koop het plaatselijk gezag om om je reputatie te verhogen met het risico op een ernstige sanctie wanneer je gepakt wordt.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Doelen @@ -3640,15 +3676,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Schepen STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD} Rente van lening STR_FINANCES_SECTION_OTHER :{GOLD}Overig +STR_FINANCES_TOTAL_CAPTION :{WHITE}Totaal STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Nettowinst +STR_FINANCES_PROFIT :{WHITE}Winst STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Banksaldo STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Eigen kapitaal STR_FINANCES_LOAN_TITLE :{WHITE}Lening STR_FINANCES_INTEREST_RATE :{WHITE}Rente op lening: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maximale lening: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}{CURRENCY_LONG} lenen STR_FINANCES_BORROW_TOOLTIP :{BLACK}Vergroot lening. Ctrl+klik om zoveel als mogelijk te lenen STR_FINANCES_REPAY_BUTTON :{BLACK}{CURRENCY_LONG} terugbetalen @@ -3749,7 +3788,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Producee STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Vereist: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} wachtend{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Productie wijzigen (veelvoud van 8, maximaal 2040) @@ -3779,6 +3818,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Stuur in STR_VEHICLE_LIST_REPLACE_VEHICLES :Vervang voertuigen STR_VEHICLE_LIST_SEND_FOR_SERVICING :Stuur voor onderhoud STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Winst dit jaar: {CURRENCY_LONG} (vorig jaar: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Stuur naar depot STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Stuur naar garage @@ -3870,6 +3911,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. tre STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Bereik: {GOLD}{COMMA} tegels STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Vliegtuigtype: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Alle soorten vracht +STR_CARGO_TYPE_FILTER_FREIGHT :Vracht +STR_CARGO_TYPE_FILTER_NONE :Geen + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Spoorvoertuigkeuzelijst. Klik op een spoorvoertuig voor informatie. Ctrl+klik voor spoorvoertuigtype weergeven-verbergen. STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Wegvoertuigkeuzelijst. Klik op wegvoertuig voor informatie. Ctrl+klik voor voertuigtype weergeven-verbergen. @@ -4038,7 +4084,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :vliegtuig STR_ENGINE_PREVIEW_SHIP :schip STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Kosten: {CURRENCY_LONG} Gewicht: {WEIGHT_SHORT}{}Snelheid: {VELOCITY} Kracht: {POWER}{}Lopende kosten: {CURRENCY_LONG}/jr{}Capaciteit: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Kosten: {CURRENCY_LONG} Gewicht: {WEIGHT_SHORT}{}Snelheid: {VELOCITY} Kracht: {POWER} Max. T.E.: {6:FORCE}{}Lopende kosten: {4:CURRENCY_LONG}/yr{}Capaciteit: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Kosten: {0:CURRENCY_LONG} Gewicht: {1:WEIGHT_SHORT}{}Snelheid: {2:VELOCITY} Kracht: {3:POWER} Max. T.E.: {6:FORCE}{}Lopende kosten: {4:CURRENCY_LONG}/yr{}Capaciteit: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Kosten: {CURRENCY_LONG} Max.snelheid: {VELOCITY}{}Capaciteit: {CARGO_LONG}{}Gebruikskosten: {CURRENCY_LONG}/jaar STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Kosten: {CURRENCY_LONG} Max.snelheid: {VELOCITY}{}Vliegtuigtype: {STRING}{}Capaciteit: {CARGO_LONG}, {CARGO_LONG}{}Gebruikskosten: {CURRENCY_LONG}/jaar STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Kosten: {CURRENCY_LONG} Max.snelheid: {VELOCITY}{}Vliegtuigtype: {STRING}{}Capaciteit: {CARGO_LONG}{}Gebruikskosten: {CURRENCY_LONG}/jaar @@ -4059,8 +4105,8 @@ STR_REPLACE_VEHICLE_ROAD_VEHICLE :Wegvoertuig STR_REPLACE_VEHICLE_SHIP :Schip STR_REPLACE_VEHICLE_AIRCRAFT :Vliegtuig -STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Kies het type locomotief om te vervangen -STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Kies een nieuw type locomotief die je wilt gebruiken om het links geselecteerde type locomotief te vervangen +STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Selecteer het type locomotief om te vervangen +STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Selecteer een nieuw type locomotief die je wilt gebruiken om het links geselecteerde type locomotief te vervangen STR_REPLACE_VEHICLES_START :{BLACK}Start het vervangen STR_REPLACE_VEHICLES_NOW :Vervang alle voertuigen nu @@ -4080,7 +4126,7 @@ STR_REPLACE_ALL_ROADTYPE :Alle wegvoertui ###length 2 STR_REPLACE_HELP_RAILTYPE :{BLACK}Selecteer een spoortype waar je locomotieven voor wilt vervangen -STR_REPLACE_HELP_ROADTYPE :{BLACK}Kies het type weg waar je voertuigen voor wilt vervangen +STR_REPLACE_HELP_ROADTYPE :{BLACK}Selecteer het type weg waar je voertuigen voor wilt vervangen ###next-name-looks-similar STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Dit geeft weer waarmee de links geselecteerde locomotief vervangen wordt @@ -4194,15 +4240,16 @@ STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Max.snel STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Max.snelheid: {LTBLUE}{VELOCITY} {BLACK}Vliegtuigtype: {LTBLUE}{STRING} STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Max.snelheid: {LTBLUE}{VELOCITY} {BLACK}Vliegtuigtype: {LTBLUE}{STRING} {BLACK}Bereik: {LTBLUE}{COMMA} tegels STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Gewicht: {LTBLUE}{WEIGHT_SHORT} {BLACK}Vermogen: {LTBLUE}{POWER}{BLACK} Max.snelheid: {LTBLUE}{VELOCITY} -STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Gewicht: {LTBLUE}{WEIGHT_SHORT} {BLACK}Vermogen: {LTBLUE}{POWER}{BLACK} Max.snelheid: {LTBLUE}{VELOCITY} {BLACK}Max. tr.kr..: {LTBLUE}{FORCE} +STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Gewicht: {LTBLUE}{WEIGHT_SHORT} {BLACK}Vermogen: {LTBLUE}{POWER}{BLACK} Max.snelheid: {LTBLUE}{VELOCITY} {BLACK}Max. tr.kr.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Winst dit jaar: {LTBLUE}{CURRENCY_LONG} (vorig jaar: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Winst dit jaar: {LTBLUE}{CURRENCY_LONG} (vorig jaar: {CURRENCY_LONG}) {BLACK}Min. prestatie: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Betrouwbaarheid: {LTBLUE}{COMMA}% {BLACK}Aantal keren motorpech sinds laatste onderhoud: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Gebouwd: {LTBLUE}{NUM}{BLACK} Waarde: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capaciteit: {LTBLUE}Geen{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capaciteit: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capaciteit: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capaciteit: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capaciteit: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capaciteit: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Geldoverdracht: {LTBLUE}{CURRENCY_LONG} @@ -4250,10 +4297,10 @@ STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}Capacite STR_REFIT_CAPTION :{WHITE}{VEHICLE} (Ombouwen) STR_REFIT_TITLE :{GOLD}Vrachttype selecteren: STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nieuwe capaciteit: {GOLD}{CARGO_LONG}{}{BLACK}Ombouwkosten: {RED}{CURRENCY_LONG} -STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Nieuwe capaciteit: {GOLD}{CARGO_LONG}{}{BLACK}Inkomsten na ombouwen: {GREEN}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Nieuwe capaciteit: {GOLD}{CARGO_LONG}{}{BLACK}Inkomsten van ombouwen: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Nieuwe capaciteit: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Ombouwkosten: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Nieuwe capaciteit: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Inkomsten na ombouwen: {GREEN}{CURRENCY_LONG} -STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Kies het voertuig dat je wilt ombouwen. Sleep met de muis om meerdere voertuigen te selecteren. Klik op een lege ruimte om het hele voertuig te selecteren. Met ctrl+klik selecteer je een voertuig en de volgende keten. +STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Selecteer het voertuig dat je wilt ombouwen. Sleep met de muis om meerdere voertuigen te selecteren. Klik op een lege ruimte om het hele voertuig te selecteren. Met Ctrl+klik selecteer je een voertuig en de volgende keten ###length VEHICLE_TYPES STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Vrachttype selecteren dat deze trein moet vervoeren @@ -4308,9 +4355,9 @@ STR_ORDER_DROP_NO_UNLOADING :Niet lossen STR_ORDER_TOOLTIP_UNLOAD :{BLACK}Verander het losgedrag van de geselecteerde order STR_ORDER_REFIT :{BLACK}Ombouwen -STR_ORDER_REFIT_TOOLTIP :{BLACK}Kies naar welk type vracht moet worden omgebouwd in deze order. Ctrl+klik om ombouwopdracht te verwijderen +STR_ORDER_REFIT_TOOLTIP :{BLACK}Selecteer naar welk type vracht moet worden omgebouwd in deze order. Ctrl+klik om de ombouwopdracht te verwijderen STR_ORDER_REFIT_AUTO :{BLACK}Ombouwen -STR_ORDER_REFIT_AUTO_TOOLTIP :{BLACK}Kies vrachttype om naar om te bouwen in deze order. Ctrl+Klik om ombouwopdracht te verwijderen. Ombouwen wordt alleen uitgevoerd als het voertuig dit toelaat +STR_ORDER_REFIT_AUTO_TOOLTIP :{BLACK}Selecteer het vrachttype om naar om te bouwen in deze order. Ctrl+klik om de ombouwopdracht te verwijderen. Ombouwen wordt alleen uitgevoerd als het voertuig dit toelaat STR_ORDER_DROP_REFIT_AUTO :Vaste vracht STR_ORDER_DROP_REFIT_AUTO_ANY :Beschikbare vracht @@ -4468,25 +4515,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Deze die STR_TIMETABLE_STATUS_START_AT :{BLACK}Deze dienstregeling begint op {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Startdatum -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Selecteer een datum als startpunt voor deze dienstregeling. Ctrl + klik verdeelt alle voertuigen die deze orders delen gelijkmatig vanaf deze datum op basis van hun relatieve volgorde, als de order volledig is ingeroosterd. +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Selecteer een datum als startpunt voor deze dienstregeling. Ctrl+klik verdeelt alle voertuigen die deze orders delen gelijkmatig vanaf deze datum op basis van hun relatieve volgorde, als de order volledig is ingeroosterd STR_TIMETABLE_CHANGE_TIME :{BLACK}Tijd wijzigen -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Verander de tijdsduur die de geselecteerde order mag duren +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Verander de tijdsduur die de geselecteerde order mag duren. Met Ctrl+klik stel je de tijd voor alle orders in STR_TIMETABLE_CLEAR_TIME :{BLACK}Tijd wissen -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Verwijder de tijdsduur die de geselecteerde order mag duren +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Verwijder de tijdsduur die de geselecteerde order mag duren. Met Ctrl+klik wis je de tijd voor alle orders STR_TIMETABLE_CHANGE_SPEED :{BLACK}Maximumsnelheid wijzigen -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Wijzig de maximumsnelheid voor de gekozen order +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Wijzig de maximumsnelheid voor de gekozen order. Met Ctrl+klik stel je de snelheid voor alle orders in STR_TIMETABLE_CLEAR_SPEED :{BLACK}Snelheidslimiet wissen -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Verwijder de maximumsnelheid van de gekozen order +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Verwijder de maximumsnelheid van de gekozen order. Met Ctrl+klik wis je de snelheid voor alle orders STR_TIMETABLE_RESET_LATENESS :{BLACK}Vertragingsteller terugstellen -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Stel de vertragingsteller terug zodat het voertuig op tijd is +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Stel de vertragingsteller terug zodat het voertuig op tijd is. Ctrl+kllik stelt de hele groep terug zodat het laatste voertuig op tijd komt en alle andere te vroeg. STR_TIMETABLE_AUTOFILL :{BLACK}Automatisch vullen -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Vul de dienstregeling automatisch in aan de hand van de volgende reis (Ctrl+klik om te proberen om wachttijden te bewaren) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Vul de dienstregeling automatisch in aan de hand van de volgende reis. Ctrl+klik om te proberen om wachttijden te bewaren STR_TIMETABLE_EXPECTED :{BLACK}Verwacht STR_TIMETABLE_SCHEDULED :{BLACK}Volgens dienstregeling @@ -4510,7 +4557,7 @@ STR_AI_DEBUG :{WHITE}Probleem STR_AI_DEBUG_NAME_AND_VERSION :{BLACK}{STRING} (v{NUM}) STR_AI_DEBUG_NAME_TOOLTIP :{BLACK}Naam van het script STR_AI_DEBUG_SETTINGS :{BLACK}Instellingen -STR_AI_DEBUG_SETTINGS_TOOLTIP :{BLACK}Instellingen van script wijzigen +STR_AI_DEBUG_SETTINGS_TOOLTIP :{BLACK}Script-instellingen wijzigen STR_AI_DEBUG_RELOAD :{BLACK}Computerspeler opnieuw laden STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}Computerspeler verwijderen, script opnieuw laden en computerspeler opnieuw starten STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}Afbreken in-uitschakelen als een AI-logbericht overeenstemt met de afbreektekst @@ -4530,12 +4577,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Eén van STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI-/spelscript-probleemvenster is alleen beschikbaar voor de server # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI-/spelscriptconfiguratie +STR_AI_CONFIG_CAPTION_AI :{WHITE}Configuratie AI +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Configuratie spelscript STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Het spelscript dat in het volgende spel geladen wordt STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}De AI's die in het volgende spel geladen worden STR_AI_CONFIG_HUMAN_PLAYER :Menselijke speler STR_AI_CONFIG_RANDOM_AI :Willekeurige AI STR_AI_CONFIG_NONE :(geen) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maximaal aantal tegenstanders: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Omhoog verplaatsen STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Geselecteerde AI omhoog verplaatsen in de lijst @@ -4543,12 +4592,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Omlaag v STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Geselecteerde AI naar omlaag verplaatsen in de lijst STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spelscript +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parameters STR_AI_CONFIG_AI :{SILVER}AI's -STR_AI_CONFIG_CHANGE :{BLACK}{STRING} selecteren -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Spelscript +STR_AI_CONFIG_CHANGE_AI :{BLACK}AI selecteren +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Spelscript selecteren STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Ander script laden STR_AI_CONFIG_CONFIGURE :{BLACK}Configureren STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}De parameters van het script configureren @@ -4576,9 +4624,9 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Schermaf STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Schermafbeelding van de hoogtekaart STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Schermafbeelding van de minikaart -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters -STR_AI_SETTINGS_CAPTION_AI :AI +STR_AI_SETTINGS_CAPTION_AI :{WHITE}AI-parameters STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spelscript STR_AI_SETTINGS_CLOSE :{BLACK}Sluiten STR_AI_SETTINGS_RESET :{BLACK}Terugstellen @@ -4725,17 +4773,17 @@ STR_ERROR_CAN_T_SELL_25_SHARE_IN :{WHITE}Kan geen STR_ERROR_PROTECTED :{WHITE}Dit bedrijf verhandelt nog geen aandelen... # Town related errors -STR_ERROR_CAN_T_GENERATE_TOWN :{WHITE}Kan geen plaatsen bouwen -STR_ERROR_CAN_T_RENAME_TOWN :{WHITE}Kan plaats niet hernoemen... -STR_ERROR_CAN_T_FOUND_TOWN_HERE :{WHITE}Kan hier geen nieuwe plaats bouwen... +STR_ERROR_CAN_T_GENERATE_TOWN :{WHITE}Kan geen steden bouwen +STR_ERROR_CAN_T_RENAME_TOWN :{WHITE}Kan stad niet hernoemen... +STR_ERROR_CAN_T_FOUND_TOWN_HERE :{WHITE}Kan hier geen nieuwe stad bouwen... STR_ERROR_CAN_T_EXPAND_TOWN :{WHITE}Kan dorp niet uitbreiden... STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... te dicht bij de rand van de kaart STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... te dicht bij een andere plaats STR_ERROR_TOO_MANY_TOWNS :{WHITE}... te veel plaatsen STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... er is geen ruimte meer op de kaart -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}De plaats bouwt geen wegen. Het bouwen van wegen kan aangezet worden via Geavanceerde Instellingen->Omgeving->Plaatsen +STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}De stad bouwt geen wegen. Het bouwen van wegen kan aangezet worden via Instellingen->Omgeving->Steden STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Wegwerkzaamheden in uitvoering -STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan deze plaats niet verwijderen...{}Een station of depot verwijst naar deze plaats of een door de plaats beheerde tegel kan niet worden verwijderd +STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Kan deze stad niet verwijderen...{}Een station of depot verwijst naar deze plaats of een door de stad beheerde tegel kan niet worden verwijderd STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... er is geen geschikte plaats voor een standbeeld in het centrum van dit dorp # Industry related errors @@ -4743,13 +4791,14 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... te v STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Kan geen industrieën genereren... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Kan {STRING} hier niet bouwen... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Kan dit type industrie hier niet bouwen... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Kan industrie niet onderzoeken... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... te dicht bij een andere industrie STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... moet eerst dorp bouwen -STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... slechts één per plaats toegestaan -STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200 :{WHITE}... kan alleen in plaatsen met meer dan 1.200 inwoners worden gebouwd +STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... slechts één per stad toegestaan +STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200 :{WHITE}... kan alleen in steden met meer dan 1.200 inwoners worden gebouwd STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}... kan alleen in regenwouden gebouwd worden STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}... kan alleen in woestijnen gebouwd worden -STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... kan alleen in plaatsen gebouwd worden (vervangt huizen) +STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... kan alleen in steden gebouwd worden (vervangt huizen) STR_ERROR_CAN_ONLY_BE_BUILT_NEAR_TOWN_CENTER :{WHITE}... kan alleen worden gebouwd in het centrum van de stad STR_ERROR_CAN_ONLY_BE_BUILT_IN_LOW_AREAS :{WHITE}... kan alleen in laaggelegen gebieden gebouwd worden STR_ERROR_CAN_ONLY_BE_POSITIONED :{WHITE}... kan alleen aan de rand van de kaart geplaatst worden @@ -4757,8 +4806,10 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... boss STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... kan alleen boven de sneeuwlijn gebouwd worden STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... kan alleen onder de sneeuwlijn gebouwd worden -STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Er waren een geschikte locaties voor '{STRING}' industrieën -STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Parameters voor kaartontwikkeling wijzigen om een betere kaart te krijgen +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}De financiering is mislukt vanwege domme pech. Probeer het opnieuw. +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Er was geen geschikte plek voor onderzoek voor deze industrie +STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Er waren geen geschikte locaties voor {STRING}-industrieën +STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Wijzig de instellingen van wereldontwikkeling om een betere kaart te krijgen # Station construction related errors STR_ERROR_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Kan hier geen treinstation bouwen... @@ -4924,6 +4975,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Object i STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... hoofdkantoor in de weg STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Kan dit stuk land niet kopen... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... het is al van jou! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... bouwlimiet voor objecten bereikt # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Kan groep niet creëren... @@ -4996,6 +5048,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Kan onde STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... voertuig is vernietigd +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... niet alle voertuigen zijn identiek + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Er zullen geen voertuigen beschikbaar zijn STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Pas je NewGRF-configuratie aan STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Nog geen voertuigen beschikbaar @@ -5022,6 +5076,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Kan gese STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... voertuig kan niet naar alle stations STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... voertuig kan niet naar dat station STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... een voertuig die deze order deelt kan niet naar dat station +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... niet alle voertuigen hebben dezelfde orders +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... niet alle voertuigen delen hun orders STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Kan orderlijst niet delen... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Kan niet stoppen met delen van orderlijst... @@ -5029,6 +5085,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Kan orde STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... te ver van vorige bestemming STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... vliegtuig heeft niet genoeg bereik +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Er is geen station +STR_ERROR_NO_BUS_STATION :{WHITE}Er is geen bussstation +STR_ERROR_NO_TRUCK_STATION :{WHITE}Er is geen vrachtwagenlaadstation +STR_ERROR_NO_DOCK :{WHITE}Er is geen dok +STR_ERROR_NO_AIRPORT :{WHITE}Er is geen vliegveld/heliplatform +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Er zijn geen haltes met een compatibel wegtype +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Er zijn geen haltes met een compatibel type tram +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Er zijn geen haltes die geschikt zijn voor gelede wegvoertuigen.{}Gelede wegvoertuigen kunnen alleen stoppen aan de weg, niet bij een laadplatform. +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Dit vliegtuig kan niet landen op dit heliplatform +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Deze helikopter kan niet landen op dit vliegveld +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Er is geen routepunt +STR_ERROR_NO_BUOY :{WHITE}Er is geen boei + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kan geen dienstregeling opzetten voor dit voertuig... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Voertuigen kunnen alleen wachten op stations @@ -5055,7 +5125,7 @@ STR_BASESOUNDS_NONE_DESCRIPTION :Een geluidenset STR_BASEMUSIC_WIN_DESCRIPTION :Originele muziek van de Transport Tycoon Deluxe Windows-versie. STR_BASEMUSIC_DOS_DESCRIPTION :Originele muziek van Transport Tycoon Deluxe voor DOS. STR_BASEMUSIC_TTO_DESCRIPTION :Originele muziek van Transport Tycoon (Original/World Editor) voor DOS. -STR_BASEMUSIC_NONE_DESCRIPTION :Een muziekset zonder muziek. +STR_BASEMUSIC_NONE_DESCRIPTION :Geen muziek. ##id 0x2000 # Town building names diff --git a/src/lang/english.txt b/src/lang/english.txt index f5b804f613351..b35332f6184e3 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -225,9 +235,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filter string: -STR_LIST_FILTER_OSKTITLE :{BLACK}Enter filter string -STR_LIST_FILTER_TOOLTIP :{BLACK}Enter a keyword to filter the list for +STR_LIST_FILTER_TITLE :{BLACK}Filter: +STR_LIST_FILTER_OSKTITLE :{BLACK}Enter one or more keywords to filter the list for +STR_LIST_FILTER_TOOLTIP :{BLACK}Enter one or more keywords to filter the list for STR_TOOLTIP_GROUP_ORDER :{BLACK}Select grouping order STR_TOOLTIP_SORT_ORDER :{BLACK}Select sorting order (descending/ascending) @@ -376,9 +386,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Town gen STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industry generation STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Road construction STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Tramway construction -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Shift toggles building/showing cost estimate +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Place sign -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Shift toggles building/showing cost estimate +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Exit # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Game options STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Settings -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Game script settings +STR_SETTINGS_MENU_AI_SETTINGS :AI settings +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Game script settings STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF settings STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Transparency options STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Town names displayed @@ -967,37 +978,7 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indian Rupee (I STR_GAME_OPTIONS_CURRENCY_IDR :Indonesian Rupiah (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaysian Ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Drive on left -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Drive on right - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Town names: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Select style of town names - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :English (Original) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :French -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :German -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :English (Additional) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latin-American -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Silly -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Swedish -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Dutch -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finnish -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polish -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovak -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norwegian -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungarian -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austrian -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romanian -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Czech -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Swiss -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danish -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turkish -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italian -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalan - -############ start of game pace dropdown +##### game pace dropdown STR_GAME_OPTIONS_GAMEYEAR_FRAME :{BLACK}Game year lasts: STR_GAME_OPTIONS_GAMEYEAR_DROPDOWN_TOOLTIP :{BLACK}Choose how fast game year goes in real time STR_GAME_OPTIONS_GAMEYEAR_CUSTOM_NUMBER :Custom (x{NUM}) @@ -1006,7 +987,6 @@ STR_GAME_OPTIONS_GAMEYEAR_DEFAULT :15 mins (origina STR_GAME_OPTIONS_GAMEYEAR_HOUR :One hour STR_GAME_OPTIONS_GAMEYEAR_DAY :One day STR_GAME_OPTIONS_GAMEYEAR_WEEK :One week -############ end of game pace dropdown STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Autosave STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Select interval between automatic game saves @@ -1040,21 +1020,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Check th STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Current driver: {RAW_STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Interface size -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Select the interface element size to use - -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(auto-detect) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Double size -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quad size +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Interface size +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Drag slider to set interface size. Hold Ctrl for continuous adjustment +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Auto-detect size +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Check this box to detect interface size automatically -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Font size -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Select the interface font size to use +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Scale bevels +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Check this box to scale bevels by interface size -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(auto-detect) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Double size -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quad size +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Graphics @@ -1106,8 +1084,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Preview STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pound (£) in your currency STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Change custom currency parameter -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maximum no. competitors: {ORANGE}{COMMA} - STR_NONE :None STR_FUNDING_ONLY :Funding only STR_MINIMAL :Minimal @@ -1157,6 +1133,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Temperate landscape +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arctic landscape +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropical landscape +STR_CLIMATE_TOYLAND_LANDSCAPE :Toyland landscape + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Very Flat STR_TERRAIN_TYPE_FLAT :Flat @@ -1176,7 +1158,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}No suita # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Settings -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter string: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Expand all STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Collapse all STR_CONFIG_SETTING_RESET_ALL :{BLACK}Reset all values @@ -1236,6 +1218,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Right STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maximum initial loan: {STRING2} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximum amount a company can loan (without taking inflation into account) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :No loan {RED}Requires Game Script to provide initial funds STR_CONFIG_SETTING_INTEREST_RATE :Interest rate: {STRING2} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Loan interest rate; also controls inflation, if enabled @@ -1462,6 +1447,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Width of the li STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Show the NewGRF's name in the build vehicle window: {STRING2} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Add a line to the build vehicle window, showing which NewGRF the selected vehicle comes from. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Show the cargoes the vehicles can carry in the list windows {STRING2} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :If enabled, the vehicle's transportable load will appear above it in the vehicle lists STR_CONFIG_SETTING_LANDSCAPE :Landscape: {STRING2} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landscapes define basic gameplay scenarios with different cargoes and town growth requirements. NewGRF and Game Scripts allow finer control though @@ -1516,6 +1503,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Improved STR_CONFIG_SETTING_ROAD_SIDE :Road vehicles: {STRING2} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Choose the driving side +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Drive on left +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Drive on right + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Heightmap rotation: {STRING2} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Counter clockwise @@ -1949,13 +1940,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Take {STRING2}{ STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Time taken for each recalculation of a link graph component. When a recalculation is started, a thread is spawned which is allowed to run for this number of days. The shorter you set this the more likely it is that the thread is not finished when it's supposed to. Then the game stops until it is ("lag"). The longer you set it the longer it takes for the distribution to be updated when routes change. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distribution mode for passengers: {STRING2} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symmetric" means that roughly the same number of passengers will go from a station A to a station B as from B to A. "asymmetric" means that arbitrary numbers of passengers can go in either direction. "manual" means that no automatic distribution will take place for passengers. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetric" means that roughly the same number of passengers will go from a station A to a station B as from B to A. "Asymmetric" means that arbitrary numbers of passengers can go in either direction. "Manual" means that no automatic distribution will take place for passengers. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Distribution mode for mail: {STRING2} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"symmetric" means that roughly the same amount of mail will be sent from a station A to a station B as from B to A. "asymmetric" means that arbitrary amounts of mail can be sent in either direction. "manual" means that no automatic distribution will take place for mail. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Symmetric" means that roughly the same amount of mail will be sent from a station A to a station B as from B to A. "Asymmetric" means that arbitrary amounts of mail can be sent in either direction. "Manual" means that no automatic distribution will take place for mail. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Distribution mode for the ARMOURED cargo class: {STRING2} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :The ARMOURED cargo class contains valuables in the temperate, diamonds in the subtropical or gold in subarctic climate. NewGRFs may change that. "symmetric" means that roughly the same amount of that cargo will be sent from a station A to a station B as from B to A. "asymmetric" means that arbitrary amounts of that cargo can be sent in either direction. "manual" means that no automatic distribution will take place for that cargo. It is recommended to set this to asymmetric or manual when playing subarctic, as banks won't send any gold back to gold mines. For temperate and subtropical you can also choose symmetric as banks will send valuables back to the origin bank of some load of valuables. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :The ARMOURED cargo class contains valuables in the temperate, diamonds in the subtropical, or gold in the subarctic climate. NewGRFs may change that. "Symmetric" means that roughly the same amount of that cargo will be sent from a station A to a station B as from B to A. "Asymmetric" means that arbitrary amounts of that cargo can be sent in either direction. "Manual" means that no automatic distribution will take place for that cargo. It is recommended to set this to asymmetric or manual when playing subarctic or subtropic, as banks only receive cargo in these climates. For temperate you can also choose symmetric as banks will send valuables back to the origin bank. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Distribution mode for other cargo classes: {STRING2} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asymmetric" means that arbitrary amounts of cargo can be sent in either direction. "manual" means that no automatic distribution will take place for those cargoes. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asymmetric" means that arbitrary amounts of cargo can be sent in either direction. "Manual" means that no automatic distribution will take place for those cargoes. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asymmetric @@ -2050,7 +2041,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatic rever STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Allow trains to reverse on a signal, if they waited there a long time ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recommended) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Change setting value @@ -2093,7 +2084,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Highscor STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Settings STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Settings STR_INTRO_ONLINE_CONTENT :{BLACK}Check Online Content -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI/Game Script Settings +STR_INTRO_AI_SETTINGS :{BLACK}AI Settings +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Game Script Settings STR_INTRO_QUIT :{BLACK}Exit STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Start a new game. Ctrl+Click skips map configuration @@ -2113,7 +2105,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Display STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Display settings STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Display NewGRF settings STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Check for new and updated content to download -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Display AI/Game script settings +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Display AI settings +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Display Game script settings STR_INTRO_TOOLTIP_QUIT :{BLACK}Exit 'OpenTTD' STR_INTRO_BASESET :{BLACK}The currently selected base graphics set is missing {NUM} sprite{P "" s}. Please check for updates for the baseset. @@ -2145,12 +2138,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Change STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Change current year STR_CHEAT_SETUP_PROD :{LTBLUE}Enable modifying production values: {ORANGE}{STRING1} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Temperate landscape -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arctic landscape -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropical landscape -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Toyland landscape - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Colour Scheme @@ -2383,7 +2370,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(New company) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Create a new company and join it STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}This is you STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}This is the host of the game -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} compan{P y ies} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} - {NUM}/{NUM} compan{P y ies} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}The number of currently connected clients, number of companies and maximum number of companies allowed by the server administrator # Matches ConnectionType ###length 5 @@ -2510,13 +2498,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :waiting for lin STR_NETWORK_MESSAGE_CLIENT_LEAVING :leaving STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {RAW_STRING} has joined the game -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {RAW_STRING} has joined the game (Client #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {RAW_STRING} has joined company #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:RAW_STRING} has joined the game (Client #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:RAW_STRING} has joined company #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {RAW_STRING} has joined spectators -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {RAW_STRING} has started a new company (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {RAW_STRING} has left the game ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:RAW_STRING} has started a new company (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:RAW_STRING} has left the game ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {RAW_STRING} has changed their name to {RAW_STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {RAW_STRING} gave {2:CURRENCY_LONG} to {1:RAW_STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:RAW_STRING} gave {2:CURRENCY_LONG} to {1:RAW_STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The server closed the session STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait... STR_NETWORK_MESSAGE_KICKED :*** {RAW_STRING} was kicked. Reason: ({RAW_STRING}) @@ -2630,6 +2618,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}saturated STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}overloaded +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} to be transported per month from {STATION} to {STATION} ({COMMA}% of capacity){RAW_STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} to be transported back ({COMMA}% of capacity) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Average travel time: {NUM}{NBSP}day{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Coverage area highlight STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Off @@ -2638,6 +2631,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Don't hi STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Highlight coverage area of proposed site STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Accepts: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Supplies: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Maintenance cost: {GOLD}{CURRENCY_SHORT}/yr # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Join station @@ -2720,8 +2714,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Increase STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Select Rail Bridge STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Select Road Bridge STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Bridge selection - click on your preferred bridge to build it -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Suspension, Steel STR_BRIDGE_NAME_GIRDER_STEEL :Girder, Steel STR_BRIDGE_NAME_CANTILEVER_STEEL :Cantilever, Steel @@ -2825,11 +2821,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Landscap STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Lower a corner of land. Dragging lowers the first selected corner and levels the selected area to the new corner height. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Raise a corner of land. Dragging raises the first selected corner and levels the selected area to the new corner height. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Level an area of land to the height of the first selected corner. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Shift toggles building/showing cost estimate +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Object Selection -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Shift toggles building/showing cost estimate +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Select class of the object to build STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Preview of the object STR_OBJECT_BUILD_SIZE :{BLACK}Size: {GOLD}{NUM} x {NUM} tiles @@ -2841,7 +2837,7 @@ STR_OBJECT_CLASS_TRNS :Transmitters STR_PLANT_TREE_CAPTION :{WHITE}Trees STR_PLANT_TREE_TOOLTIP :{BLACK}Select tree type to plant. If the tile already has a tree, this will add more trees of mixed types independent of the selected type STR_TREES_RANDOM_TYPE :{BLACK}Trees of random type -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Shift toggles building/showing cost estimate +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Random Trees STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plant trees randomly throughout the landscape STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2873,6 +2869,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Random T STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Found town in random location STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Many random towns STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cover the map with randomly placed towns +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Expand all towns +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Make all towns grow slightly STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Town name: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Enter town name @@ -3137,7 +3135,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Game Det STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No information available STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING1} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter string: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Overwrite File STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Are you sure you want to overwrite the existing file? STR_SAVELOAD_DIRECTORY :{RAW_STRING} (Directory) @@ -3151,6 +3149,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Map size STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Select the size of the map in tiles. The number of available tiles will be slightly smaller STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}No. of towns: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Town names: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Select style of town names STR_MAPGEN_DATE :{BLACK}Date: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}No. of industries: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Highest peak: @@ -3164,13 +3164,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Desert c STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Increase desert coverage by ten percent STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Decrease desert coverage by ten percent STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Land generator: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terrain type: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Sea level: +STR_MAPGEN_SEA_LEVEL :{BLACK}Sea level: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Rivers: STR_MAPGEN_SMOOTHNESS :{BLACK}Smoothness: STR_MAPGEN_VARIETY :{BLACK}Variety distribution: STR_MAPGEN_GENERATE :{WHITE}Generate +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF Settings +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Display NewGRF settings +STR_MAPGEN_AI_SETTINGS :{BLACK}AI Settings +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Display AI settings +STR_MAPGEN_GS_SETTINGS :{BLACK}Game Script Settings +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Display game script settings + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :English (Original) +STR_MAPGEN_TOWN_NAME_FRENCH :French +STR_MAPGEN_TOWN_NAME_GERMAN :German +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :English (Additional) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latin-American +STR_MAPGEN_TOWN_NAME_SILLY :Silly +STR_MAPGEN_TOWN_NAME_SWEDISH :Swedish +STR_MAPGEN_TOWN_NAME_DUTCH :Dutch +STR_MAPGEN_TOWN_NAME_FINNISH :Finnish +STR_MAPGEN_TOWN_NAME_POLISH :Polish +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovak +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norwegian +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungarian +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austrian +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romanian +STR_MAPGEN_TOWN_NAME_CZECH :Czech +STR_MAPGEN_TOWN_NAME_SWISS :Swiss +STR_MAPGEN_TOWN_NAME_DANISH :Danish +STR_MAPGEN_TOWN_NAME_TURKISH :Turkish +STR_MAPGEN_TOWN_NAME_ITALIAN :Italian +STR_MAPGEN_TOWN_NAME_CATALAN :Catalan # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Map edges: @@ -3229,7 +3257,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Detailed STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Active NewGRF files STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Inactive NewGRF files STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Select preset: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter string: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Load the selected preset STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Save preset STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Save the current list as a preset @@ -3316,6 +3344,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Previous STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Proceed to the previous normal sprite, skipping any pseudo/recolour/font sprites and wrapping around from the first sprite to the last STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representation of the currently selected sprite. The alignment is ignored when drawing this sprite STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Move the sprite around, changing the X and Y offsets. Ctrl+Click to move the sprite eight units at a time + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Offset centred +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centred + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Crosshair + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Reset relative STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Reset the current relative offsets STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X offset: {NUM}, Y offset: {NUM} (Absolute) @@ -3330,18 +3365,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{RAW_ST STR_NEWGRF_ERROR_MSG_WARNING :{RED}Warning: {SILVER}{RAW_STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Error: {SILVER}{RAW_STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{RAW_STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}A fatal NewGRF error has occurred: {}{STRING5} -STR_NEWGRF_ERROR_POPUP :{WHITE}A NewGRF error has occurred: {}{STRING5} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}The NewGRF "{RAW_STRING}" has returned a fatal error: {}{STRING5} +STR_NEWGRF_ERROR_POPUP :{WHITE}The NewGRF "{RAW_STRING}" has returned an error: {}{STRING5} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:RAW_STRING} will not work with the TTDPatch version reported by OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:RAW_STRING} is for the {RAW_STRING} version of TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:RAW_STRING} is designed to be used with {RAW_STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Invalid parameter for {1:RAW_STRING}: parameter {RAW_STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:RAW_STRING} must be loaded before {RAW_STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:RAW_STRING} must be loaded after {RAW_STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:RAW_STRING} requires OpenTTD version {RAW_STRING} or better +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:RAW_STRING} is for the {2:RAW_STRING} version of TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:RAW_STRING} is designed to be used with {2:RAW_STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Invalid parameter for {1:RAW_STRING}: parameter {2:RAW_STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:RAW_STRING} must be loaded before {2:RAW_STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:RAW_STRING} must be loaded after {2:RAW_STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:RAW_STRING} requires OpenTTD version {2:RAW_STRING} or better STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :the GRF file it was designed to translate STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Too many NewGRFs are loaded -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Loading {1:RAW_STRING} as static NewGRF with {RAW_STRING} could cause desyncs +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Loading {1:RAW_STRING} as static NewGRF with {2:RAW_STRING} could cause desyncs STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Unexpected sprite (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Unknown Action 0 property {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Attempt to use invalid ID (sprite {3:NUM}) @@ -3473,14 +3508,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Buy exclusive t STR_LOCAL_AUTHORITY_ACTION_BRIBE :Bribe the local authority ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Initiate a small local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a small radius around the town centre.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Initiate a medium local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a medium radius around the town centre.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Initiate a large local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a large radius around the town centre.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Fund the reconstruction of the urban road network.{}Causes considerable disruption to road traffic for up to 6 months.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Build a statue in honour of your company.{}Provides a permanent boost to station rating in this town.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Fund the construction of new buildings in the town.{}Provides a temporary boost to town growth in this town.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Buy 1 year's exclusive transport rights in town.{}Town authority will not allow passengers and cargo to use your competitors' stations.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Initiate a small local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a small radius around the town centre.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Initiate a medium local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a medium radius around the town centre.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Initiate a large local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a large radius around the town centre.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Fund the reconstruction of the urban road network.{}Causes considerable disruption to road traffic for up to 6 months.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Build a statue in honour of your company.{}Provides a permanent boost to station rating in this town.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Fund the construction of new buildings in the town.{}Provides a temporary boost to town growth in this town.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Buy 1 year's exclusive transport rights in town.{}Town authority will not allow passengers and cargo to use your competitors' stations.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{}{POP_COLOUR}Cost: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Goals @@ -3653,15 +3688,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Ships STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Loan Interest STR_FINANCES_SECTION_OTHER :{GOLD}Other +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Net Profit +STR_FINANCES_PROFIT :{WHITE}Profit STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Bank Balance STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Own Funds STR_FINANCES_LOAN_TITLE :{WHITE}Loan STR_FINANCES_INTEREST_RATE :{WHITE}Loan Interest: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maximum Loan: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Borrow {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Increase size of loan. Ctrl+Click borrows as much as possible STR_FINANCES_REPAY_BUTTON :{BLACK}Repay {CURRENCY_LONG} @@ -3762,7 +3800,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produces STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{RAW_STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Requires: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:RAW_STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:RAW_STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} waiting{RAW_STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Change production (multiple of 8, up to 2040) @@ -3792,6 +3830,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Send ins STR_VEHICLE_LIST_REPLACE_VEHICLES :Replace vehicles STR_VEHICLE_LIST_SEND_FOR_SERVICING :Send for Servicing STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Profit this year: {CURRENCY_LONG} (last year: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING1} {STRING1} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Send to Depot STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Send to Depot @@ -3883,6 +3923,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Tra STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Range: {GOLD}{COMMA} tiles STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Aircraft type: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :All cargo types +STR_CARGO_TYPE_FILTER_FREIGHT :Freight +STR_CARGO_TYPE_FILTER_NONE :None + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Train vehicle selection list. Click on vehicle for information. Ctrl+Click for toggling hiding of the vehicle type STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Road vehicle selection list. Click on vehicle for information. Ctrl+Click for toggling hiding of the vehicle type @@ -4051,7 +4096,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :aircraft STR_ENGINE_PREVIEW_SHIP :ship STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cost: {CURRENCY_LONG} Weight: {WEIGHT_SHORT}{}Speed: {VELOCITY} Power: {POWER}{}Running Cost: {CURRENCY_LONG}/yr{}Capacity: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {CURRENCY_LONG} Weight: {WEIGHT_SHORT}{}Speed: {VELOCITY} Power: {POWER} Max. T.E.: {6:FORCE}{}Running Cost: {4:CURRENCY_LONG}/yr{}Capacity: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {0:CURRENCY_LONG} Weight: {1:WEIGHT_SHORT}{}Speed: {2:VELOCITY} Power: {3:POWER} Max. T.E.: {6:FORCE}{}Running Cost: {4:CURRENCY_LONG}/yr{}Capacity: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING}{}Capacity: {CARGO_LONG}, {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr @@ -4210,12 +4255,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Weight: STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Weight: {LTBLUE}{WEIGHT_SHORT} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY_LONG} (last year: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Profit this year: {LTBLUE}{CURRENCY_LONG} (last year: {CURRENCY_LONG}) {BLACK}Min. performance: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacity: {LTBLUE}None{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacity: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacity: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transfer Credits: {LTBLUE}{CURRENCY_LONG} @@ -4491,22 +4537,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Start da STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Select a date as starting point of this timetable. Ctrl+Click distributes all vehicles sharing this order evenly from the given date based on their relative order, if the order is completely timetabled STR_TIMETABLE_CHANGE_TIME :{BLACK}Change Time -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Change the amount of time that the highlighted order should take +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Change the amount of time that the highlighted order should take. Ctrl+Click sets the time for all orders STR_TIMETABLE_CLEAR_TIME :{BLACK}Clear Time -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Clear the amount of time for the highlighted order +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Clear the amount of time for the highlighted order. Ctrl+Click clears the time for all orders STR_TIMETABLE_CHANGE_SPEED :{BLACK}Change Speed Limit -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Change the maximum travel speed of the highlighted order +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Change the maximum travel speed of the highlighted order. Ctrl+Click sets the speed for all orders STR_TIMETABLE_CLEAR_SPEED :{BLACK}Clear Speed Limit -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Clear the maximum travel speed of the highlighted order +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Clear the maximum travel speed of the highlighted order. Ctrl+Click clears the speed for all orders STR_TIMETABLE_RESET_LATENESS :{BLACK}Reset Late Counter -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reset the lateness counter, so the vehicle will be on time +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reset the lateness counter, so the vehicle will be on time. Ctrl+Click will reset the entire group so the latest vehicle will be on time and all others will be early STR_TIMETABLE_AUTOFILL :{BLACK}Autofill -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fill the timetable automatically with the values from the next journey (Ctrl+Click to try to keep waiting times) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fill the timetable automatically with the values from the next journey. Ctrl+Click to try to keep waiting times STR_TIMETABLE_EXPECTED :{BLACK}Expected STR_TIMETABLE_SCHEDULED :{BLACK}Scheduled @@ -4564,12 +4610,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}One of t STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/Game Script Debug window is only available for the server # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI/Game Script Configuration +STR_AI_CONFIG_CAPTION_AI :{WHITE}AI Configuration +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Game Script Configuration STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}The Game Script that will be loaded in the next game STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}The AIs that will be loaded in the next game STR_AI_CONFIG_HUMAN_PLAYER :Human player STR_AI_CONFIG_RANDOM_AI :Random AI STR_AI_CONFIG_NONE :(none) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maximum no. competitors: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Move Up STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Move selected AI up in the list @@ -4577,12 +4625,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Move Dow STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Move selected AI down in the list STR_AI_CONFIG_GAMESCRIPT :{SILVER}Game Script +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parameters STR_AI_CONFIG_AI :{SILVER}AIs -STR_AI_CONFIG_CHANGE :{BLACK}Select {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Game Script +STR_AI_CONFIG_CHANGE_AI :{BLACK}Select AI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Select Game Script STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Load another script STR_AI_CONFIG_CONFIGURE :{BLACK}Configure STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configure the parameters of the Script @@ -4610,7 +4657,7 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Whole ma STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Heightmap screenshot STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minimap screenshot -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters STR_AI_SETTINGS_CAPTION_AI :AI STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Game Script @@ -4777,6 +4824,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... too STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Can't generate industries... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Can't build {STRING} here... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Can't construct this industry type here... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Can't prospect industry... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... too close to another industry STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... must found town first STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... only one allowed per town @@ -4791,6 +4839,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... fore STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... can only be built above the snow-line STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... can only be built below the snow-line +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}The funding failed to prospect due to bad luck; try again +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}There were no suitable places to prospect for this industry STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}There were no suitable places for '{STRING}' industries STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Change the map generation parameters to get a better map @@ -4958,6 +5008,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Object i STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... company headquarters in the way STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Can't purchase this land area... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... you already own it! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... object construction limit reached # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Can't create group... @@ -5030,6 +5081,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Can't ch STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vehicle is destroyed +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... not all vehicles are identical + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}No vehicles will be available at all STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Change your NewGRF configuration STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}No vehicles are available yet @@ -5056,6 +5109,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Can't sk STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... vehicle can't go to all stations STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... vehicle can't go to that station STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... a vehicle sharing this order can't go to that station +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... not all vehicles have the same orders +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... not all vehicles are sharing orders STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Can't share order list... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Can't stop sharing order list... @@ -5063,6 +5118,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Can't co STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... too far from previous destination STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... aircraft has not enough range +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}There is no railway station +STR_ERROR_NO_BUS_STATION :{WHITE}There is no bus station +STR_ERROR_NO_TRUCK_STATION :{WHITE}There is no lorry station +STR_ERROR_NO_DOCK :{WHITE}There is no dock +STR_ERROR_NO_AIRPORT :{WHITE}There is no airport/heliport +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}There are no stops with a compatible road type +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}There are no stops with a compatible tram type +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}There are no stops which are suitable for articulated road vehicles.{}Articulated road vehicles require a drive-through stop, not a bay stop +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}This plane cannot land at this heliport +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}This helicopter cannot land at this airport +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}There is no railway waypoint +STR_ERROR_NO_BUOY :{WHITE}There is no buoy + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Can't timetable vehicle... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Vehicles can only wait at stations diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index 41ad55245c327..f2044c17e5d64 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -225,9 +235,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filter string: -STR_LIST_FILTER_OSKTITLE :{BLACK}Enter filter string -STR_LIST_FILTER_TOOLTIP :{BLACK}Enter a keyword to filter the list for +STR_LIST_FILTER_TITLE :{BLACK}Filter: +STR_LIST_FILTER_OSKTITLE :{BLACK}Enter one or more keywords to filter the list for +STR_LIST_FILTER_TOOLTIP :{BLACK}Enter one or more keywords to filter the list for STR_TOOLTIP_GROUP_ORDER :{BLACK}Select grouping order STR_TOOLTIP_SORT_ORDER :{BLACK}Select sorting order (descending/ascending) @@ -376,9 +386,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Town gen STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industry generation STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Road construction STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Tramway construction -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Shift toggles building/showing cost estimate +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Place sign -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Shift toggles building/showing cost estimate +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Exit # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Game options STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Settings -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Game script settings +STR_SETTINGS_MENU_AI_SETTINGS :AI settings +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Game script settings STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF settings STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Transparency options STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Town names displayed @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indian Rupee (I STR_GAME_OPTIONS_CURRENCY_IDR :Indonesian Rupiah (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaysian Ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Drive on left -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Drive on right - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Town names: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Select style of town names - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :English (Original) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :French -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :German -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :English (Additional) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latin-American -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Silly -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Swedish -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Dutch -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finnish -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polish -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovak -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norwegian -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungarian -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austrian -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romanian -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Czech -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Swiss -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danish -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turkish -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italian -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalan - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Autosave STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Select interval between automatic game saves @@ -1027,21 +1008,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Check th STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Current driver: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Interface size -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Select the interface element size to use +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Interface size +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Drag slider to set interface size. Hold Ctrl for continuous adjustment +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Auto-detect size +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Check this box to detect interface size automatically -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(auto-detect) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Double size -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quad size +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Scale bevels +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Check this box to scale bevels by interface size -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Font size -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Select the interface font size to use - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(auto-detect) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Double size -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quad size +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Graphics @@ -1093,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Preview STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pound (£) in your currency STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Change custom currency parameter -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maximum no. competitors: {ORANGE}{COMMA} - STR_NONE :None STR_FUNDING_ONLY :Funding only STR_MINIMAL :Minimal @@ -1144,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Temperate landscape +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arctic landscape +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropical landscape +STR_CLIMATE_TOYLAND_LANDSCAPE :Toyland landscape + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Very Flat STR_TERRAIN_TYPE_FLAT :Flat @@ -1163,7 +1146,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}No suita # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Settings -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter string: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Expand all STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Collapse all STR_CONFIG_SETTING_RESET_ALL :{BLACK}Reset all values @@ -1223,6 +1206,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Right STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maximum initial loan: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximum amount a company can loan (without taking inflation into account) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :No loan {RED}Requires Game Script to provide initial funds STR_CONFIG_SETTING_INTEREST_RATE :Interest rate: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Loan interest rate; also controls inflation, if enabled @@ -1449,6 +1435,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Width of the li STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Show the NewGRF's name in the build vehicle window: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Add a line to the build vehicle window, showing which NewGRF the selected vehicle comes from. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Show the cargoes the vehicles can carry in the list windows {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :If enabled, the vehicle's transportable load will appear above it in the vehicle lists STR_CONFIG_SETTING_LANDSCAPE :Landscape: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landscapes define basic gameplay scenarios with different cargoes and town growth requirements. NewGRF and Game Scripts allow finer control though @@ -1503,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Improved STR_CONFIG_SETTING_ROAD_SIDE :Road vehicles: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Choose the driving side +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Drive on left +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Drive on right + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Heightmap rotation: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Counter clockwise @@ -1936,13 +1928,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Take {STRING}{N STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Time taken for each recalculation of a link graph component. When a recalculation is started, a thread is spawned which is allowed to run for this number of days. The shorter you set this the more likely it is that the thread is not finished when it's supposed to. Then the game stops until it is ("lag"). The longer you set it the longer it takes for the distribution to be updated when routes change. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distribution mode for passengers: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symmetric" means that roughly the same number of passengers will go from a station A to a station B as from B to A. "asymmetric" means that arbitrary numbers of passengers can go in either direction. "manual" means that no automatic distribution will take place for passengers. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetric" means that roughly the same number of passengers will go from a station A to a station B as from B to A. "Asymmetric" means that arbitrary numbers of passengers can go in either direction. "Manual" means that no automatic distribution will take place for passengers. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Distribution mode for mail: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"symmetric" means that roughly the same amount of mail will be sent from a station A to a station B as from B to A. "asymmetric" means that arbitrary amounts of mail can be sent in either direction. "manual" means that no automatic distribution will take place for mail. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Symmetric" means that roughly the same amount of mail will be sent from a station A to a station B as from B to A. "Asymmetric" means that arbitrary amounts of mail can be sent in either direction. "Manual" means that no automatic distribution will take place for mail. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Distribution mode for the ARMOURED cargo class: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :The ARMOURED cargo class contains valuables in the temperate, diamonds in the subtropical or gold in subarctic climate. NewGRFs may change that. "symmetric" means that roughly the same amount of that cargo will be sent from a station A to a station B as from B to A. "asymmetric" means that arbitrary of that cargo can be sent in either direction. "manual" means that no automatic distribution will take place for that cargo. It is recommended to set this to asymmetric or manual when playing subarctic, as banks won't send any gold back to gold mines. For temperate and subtropical you can also choose symmetric as banks will send valuables back to the origin bank of some load of valuables. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :The ARMOURED cargo class contains valuables in the temperate, diamonds in the subtropical, or gold in the subarctic climate. NewGRFs may change that. "Symmetric" means that roughly the same amount of that cargo will be sent from a station A to a station B as from B to A. "Asymmetric" means that arbitrary amounts of that cargo can be sent in either direction. "Manual" means that no automatic distribution will take place for that cargo. It is recommended to set this to asymmetric or manual when playing subarctic or subtropic, as banks only receive cargo in these climates. For temperate you can also choose symmetric as banks will send valuables back to the origin bank. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Distribution mode for other cargo classes: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asymmetric" means that arbitrary amounts of cargo can be sent in either direction. "manual" means that no automatic distribution will take place for those cargoes. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asymmetric" means that arbitrary amounts of cargo can be sent in either direction. "Manual" means that no automatic distribution will take place for those cargoes. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asymmetric @@ -2037,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatic rever STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Allow trains to reverse on a signal, if they have waited there a long time ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recommended) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Change setting value @@ -2080,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Highscor STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Settings STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Settings STR_INTRO_ONLINE_CONTENT :{BLACK}Check Online Content -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI/Game Script Settings +STR_INTRO_AI_SETTINGS :{BLACK}AI Settings +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Game Script Settings STR_INTRO_QUIT :{BLACK}Exit STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Start a new game. Ctrl+Click skips map configuration @@ -2100,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Display STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Display settings STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Display NewGRF settings STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Check for new and updated content to download -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Display AI/Game script settings +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Display AI settings +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Display Game script settings STR_INTRO_TOOLTIP_QUIT :{BLACK}Exit 'OpenTTD' STR_INTRO_BASESET :{BLACK}The currently selected base graphics set is missing {NUM} sprite{P "" s}. Please check for updates for the baseset. @@ -2132,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Change STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Change current year STR_CHEAT_SETUP_PROD :{LTBLUE}Enable modifying production values: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Temperate landscape -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arctic landscape -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropical landscape -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Toyland landscape - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Colour Scheme @@ -2370,7 +2358,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(New company) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Create a new company and join it STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}This is you STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}This is the host of the game -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} compan{P y ies} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} - {NUM}/{NUM} compan{P y ies} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}The number of currently connected clients, number of companies and maximum number of companies allowed by the server administrator # Matches ConnectionType ###length 5 @@ -2497,13 +2486,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :waiting for lin STR_NETWORK_MESSAGE_CLIENT_LEAVING :leaving STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} has joined the game -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} has joined the game (Client #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} has joined company #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} has joined the game (Client #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} has joined company #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} has joined spectators -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} has started a new company (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} has left the game ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} has started a new company (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} has left the game ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} has changed their name to {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} gave {2:CURRENCY_LONG} to {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} gave {2:CURRENCY_LONG} to {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The server closed the session STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait... STR_NETWORK_MESSAGE_KICKED :*** {STRING} was kicked. Reason: ({STRING}) @@ -2617,6 +2606,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}saturated STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}overloaded +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} to be transported per month from {STATION} to {STATION} ({COMMA}% of capacity){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} to be transported back ({COMMA}% of capacity) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Average travel time: {NUM}{NBSP}day{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Coverage area highlight STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Off @@ -2625,6 +2619,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Don't hi STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Highlight coverage area of proposed site STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Accepts: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Supplies: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Maintenance cost: {GOLD}{CURRENCY_SHORT}/yr # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Join station @@ -2707,8 +2702,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Increase STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Select Rail Bridge STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Select Road Bridge STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Bridge selection - click on your preferred bridge to build it -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Suspension, Steel STR_BRIDGE_NAME_GIRDER_STEEL :Girder, Steel STR_BRIDGE_NAME_CANTILEVER_STEEL :Cantilever, Steel @@ -2812,11 +2809,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Landscap STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Lower a corner of land. Dragging lowers the first selected corner and levels the selected area to the new corner height. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Raise a corner of land. Dragging raises the first selected corner and levels the selected area to the new corner height. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Level an area of land to the height of the first selected corner. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Shift toggles building/showing cost estimate +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Object Selection -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Shift toggles building/showing cost estimate +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Select class of the object to build STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Preview of the object STR_OBJECT_BUILD_SIZE :{BLACK}Size: {GOLD}{NUM} x {NUM} tiles @@ -2828,7 +2825,7 @@ STR_OBJECT_CLASS_TRNS :Transmitters STR_PLANT_TREE_CAPTION :{WHITE}Trees STR_PLANT_TREE_TOOLTIP :{BLACK}Select tree type to plant. If the tile already has a tree, this will add more trees of mixed types independent of the selected type STR_TREES_RANDOM_TYPE :{BLACK}Trees of random type -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Shift toggles building/showing cost estimate +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Random Trees STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plant trees randomly throughout the landscape STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2860,6 +2857,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Random T STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Found town in random location STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Many random towns STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cover the map with randomly placed towns +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Expand all towns +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Make all towns grow slightly STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Town name: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Enter town name @@ -3124,7 +3123,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Game Det STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No information available STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter string: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Overwrite File STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Are you sure you want to overwrite the existing file? STR_SAVELOAD_DIRECTORY :{STRING} (Directory) @@ -3138,6 +3137,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Map size STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Select the size of the map in tiles. The number of available tiles will be slightly smaller STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}No. of towns: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Town names: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Select style of town names STR_MAPGEN_DATE :{BLACK}Date: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}No. of industries: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Highest peak: @@ -3151,13 +3152,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Desert c STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Increase desert coverage by ten percent STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Decrease desert coverage by ten percent STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Land generator: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terrain type: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Sea level: +STR_MAPGEN_SEA_LEVEL :{BLACK}Sea level: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Rivers: STR_MAPGEN_SMOOTHNESS :{BLACK}Smoothness: STR_MAPGEN_VARIETY :{BLACK}Variety distribution: STR_MAPGEN_GENERATE :{WHITE}Generate +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF Settings +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Display NewGRF settings +STR_MAPGEN_AI_SETTINGS :{BLACK}AI Settings +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Display AI settings +STR_MAPGEN_GS_SETTINGS :{BLACK}Game Script Settings +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Display game script settings + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :English (Original) +STR_MAPGEN_TOWN_NAME_FRENCH :French +STR_MAPGEN_TOWN_NAME_GERMAN :German +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :English (Additional) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latin-American +STR_MAPGEN_TOWN_NAME_SILLY :Silly +STR_MAPGEN_TOWN_NAME_SWEDISH :Swedish +STR_MAPGEN_TOWN_NAME_DUTCH :Dutch +STR_MAPGEN_TOWN_NAME_FINNISH :Finnish +STR_MAPGEN_TOWN_NAME_POLISH :Polish +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovak +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norwegian +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungarian +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austrian +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romanian +STR_MAPGEN_TOWN_NAME_CZECH :Czech +STR_MAPGEN_TOWN_NAME_SWISS :Swiss +STR_MAPGEN_TOWN_NAME_DANISH :Danish +STR_MAPGEN_TOWN_NAME_TURKISH :Turkish +STR_MAPGEN_TOWN_NAME_ITALIAN :Italian +STR_MAPGEN_TOWN_NAME_CATALAN :Catalan # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Map edges: @@ -3216,7 +3245,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Detailed STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Active NewGRF files STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Inactive NewGRF files STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Select preset: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter string: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Load the selected preset STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Save preset STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Save the current list as a preset @@ -3303,6 +3332,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Previous STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Proceed to the previous normal sprite, skipping any pseudo/recolour/font sprites and wrapping around at the begin STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representation of the currently selected sprite. The alignment is ignored when drawing this sprite STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Move the sprite around, changing the X and Y offsets + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Offset centred +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centred + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Crosshair + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Reset relative STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Reset the current relative offsets STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X offset: {NUM}, Y offset: {NUM} (Absolute) @@ -3317,18 +3353,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Warning: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Error: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}A fatal NewGRF error has occurred:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}A NewGRF error has occurred:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}The NewGRF "{STRING}" has returned a fatal error:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}The NewGRF "{STRING}" has returned an error:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} will not work with the TTDPatch version reported by OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} is for the {STRING} version of TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} is designed to be used with {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Invalid parameter for {1:STRING}: parameter {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} must be loaded before {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} must be loaded after {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requires OpenTTD version {STRING} or better +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} is for the {2:STRING} version of TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} is designed to be used with {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Invalid parameter for {1:STRING}: parameter {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} must be loaded before {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} must be loaded after {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requires OpenTTD version {2:STRING} or better STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :the GRF file it was designed to translate STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Too many NewGRFs are loaded -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Loading {1:STRING} as static NewGRF with {STRING} could cause desyncs +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Loading {1:STRING} as static NewGRF with {2:STRING} could cause desyncs STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Unexpected sprite (sptite{3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Unknown Action 0 property {4:HEX} (sprite{3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Attempt to use invalid ID (sprite{3:NUM}) @@ -3460,14 +3496,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Buy exclusive t STR_LOCAL_AUTHORITY_ACTION_BRIBE :Bribe the local authority ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Initiate a small local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a small radius around the town centre.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Initiate a medium local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a medium radius around the town centre.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Initiate a large local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a large radius around the town centre.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Fund the reconstruction of the urban road network.{}Causes considerable disruption to road traffic for up to 6 months.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Build a statue in honour of your company.{}Provides a permanent boost to station rating in this town.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Fund the construction of new buildings in the town.{}Provides a temporary boost to town growth in this town.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Buy 1 year's exclusive transport rights in town.{}Town authority will not allow passengers and cargo to use your competitors' stations.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Initiate a small local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a small radius around the town centre.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Initiate a medium local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a medium radius around the town centre.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Initiate a large local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a large radius around the town centre.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Fund the reconstruction of the urban road network.{}Causes considerable disruption to road traffic for up to 6 months.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Build a statue in honour of your company.{}Provides a permanent boost to station rating in this town.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Fund the construction of new buildings in the town.{}Provides a temporary boost to town growth in this town.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Buy 1 year's exclusive transport rights in town.{}Town authority will not allow passengers and cargo to use your competitors' stations.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{}{POP_COLOUR}Cost: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Goals @@ -3640,15 +3676,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Ships STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Loan Interest STR_FINANCES_SECTION_OTHER :{GOLD}Other +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Net Profit +STR_FINANCES_PROFIT :{WHITE}Profit STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Bank Balance STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Own Funds STR_FINANCES_LOAN_TITLE :{WHITE}Loan STR_FINANCES_INTEREST_RATE :{WHITE}Loan Interest: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maximum Loan: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Borrow {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Increase size of loan. Ctrl+Click borrows as much as possible STR_FINANCES_REPAY_BUTTON :{BLACK}Repay {CURRENCY_LONG} @@ -3749,7 +3788,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produces STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Requires: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} waiting{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Change production (multiple of 8, up to 2040) @@ -3779,6 +3818,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Send ins STR_VEHICLE_LIST_REPLACE_VEHICLES :Replace vehicles STR_VEHICLE_LIST_SEND_FOR_SERVICING :Send for Servicing STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Profit this year: {CURRENCY_LONG} (last year: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Send to Depot STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Send to Depot @@ -3870,6 +3911,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Tra STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Range: {GOLD}{COMMA} tiles STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Aircraft type: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :All cargo types +STR_CARGO_TYPE_FILTER_FREIGHT :Freight +STR_CARGO_TYPE_FILTER_NONE :None + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Train vehicle selection list - click on vehicle for information STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Road vehicle selection list - click on vehicle for information @@ -4038,7 +4084,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :aircraft STR_ENGINE_PREVIEW_SHIP :ship STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cost: {CURRENCY_LONG} Weight: {WEIGHT_SHORT}{}Speed: {VELOCITY} Power: {POWER}{}Running Cost: {CURRENCY_LONG}/yr{}Capacity: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {CURRENCY_LONG} Weight: {WEIGHT_SHORT}{}Speed: {VELOCITY} Power: {POWER} Max. T.E.: {6:FORCE}{}Running Cost: {4:CURRENCY_LONG}/yr{}Capacity: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {0:CURRENCY_LONG} Weight: {1:WEIGHT_SHORT}{}Speed: {2:VELOCITY} Power: {3:POWER} Max. T.E.: {6:FORCE}{}Running Cost: {4:CURRENCY_LONG}/yr{}Capacity: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING}{}Capacity: {CARGO_LONG}, {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr @@ -4197,12 +4243,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Weight: STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Weight: {LTBLUE}{WEIGHT_SHORT} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY_LONG} (last year: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Profit this year: {LTBLUE}{CURRENCY_LONG} (last year: {CURRENCY_LONG}) {BLACK}Min. performance: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last service: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacity: {LTBLUE}None{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacity: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacity: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transfer Credits: {LTBLUE}{CURRENCY_LONG} @@ -4471,22 +4518,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Start da STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Select a date as starting point of this timetable. Ctrl+Click distributes all vehicles sharing this order evenly from the given date based on their relative order, if the order is completely timetabled STR_TIMETABLE_CHANGE_TIME :{BLACK}Change Time -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Change the amount of time that the highlighted order should take +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Change the amount of time that the highlighted order should take. Ctrl+Click sets the time for all orders STR_TIMETABLE_CLEAR_TIME :{BLACK}Clear Time -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Clear the amount of time for the highlighted order +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Clear the amount of time for the highlighted order. Ctrl+Click clears the time for all orders STR_TIMETABLE_CHANGE_SPEED :{BLACK}Change Speed Limit -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Change the maximum travel speed of the highlighted order +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Change the maximum travel speed of the highlighted order. Ctrl+Click sets the speed for all orders STR_TIMETABLE_CLEAR_SPEED :{BLACK}Clear Speed Limit -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Clear the maximum travel speed of the highlighted order +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Clear the maximum travel speed of the highlighted order. Ctrl+Click clears the speed for all orders STR_TIMETABLE_RESET_LATENESS :{BLACK}Reset Late Counter -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reset the lateness counter, so the vehicle will be on time +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reset the lateness counter, so the vehicle will be on time. Ctrl+Click will reset the entire group so the latest vehicle will be on time and all others will be early STR_TIMETABLE_AUTOFILL :{BLACK}Autofill -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fill the timetable automatically with the values from the next journey (Ctrl+Click to try to keep waiting times) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fill the timetable automatically with the values from the next journey. Ctrl+Click to try to keep waiting times STR_TIMETABLE_EXPECTED :{BLACK}Expected STR_TIMETABLE_SCHEDULED :{BLACK}Scheduled @@ -4530,12 +4577,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}One of t STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI / GameScript Debug window is only available for the server # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI/Game Script Configuration +STR_AI_CONFIG_CAPTION_AI :{WHITE}AI Configuration +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Game Script Configuration STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}The Game Script that will be loaded in the next game STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}The AIs that will be loaded in the next game STR_AI_CONFIG_HUMAN_PLAYER :Human player STR_AI_CONFIG_RANDOM_AI :Random AI STR_AI_CONFIG_NONE :(none) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maximum no. competitors: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Move Up STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Move selected AI up in the list @@ -4543,12 +4592,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Move Dow STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Move selected AI down in the list STR_AI_CONFIG_GAMESCRIPT :{SILVER}Game Script +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parameters STR_AI_CONFIG_AI :{SILVER}AIs -STR_AI_CONFIG_CHANGE :{BLACK}Select {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Game Script +STR_AI_CONFIG_CHANGE_AI :{BLACK}Select AI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Select Game Script STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Load another script STR_AI_CONFIG_CONFIGURE :{BLACK}Configure STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configure the parameters of the Script @@ -4576,7 +4624,7 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Whole ma STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Heightmap screenshot STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minimap screenshot -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters STR_AI_SETTINGS_CAPTION_AI :AI STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Game Script @@ -4743,6 +4791,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... too STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Can't generate industries... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Can't build {STRING} here... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Can't construct this industry type here... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Can't prospect industry... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... too close to another industry STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... must found town first STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... only one allowed per town @@ -4757,6 +4806,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... fore STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... can only be built above the snow-line STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... can only be built below the snow-line +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}The funding failed to prospect due to bad luck; try again +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}There were no suitable places to prospect for this industry STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}There were no suitable places for '{STRING}' industries STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Change the map generation parameters to get a better map @@ -4924,6 +4975,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Object i STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... company headquarters in the way STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Can't purchase this land area... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... you already own it! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... object construction limit reached # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Can't create group... @@ -4996,6 +5048,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Can't ch STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vehicle is destroyed +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... not all vehicles are identical + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}No vehicles will be available at all STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Change your NewGRF configuration STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}No vehicles are available yet @@ -5022,6 +5076,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Can't sk STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... vehicle can't go to all stations STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... vehicle can't go to that station STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... a vehicle sharing this order can't go to that station +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... not all vehicles have the same orders +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... not all vehicles are sharing orders STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Can't share order list... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Can't stop sharing order list... @@ -5029,6 +5085,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Can't co STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... too far from previous destination STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... aircraft has not enough range +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}There is no railway station +STR_ERROR_NO_BUS_STATION :{WHITE}There is no bus station +STR_ERROR_NO_TRUCK_STATION :{WHITE}There is no lorry station +STR_ERROR_NO_DOCK :{WHITE}There is no dock +STR_ERROR_NO_AIRPORT :{WHITE}There is no airport/heliport +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}There are no stops with a compatible road type +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}There are no stops with a compatible tram type +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}There are no stops which are suitable for articulated road vehicles.{}Articulated road vehicles require a drive-through stop, not a bay stop +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}This plane cannot land at this heliport +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}This helicopter cannot land at this airport +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}There is no railway waypoint +STR_ERROR_NO_BUOY :{WHITE}There is no buoy + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Can't timetable vehicle... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Vehicles can only wait at stations diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 01e0f45700bde..11d93e1e5bc20 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -37,7 +37,7 @@ STR_CARGO_PLURAL_IRON_ORE :Iron Ore STR_CARGO_PLURAL_STEEL :Steel STR_CARGO_PLURAL_VALUABLES :Valuables STR_CARGO_PLURAL_COPPER_ORE :Copper Ore -STR_CARGO_PLURAL_MAIZE :Maize +STR_CARGO_PLURAL_MAIZE :Corn STR_CARGO_PLURAL_FRUIT :Fruit STR_CARGO_PLURAL_DIAMONDS :Diamonds STR_CARGO_PLURAL_FOOD :Food @@ -71,7 +71,7 @@ STR_CARGO_SINGULAR_IRON_ORE :Iron Ore STR_CARGO_SINGULAR_STEEL :Steel STR_CARGO_SINGULAR_VALUABLES :Valuables STR_CARGO_SINGULAR_COPPER_ORE :Copper Ore -STR_CARGO_SINGULAR_MAIZE :Maize +STR_CARGO_SINGULAR_MAIZE :Corn STR_CARGO_SINGULAR_FRUIT :Fruit STR_CARGO_SINGULAR_DIAMOND :Diamond STR_CARGO_SINGULAR_FOOD :Food @@ -105,7 +105,7 @@ STR_QUANTITY_IRON_ORE :{WEIGHT_LONG} o STR_QUANTITY_STEEL :{WEIGHT_LONG} of steel STR_QUANTITY_VALUABLES :{COMMA}{NBSP}bag{P "" s} of valuables STR_QUANTITY_COPPER_ORE :{WEIGHT_LONG} of copper ore -STR_QUANTITY_MAIZE :{WEIGHT_LONG} of maize +STR_QUANTITY_MAIZE :{WEIGHT_LONG} of corn STR_QUANTITY_FRUIT :{WEIGHT_LONG} of fruit STR_QUANTITY_DIAMONDS :{COMMA}{NBSP}bag{P "" s} of diamonds STR_QUANTITY_FOOD :{WEIGHT_LONG} of food @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -225,9 +235,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filter string: -STR_LIST_FILTER_OSKTITLE :{BLACK}Enter filter string -STR_LIST_FILTER_TOOLTIP :{BLACK}Enter a keyword to filter the list for +STR_LIST_FILTER_TITLE :{BLACK}Filter: +STR_LIST_FILTER_OSKTITLE :{BLACK}Enter one or more keywords to filter the list for +STR_LIST_FILTER_TOOLTIP :{BLACK}Enter one or more keywords to filter the list for STR_TOOLTIP_GROUP_ORDER :{BLACK}Select grouping order STR_TOOLTIP_SORT_ORDER :{BLACK}Select sorting order (descending/ascending) @@ -376,9 +386,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Town gen STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industry generation STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Road construction STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Streetcar line construction -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Shift toggles building/showing cost estimate +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trees. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Place sign -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Shift toggles building/showing cost estimate +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Quit # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Game options STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Settings -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Game script settings +STR_SETTINGS_MENU_AI_SETTINGS :AI settings +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Game script settings STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF settings STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Transparency options STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Town names displayed @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indian Rupee (I STR_GAME_OPTIONS_CURRENCY_IDR :Indonesian Rupiah (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaysian Ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Drive on left -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Drive on right - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Town names: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Select style of town names - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :English (Original) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :French -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :German -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :English (Additional) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latin-American -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Silly -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Swedish -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Dutch -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finnish -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polish -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovak -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norwegian -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungarian -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austrian -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romanian -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Czech -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Swiss -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danish -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turkish -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italian -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalan - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Autosave STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Select interval between automatic game saves @@ -1027,21 +1008,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Check th STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Current driver: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Interface size -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Select the interface element size to use +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Interface size +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Drag slider to set interface size. Hold Ctrl for continuous adjustment +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Auto-detect size +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Check this box to detect interface size automatically -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(auto-detect) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Double size -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quad size +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Scale bevels +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Check this box to scale bevels by interface size -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Font size -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Select the interface font size to use - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(auto-detect) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Double size -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quad size +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Graphics @@ -1093,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Preview STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pound (£) in your currency STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Change custom currency parameter -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maximum no. competitors: {ORANGE}{COMMA} - STR_NONE :None STR_FUNDING_ONLY :Funding only STR_MINIMAL :Minimal @@ -1144,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Temperate landscape +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arctic landscape +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropical landscape +STR_CLIMATE_TOYLAND_LANDSCAPE :Toyland landscape + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Very Flat STR_TERRAIN_TYPE_FLAT :Flat @@ -1163,7 +1146,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}No suita # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Settings -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter string: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Expand all STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Collapse all STR_CONFIG_SETTING_RESET_ALL :{BLACK}Reset all values @@ -1223,6 +1206,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Right STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maximum initial loan: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximum amount a company can loan (without taking inflation into account) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :No loan {RED}Requires Game Script to provide initial funds STR_CONFIG_SETTING_INTEREST_RATE :Interest rate: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Loan interest rate; also controls inflation, if enabled @@ -1449,6 +1435,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Width of the li STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Show the NewGRF's name in the build vehicle window: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Add a line to the build vehicle window, showing which NewGRF the selected vehicle comes from. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Show the cargos the vehicles can carry in the list windows {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :If enabled, the vehicle's transportable load will appear above it in the vehicle lists STR_CONFIG_SETTING_LANDSCAPE :Landscape: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landscapes define basic gameplay scenarios with different cargos and town growth requirements. NewGRF and Game Scripts allow finer control though @@ -1503,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Improved STR_CONFIG_SETTING_ROAD_SIDE :Road vehicles: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Choose the driving side +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Drive on left +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Drive on right + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Heightmap rotation: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Counter-clockwise @@ -1537,7 +1529,7 @@ STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Green to blue STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Gray to red STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :Grayscale -STR_CONFIG_SETTING_SCROLLMODE :Viewport scroll behaviour: {STRING} +STR_CONFIG_SETTING_SCROLLMODE :Viewport scroll behavior: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Behavior when scrolling the map ###length 4 STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Move viewport with RMB, mouse position locked @@ -1936,13 +1928,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Take {STRING}{N STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Time taken for each recalculation of a link graph component. When a recalculation is started, a thread is spawned which is allowed to run for this number of days. The shorter you set this the more likely it is that the thread is not finished when it's supposed to. Then the game stops until it is ("lag"). The longer you set it the longer it takes for the distribution to be updated when routes change. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distribution mode for passengers: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symmetric" means that roughly the same number of passengers will go from a station A to a station B as from B to A. "asymmetric" means that arbitrary numbers of passengers can go in either direction. "manual" means that no automatic distribution will take place for passengers. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetric" means that roughly the same number of passengers will go from a station A to a station B as from B to A. "Asymmetric" means that arbitrary numbers of passengers can go in either direction. "Manual" means that no automatic distribution will take place for passengers. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Distribution mode for mail: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"symmetric" means that roughly the same amount of mail will be sent from a station A to a station B as from B to A. "asymmetric" means that arbitrary amounts of mail can be sent in either direction. "manual" means that no automatic distribution will take place for mail. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Symmetric" means that roughly the same amount of mail will be sent from a station A to a station B as from B to A. "Asymmetric" means that arbitrary amounts of mail can be sent in either direction. "Manual" means that no automatic distribution will take place for mail. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Distribution mode for the ARMORED cargo class: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :The ARMORED cargo class contains valuables in the temperate, diamonds in the subtropical, or gold in the subarctic climate. NewGRFs may change that. "symmetric" means that roughly the same amount of that cargo will be sent from a station A to a station B as from B to A. "asymmetric" means that arbitrary amounts of that cargo can be sent in either direction. "manual" means that no automatic distribution will take place for that cargo. It is recommended to set this to asymmetric or manual when playing subarctic, as banks won't send any gold back to gold mines. For temperate and subtropical you can also choose symmetric as banks will send valuables back to the origin bank of some load of valuables. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :The ARMORED cargo class contains valuables in the temperate, diamonds in the subtropical, or gold in the subarctic climate. NewGRFs may change that. "Symmetric" means that roughly the same amount of that cargo will be sent from a station A to a station B as from B to A. "Asymmetric" means that arbitrary amounts of that cargo can be sent in either direction. "Manual" means that no automatic distribution will take place for that cargo. It is recommended to set this to asymmetric or manual when playing subarctic or subtropic, as banks only receive cargo in these climates. For temperate you can also choose symmetric as banks will send valuables back to the origin bank. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Distribution mode for other cargo classes: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asymmetric" means that arbitrary amounts of cargo can be sent in either direction. "manual" means that no automatic distribution will take place for those cargos. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asymmetric" means that arbitrary amounts of cargo can be sent in either direction. "Manual" means that no automatic distribution will take place for those cargoes. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asymmetric @@ -2037,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatic rever STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Allow trains to reverse on a signal, if they waited there a long time ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recommended) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Change setting value @@ -2080,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Highscor STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Settings STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Settings STR_INTRO_ONLINE_CONTENT :{BLACK}Check Online Content -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI/Game Script Settings +STR_INTRO_AI_SETTINGS :{BLACK}AI Settings +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Game Script Settings STR_INTRO_QUIT :{BLACK}Quit STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Start a new game. Ctrl+Click skips map configuration @@ -2100,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Display STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Display settings STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Display NewGRF settings STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Check for new and updated content to download -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Display AI/Game script settings +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Display AI settings +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Display Game script settings STR_INTRO_TOOLTIP_QUIT :{BLACK}Quit 'OpenTTD' STR_INTRO_BASESET :{BLACK}The currently selected base graphics set is missing {NUM} sprite{P "" s}. Please check for updates for the baseset. @@ -2132,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Change STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Change current year STR_CHEAT_SETUP_PROD :{LTBLUE}Enable modifying production values: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Temperate landscape -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arctic landscape -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropical landscape -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Toyland landscape - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Color Scheme @@ -2370,7 +2358,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(New company) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Create a new company and join it STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}This is you STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}This is the host of the game -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} compan{P y ies} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} - {NUM}/{NUM} compan{P y ies} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}The number of currently connected clients, number of companies and maximum number of companies allowed by the server administrator # Matches ConnectionType ###length 5 @@ -2497,13 +2486,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :waiting for lin STR_NETWORK_MESSAGE_CLIENT_LEAVING :leaving STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} has joined the game -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} has joined the game (Client #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} has joined company #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} has joined the game (Client #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} has joined company #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} has joined spectators -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} has started a new company (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} has left the game ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} has started a new company (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} has left the game ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} has changed their name to {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} gave {2:CURRENCY_LONG} to {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} gave {2:CURRENCY_LONG} to {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The server closed the session STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait... STR_NETWORK_MESSAGE_KICKED :*** {STRING} was kicked. Reason: ({STRING}) @@ -2617,6 +2606,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}saturated STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}overloaded +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} to be transported per month from {STATION} to {STATION} ({COMMA}% of capacity){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} to be transported back ({COMMA}% of capacity) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Average travel time: {NUM}{NBSP}day{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Coverage area highlight STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Off @@ -2625,6 +2619,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Don't hi STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Highlight coverage area of proposed site STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Accepts: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Supplies: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Maintenance cost: {GOLD}{CURRENCY_SHORT}/yr # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Join station @@ -2707,8 +2702,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Increase STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Select Rail Bridge STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Select Road Bridge STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Bridge selection - click on your preferred bridge to build it -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Suspension, Steel STR_BRIDGE_NAME_GIRDER_STEEL :Girder, Steel STR_BRIDGE_NAME_CANTILEVER_STEEL :Cantilever, Steel @@ -2812,11 +2809,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Landscap STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Lower a corner of land. Dragging lowers the first selected corner and levels the selected area to the new corner height. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Raise a corner of land. Dragging raises the first selected corner and levels the selected area to the new corner height. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Level an area of land to the height of the first selected corner. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Shift toggles building/showing cost estimate +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Purchase land for future use. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Object Selection -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Shift toggles building/showing cost estimate +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Select object to build. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Select class of the object to build STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Preview of the object STR_OBJECT_BUILD_SIZE :{BLACK}Size: {GOLD}{NUM} x {NUM} tiles @@ -2828,7 +2825,7 @@ STR_OBJECT_CLASS_TRNS :Transmitters STR_PLANT_TREE_CAPTION :{WHITE}Trees STR_PLANT_TREE_TOOLTIP :{BLACK}Select tree type to plant. If the tile already has a tree, this will add more trees of mixed types independent of the selected type STR_TREES_RANDOM_TYPE :{BLACK}Trees of random type -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Shift toggles building/showing cost estimate +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Place trees of random type. Ctrl selects the area diagonally. Shift toggles building/showing cost estimate STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Random Trees STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plant trees randomly throughout the landscape STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2860,6 +2857,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Random T STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Found town in random location STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Many random towns STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cover the map with randomly placed towns +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Expand all towns +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Make all towns grow slightly STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Town name: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Enter town name @@ -3124,7 +3123,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Game Det STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No information available STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter string: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Overwrite File STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Are you sure you want to overwrite the existing file? STR_SAVELOAD_DIRECTORY :{STRING} (Directory) @@ -3138,6 +3137,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Map size STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Select the size of the map in tiles. The number of available tiles will be slightly smaller STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}No. of towns: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Town names: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Select style of town names STR_MAPGEN_DATE :{BLACK}Date: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}No. of industries: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Highest peak: @@ -3151,13 +3152,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Desert c STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Increase desert coverage by ten percent STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Decrease desert coverage by ten percent STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Land generator: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terrain type: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Sea level: +STR_MAPGEN_SEA_LEVEL :{BLACK}Sea level: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Rivers: STR_MAPGEN_SMOOTHNESS :{BLACK}Smoothness: STR_MAPGEN_VARIETY :{BLACK}Variety distribution: STR_MAPGEN_GENERATE :{WHITE}Generate +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF Settings +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Display NewGRF settings +STR_MAPGEN_AI_SETTINGS :{BLACK}AI Settings +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Display AI settings +STR_MAPGEN_GS_SETTINGS :{BLACK}Game Script Settings +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Display game script settings + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :English (Original) +STR_MAPGEN_TOWN_NAME_FRENCH :French +STR_MAPGEN_TOWN_NAME_GERMAN :German +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :English (Additional) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latin-American +STR_MAPGEN_TOWN_NAME_SILLY :Silly +STR_MAPGEN_TOWN_NAME_SWEDISH :Swedish +STR_MAPGEN_TOWN_NAME_DUTCH :Dutch +STR_MAPGEN_TOWN_NAME_FINNISH :Finnish +STR_MAPGEN_TOWN_NAME_POLISH :Polish +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovak +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norwegian +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungarian +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austrian +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romanian +STR_MAPGEN_TOWN_NAME_CZECH :Czech +STR_MAPGEN_TOWN_NAME_SWISS :Swiss +STR_MAPGEN_TOWN_NAME_DANISH :Danish +STR_MAPGEN_TOWN_NAME_TURKISH :Turkish +STR_MAPGEN_TOWN_NAME_ITALIAN :Italian +STR_MAPGEN_TOWN_NAME_CATALAN :Catalan # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Map edges: @@ -3216,7 +3245,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Detailed STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Active NewGRF files STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Inactive NewGRF files STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Select preset: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter string: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Load the selected preset STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Save preset STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Save the current list as a preset @@ -3303,6 +3332,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Previous STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Proceed to the previous normal sprite, skipping any pseudo/recolor/font sprites and wrapping around from the first sprite to the last STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representation of the currently selected sprite. The alignment is ignored when drawing this sprite STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Move the sprite around, changing the X and Y offsets. Ctrl+Click to move the sprite eight units at a time + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Offset centered +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centered + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Crosshair + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Reset relative STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Reset the current relative offsets STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X offset: {NUM}, Y offset: {NUM} (Absolute) @@ -3317,18 +3353,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Warning: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Error: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}A fatal NewGRF error has occurred:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}A NewGRF error has occurred:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}The NewGRF "{STRING}" has returned a fatal error:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}The NewGRF "{STRING}" has returned an error:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} will not work with the TTDPatch version reported by OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} is for the {STRING} version of TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} is designed to be used with {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Invalid parameter for {1:STRING}: parameter {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} must be loaded before {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} must be loaded after {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requires OpenTTD version {STRING} or better +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} is for the {2:STRING} version of TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} is designed to be used with {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Invalid parameter for {1:STRING}: parameter {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} must be loaded before {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} must be loaded after {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requires OpenTTD version {2:STRING} or better STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :the GRF file it was designed to translate STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Too many NewGRFs are loaded -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Loading {1:STRING} as static NewGRF with {STRING} could cause desyncs +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Loading {1:STRING} as static NewGRF with {2:STRING} could cause desyncs STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Unexpected sprite (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Unknown Action 0 property {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Attempt to use invalid ID (sprite {3:NUM}) @@ -3460,14 +3496,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Buy exclusive t STR_LOCAL_AUTHORITY_ACTION_BRIBE :Bribe the local authority ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Initiate a small local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a small radius around the town center.{}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Initiate a small local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a small radius around the town center.{}{POP_COLOUR}Cost: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Initiate a medium local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a medium radius around the town center.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Initiate a large local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a large radius around the town center.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Fund the reconstruction of the urban road network.{}Causes considerable disruption to road traffic for up to 6 months.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Build a statue in honor of your company.{}Provides a permanent boost to station rating in this town.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Fund the construction of new buildings in the town.{}Provides a temporary boost to town growth in this town.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Buy 1 year's exclusive transport rights in town.{}Town authority will not allow passengers and cargo to use your competitors' stations.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Initiate a large local advertising campaign, to attract more passengers and cargo to your transport services.{}Provides a temporary boost to station rating in a large radius around the town center.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Fund the reconstruction of the urban road network.{}Causes considerable disruption to road traffic for up to 6 months.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Build a statue in honor of your company.{}Provides a permanent boost to station rating in this town.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Fund the construction of new buildings in the town.{}Provides a temporary boost to town growth in this town.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Buy 1 year's exclusive transport rights in town.{}Town authority will not allow passengers and cargo to use your competitors' stations.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Bribe the local authority to increase your rating, at the risk of a severe penalty if caught.{}{POP_COLOUR}Cost: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Goals @@ -3640,15 +3676,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Ships STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Loan Interest STR_FINANCES_SECTION_OTHER :{GOLD}Other +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Net Profit +STR_FINANCES_PROFIT :{WHITE}Profit STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Bank Balance STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Own Funds STR_FINANCES_LOAN_TITLE :{WHITE}Loan STR_FINANCES_INTEREST_RATE :{WHITE}Loan Interest: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maximum Loan: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Borrow {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Increase size of loan. Ctrl+Click borrows as much as possible STR_FINANCES_REPAY_BUTTON :{BLACK}Repay {CURRENCY_LONG} @@ -3749,7 +3788,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produces STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Requires: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} waiting{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Change production (multiple of 8, up to 2040) @@ -3779,6 +3818,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Send ins STR_VEHICLE_LIST_REPLACE_VEHICLES :Replace vehicles STR_VEHICLE_LIST_SEND_FOR_SERVICING :Send for Maintenance STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Profit this year: {CURRENCY_LONG} (last year: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Send to Depot STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Send to Depot @@ -3870,6 +3911,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Tra STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Range: {GOLD}{COMMA} tiles STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Aircraft type: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :All cargo types +STR_CARGO_TYPE_FILTER_FREIGHT :Freight +STR_CARGO_TYPE_FILTER_NONE :None + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Train vehicle selection list. Click on vehicle for information. Ctrl+Click to toggle hiding of the vehicle type STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Road vehicle selection list. Click on vehicle for information. Ctrl+Click to toggle hiding of the vehicle type @@ -4038,7 +4084,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :aircraft STR_ENGINE_PREVIEW_SHIP :ship STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cost: {CURRENCY_LONG} Weight: {WEIGHT_SHORT}{}Speed: {VELOCITY} Power: {POWER}{}Running Cost: {CURRENCY_LONG}/yr{}Capacity: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {CURRENCY_LONG} Weight: {WEIGHT_SHORT}{}Speed: {VELOCITY} Power: {POWER} Max. T.E.: {6:FORCE}{}Running Cost: {4:CURRENCY_LONG}/yr{}Capacity: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {0:CURRENCY_LONG} Weight: {1:WEIGHT_SHORT}{}Speed: {2:VELOCITY} Power: {3:POWER} Max. T.E.: {6:FORCE}{}Running Cost: {4:CURRENCY_LONG}/yr{}Capacity: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING}{}Capacity: {CARGO_LONG}, {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Aircraft type: {STRING}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr @@ -4197,12 +4243,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Weight: STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Weight: {LTBLUE}{WEIGHT_SHORT} {BLACK}Power: {LTBLUE}{POWER}{BLACK} Max. speed: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit this year: {LTBLUE}{CURRENCY_LONG} (last year: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Profit this year: {LTBLUE}{CURRENCY_LONG} (last year: {CURRENCY_LONG}) {BLACK}Min. performance: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Reliability: {LTBLUE}{COMMA}% {BLACK}Breakdowns since last maintenance: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Built: {LTBLUE}{NUM}{BLACK} Value: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacity: {LTBLUE}None{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacity: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacity: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacity: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transfer Credits: {LTBLUE}{CURRENCY_LONG} @@ -4316,7 +4363,7 @@ STR_ORDER_DROP_REFIT_AUTO_ANY :Available cargo STR_ORDER_SERVICE :{BLACK}Maintenance STR_ORDER_DROP_GO_ALWAYS_DEPOT :Always go -STR_ORDER_DROP_SERVICE_DEPOT :Maintain if needed +STR_ORDER_DROP_SERVICE_DEPOT :Repair if needed STR_ORDER_DROP_HALT_DEPOT :Stop STR_ORDER_SERVICE_TOOLTIP :{BLACK}Skip this order unless maintenance is needed @@ -4471,22 +4518,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Start Da STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Select a date as starting point of this timetable. Ctrl+Click distributes all vehicles sharing this order evenly from the given date based on their relative order, if the order is completely timetabled STR_TIMETABLE_CHANGE_TIME :{BLACK}Change Time -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Change the amount of time that the highlighted order should take +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Change the amount of time that the highlighted order should take. Ctrl+Click sets the time for all orders STR_TIMETABLE_CLEAR_TIME :{BLACK}Clear Time -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Clear the amount of time for the highlighted order +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Clear the amount of time for the highlighted order. Ctrl+Click clears the time for all orders STR_TIMETABLE_CHANGE_SPEED :{BLACK}Change Speed Limit -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Change the maximum travel speed of the highlighted order +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Change the maximum travel speed of the highlighted order. Ctrl+Click sets the speed for all orders STR_TIMETABLE_CLEAR_SPEED :{BLACK}Clear Speed Limit -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Clear the maximum travel speed of the highlighted order +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Clear the maximum travel speed of the highlighted order. Ctrl+Click clears the speed for all orders STR_TIMETABLE_RESET_LATENESS :{BLACK}Reset Late Counter -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reset the lateness counter, so the vehicle will be on time +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reset the lateness counter, so the vehicle will be on time. Ctrl+Click will reset the entire group so the latest vehicle will be on time and all others will be early STR_TIMETABLE_AUTOFILL :{BLACK}Autofill -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fill the timetable automatically with the values from the next journey (Ctrl+Click to try to keep waiting times) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fill the timetable automatically with the values from the next journey. Ctrl+Click to try to keep waiting times STR_TIMETABLE_EXPECTED :{BLACK}Expected STR_TIMETABLE_SCHEDULED :{BLACK}Scheduled @@ -4530,12 +4577,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}One of t STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/Game Script Debug window is only available for the server # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI/Game Script Configuration +STR_AI_CONFIG_CAPTION_AI :{WHITE}AI Configuration +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Game Script Configuration STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}The Game Script that will be loaded in the next game STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}The AIs that will be loaded in the next game STR_AI_CONFIG_HUMAN_PLAYER :Human player STR_AI_CONFIG_RANDOM_AI :Random AI STR_AI_CONFIG_NONE :(none) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maximum no. competitors: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Move Up STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Move selected AI up in the list @@ -4543,12 +4592,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Move Dow STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Move selected AI down in the list STR_AI_CONFIG_GAMESCRIPT :{SILVER}Game Script +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parameters STR_AI_CONFIG_AI :{SILVER}AIs -STR_AI_CONFIG_CHANGE :{BLACK}Select {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Game Script +STR_AI_CONFIG_CHANGE_AI :{BLACK}Select AI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Select Game Script STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Load another script STR_AI_CONFIG_CONFIGURE :{BLACK}Configure STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configure the parameters of the Script @@ -4576,7 +4624,7 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Whole ma STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Heightmap screenshot STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minimap screenshot -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters STR_AI_SETTINGS_CAPTION_AI :AI STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Game Script @@ -4743,6 +4791,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... too STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Can't generate industries... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Can't build {STRING} here... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Can't construct this industry type here... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Can't prospect industry... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... too close to another industry STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... must found town first STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... only one allowed per town @@ -4757,6 +4806,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... fore STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... can only be built above the snow-line STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... can only be built below the snow-line +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}The funding failed to prospect due to bad luck; try again +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}There were no suitable places to prospect for this industry STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}There were no suitable places for '{STRING}' industries STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Change the map generation parameters to get a better map @@ -4924,6 +4975,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Object i STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... company headquarters in the way STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Can't purchase this land area... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... you already own it! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... object construction limit reached # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Can't create group... @@ -4996,6 +5048,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Can't ch STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vehicle is destroyed +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... not all vehicles are identical + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}No vehicles will be available at all STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Change your NewGRF configuration STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}No vehicles are available yet @@ -5022,6 +5076,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Can't sk STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... vehicle can't go to all stations STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... vehicle can't go to that station STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... a vehicle sharing this order can't go to that station +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... not all vehicles have the same orders +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... not all vehicles are sharing orders STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Can't share order list... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Can't stop sharing order list... @@ -5029,6 +5085,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Can't co STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... too far from previous destination STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... aircraft has not enough range +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}There is no railroad station +STR_ERROR_NO_BUS_STATION :{WHITE}There is no bus station +STR_ERROR_NO_TRUCK_STATION :{WHITE}There is no truck station +STR_ERROR_NO_DOCK :{WHITE}There is no dock +STR_ERROR_NO_AIRPORT :{WHITE}There is no airport/heliport +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}There are no stops with a compatible road type +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}There are no stops with a compatible tram type +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}There are no stops which are suitable for articulated road vehicles.{}Articulated road vehicles require a drive-through stop, not a bay stop +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}This plane cannot land at this heliport +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}This helicopter cannot land at this airport +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}There is no railroad waypoint +STR_ERROR_NO_BUOY :{WHITE}There is no buoy + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Can't timetable vehicle... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Vehicles can only wait at stations diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index ad8ac313d138a..c9cd59fe9004d 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -198,6 +198,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}ĉ STR_UNITS_POWER_METRIC :{COMMA}{NBSP}ĉp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -368,10 +369,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Forlasi # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Ludaj opcioj STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Agordoj -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Ludo skripto agordoj STR_SETTINGS_MENU_NEWGRF_SETTINGS :Agordoj de NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Ebloj por travidebleco STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Urbonomoj montriĝas @@ -908,36 +908,6 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :Alia... STR_GAME_OPTIONS_CURRENCY_GEL :Kartvela Lario (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Irana Rialo (IRR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Veturu maldekstre -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Veturu dekstre - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Urbonomoj -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Elektu stilon de urbonomoj - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Angle (Originale) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :France -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Germane -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Angle (Aldone) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latin-Amerike -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Angle (Stulte) -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Svede -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Nederlande -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finne -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Pole -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovake -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norvege -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungare -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Aŭstrie -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumane -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Ĉeĥe -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Svise -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dane -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turke -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Itale -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalune - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Aŭtomata konservado STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Elektu intervalon inter aŭtomataj konservadoj de la ludo @@ -962,11 +932,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :alia -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Interfacgrandeco - -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normala -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Duobla grandeco -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Kvaroble grandeco @@ -1011,8 +976,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Antaŭv STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 pundo (£) en via valuto STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Ŝanĝi parametron por alia monunuo -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimumo da konkurantoj: {ORANGE}{COMMA} - STR_NONE :Neniom STR_FUNDING_ONLY :Funduso sola STR_MINIMAL :Malgrandeto @@ -1062,6 +1025,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Modera landaspekto +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Arktikeca landaspekto +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Tropikeca landaspekto +STR_CLIMATE_TOYLAND_LANDSCAPE :Ludolandaspekto + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Tre Ebene STR_TERRAIN_TYPE_FLAT :Ebene @@ -1121,6 +1090,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_CENTER :Centre STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Dekstre STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maksimuma komenca prunto: {STRING} +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Rentumtarifoj: {STRING} @@ -1286,6 +1256,10 @@ STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :Originale STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Plibonigita +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Veturu maldekstre +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Veturu dekstre + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Altecmapa turniĝo: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Maldekstrume @@ -1577,7 +1551,7 @@ STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS :Padtrovilo por STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Aŭtomata dorsflankante ĉe signaloj: {STRING} ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Rekomendite) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Rekomendite) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Ŝanĝu agord-valoron @@ -1645,12 +1619,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Ŝanĝu STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Ŝanĝu nunan jaron STR_CHEAT_SETUP_PROD :{LTBLUE}Ebligu ŝanĝi produktvalorojn: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Modera landaspekto -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Arktikeca landaspekto -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Tropikeca landaspekto -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Ludolandaspekto - # Livery window STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Montru ĝeneralajn kolorskemojn @@ -2021,6 +1989,8 @@ STR_TRANSPARENT_LOADING_TOOLTIP :{BLACK}Baskulig # Linkgraph legend window and linkgraph legend in smallmap +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Ŝarĝregiona marko STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Malaktiva @@ -2093,8 +2063,6 @@ STR_BUILD_SIGNAL_CAPTION :{WHITE}Elekto d STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Elektu Relan Ponton STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Elektu Vojan Ponton STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Pontelekto - klaku vian preferatan ponton por konstrui ĝin -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Ŝtala pendanta STR_BRIDGE_NAME_GIRDER_STEEL :Ŝtala ebena STR_BRIDGE_NAME_CANTILEVER_STEEL :Ŝtala luksa @@ -2418,16 +2386,40 @@ STR_MAPGEN_MAPSIZE :{BLACK}Mapgrand STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Selektu la grandeco de la mapo en azuleĥoj. La nombro de disponeblaj azuleĥoj estos iom pli malgranda STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Kiom da urboj: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Urbonomoj +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Elektu stilon de urbonomoj STR_MAPGEN_DATE :{BLACK}Dato: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Kiom da industrioj: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Landgenerilo: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terentipo: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Marnivelo: +STR_MAPGEN_SEA_LEVEL :{BLACK}Marnivelo: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Riveroj: STR_MAPGEN_SMOOTHNESS :{BLACK}Reguleco: STR_MAPGEN_VARIETY :{BLACK}Diverseca distribuo: STR_MAPGEN_GENERATE :{WHITE}Generu +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Angle (Originale) +STR_MAPGEN_TOWN_NAME_FRENCH :France +STR_MAPGEN_TOWN_NAME_GERMAN :Germane +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Angle (Aldone) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latin-Amerike +STR_MAPGEN_TOWN_NAME_SILLY :Angle (Stulte) +STR_MAPGEN_TOWN_NAME_SWEDISH :Svede +STR_MAPGEN_TOWN_NAME_DUTCH :Nederlande +STR_MAPGEN_TOWN_NAME_FINNISH :Finne +STR_MAPGEN_TOWN_NAME_POLISH :Pole +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovake +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norvege +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungare +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Aŭstrie +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumane +STR_MAPGEN_TOWN_NAME_CZECH :Ĉeĥe +STR_MAPGEN_TOWN_NAME_SWISS :Svise +STR_MAPGEN_TOWN_NAME_DANISH :Dane +STR_MAPGEN_TOWN_NAME_TURKISH :Turke +STR_MAPGEN_TOWN_NAME_ITALIAN :Itale +STR_MAPGEN_TOWN_NAME_CATALAN :Katalune + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Maprandoj: STR_MAPGEN_NORTHWEST :{BLACK}Nordokcidenta @@ -2545,6 +2537,10 @@ STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}Sekvanta STR_SPRITE_ALIGNER_GOTO_BUTTON :{BLACK}Iru al bildeto STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Antaŭa bildeto STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Movadi la bildeton, ŝanĝante la X kaj Y distancojn. Stir-klako por movi la bildeton je 8 unuoj samtempe + +###length 2 + + STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Elektu bildeto STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Elektu bildeton ie el la ekrano @@ -2555,7 +2551,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Averto: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Eraro: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatalo: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Neriparebla NewGRF-eraro okazis:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} ne funkcios kun la versio de TTDPatch menciata de OpenTTD. STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} estas por la {STRING} versio de TTD. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} estas intencita por uzo kun {STRING} @@ -2938,6 +2933,8 @@ STR_PURCHASE_INFO_ALL_TYPES :Ĉiaj ŝarĝoj STR_PURCHASE_INFO_ALL_BUT :Ĉio krom {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Maksimuma Tiro: {GOLD}{FORCE} +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Trajnveturila elektolisto - alklaku veturilon por informoj STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Stratveturilelektan liston - alklaku veturilon por informoj @@ -3517,10 +3514,10 @@ STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}Vidu for # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI/Ludo Skripto Agordo STR_AI_CONFIG_HUMAN_PLAYER :Homa ludanto STR_AI_CONFIG_RANDOM_AI :Hazarda AI STR_AI_CONFIG_NONE :(neniu) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maksimumo da konkurantoj: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Movi supren STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Movi elektitan AI-on supren en la listo @@ -3529,7 +3526,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Movi ele STR_AI_CONFIG_AI :{SILVER}AIj -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CONFIGURE :{BLACK}Agordi STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Agordi parametroj de la skripto @@ -3546,8 +3542,7 @@ STR_AI_LIST_CANCEL :{BLACK}Nuligi STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ne ŝanĝu AI-on -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametroj +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI STR_AI_SETTINGS_CLOSE :{BLACK}Fermi STR_AI_SETTINGS_RESET :{BLACK}Reŝargo @@ -3946,6 +3941,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Ne povas STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... veturilo estas detrua + # Specific vehicle errors STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Ne povas igi trajnon transiri signalon je danĝero... STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN :{WHITE}Ne povas inversigi direkton de trajno... @@ -3974,6 +3970,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Ne povas STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... tro for de la antaŭa destino STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... aviadilon ne havas sufiĉe da atingopovo +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Ne povas fari katalogon por veturilo... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Veturiloj povas atendi nur ĉe stacioj. diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index f5cf7bcee7c35..0ea20389f3052 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -257,6 +257,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}hj STR_UNITS_POWER_METRIC :{COMMA}hj STR_UNITS_POWER_SI :{COMMA}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hj/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hj/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hj/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hj/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hj/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hj/t +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -283,8 +293,8 @@ STR_UNITS_HEIGHT_SI :{COMMA} m # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Märksõna: -STR_LIST_FILTER_OSKTITLE :{BLACK}Sisesta märksõna -STR_LIST_FILTER_TOOLTIP :{BLACK}Sisesta märksõna mida loendist otsida +STR_LIST_FILTER_OSKTITLE :{BLACK}Sisesta üks või enam märksõna mille järgi nimekirja filtreerida +STR_LIST_FILTER_TOOLTIP :{BLACK}Sisesta üks või enam märksõna mida loendist otsida STR_TOOLTIP_GROUP_ORDER :{BLACK}Vali jaotamise järjestus STR_TOOLTIP_SORT_ORDER :{BLACK}Vali järjestus (kahanev/kasvav) @@ -383,6 +393,8 @@ STR_GROUP_BY_NONE :Puudub STR_GROUP_BY_SHARED_ORDERS :Jagatud korraldused # Order button in shared orders vehicle list +STR_GOTO_ORDER_VIEW :{BLACK}Korraldused +STR_GOTO_ORDER_VIEW_TOOLTIP :{BLACK}Ava korralduste vaade # Tooltips for the main toolbar ###length 31 @@ -431,9 +443,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Asustust STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Tööstuste tekitamine STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Maanteede ehitamine STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Trammiteede ehitamine -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Istuta puid. Shift valib ehitamise/hinna kuvamise režiimi +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Istuta puid. Ctrl valib piirkonna diagonaalselt. Shift valib ehitamise/hinna kuvamise režiimi vahel STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Paigalda silt -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Paigalda objekt. Shift valib ehitamise/hinna kuvamise režiimi +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Paigalda objekt. Ctrl valib ala diagonaaliti. Shift valib ehitamise/hinna kuvamise režiimi vahel # Scenario editor file menu ###length 7 @@ -446,10 +458,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Välju # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Mängu seadistus STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Seaded -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/GameScripti seaded +STR_SETTINGS_MENU_AI_SETTINGS :TI seaded +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :GameScript'i seaded STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF-i seadistus STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Läbipaistvuse seadistus STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Näidatavad asustuste nimed @@ -849,6 +862,7 @@ STR_STATUSBAR_PAUSED_LINK_GRAPH :{ORANGE}* * S STR_STATUSBAR_AUTOSAVE :{RED}VÄLPSALVESTUS STR_STATUSBAR_SAVING_GAME :{RED}* * MÄNGU SALVESTAMINE * * +STR_STATUSBAR_SPECTATOR :{WHITE}(vaatleja) # News message history STR_MESSAGE_HISTORY :{WHITE}Sõnumite ajalugu @@ -952,7 +966,12 @@ STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO :{WHITE}Jaam {ST STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED :{BIG_FONT}{BLACK}Toetuse pakkumine lõppes:{}{}{STRING.g} kohast {STRING} kohta {STRING} veoste eest ei maksta enam toetusi STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE :{BIG_FONT}{BLACK}Toetuse maksmise aeg sai läbi:{}{}{STRING}kohast {STRING} kohta {STRING} eest ei maksta enam edaspidi toetust +STR_NEWS_SERVICE_SUBSIDY_OFFERED :{BIG_FONT}{BLACK}Veoteenusele pakutakse toetust:{}{}{STRING.g}veo eest asustusest {STRING} asustusse {STRING}. Esimesele teenusepakkujale makstakse {NUM} aasta{P "" "t" } toetusi! ###length 4 +STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF :{BIG_FONT}{BLACK}Teenusetoetust makstakse ettevõttele {STRING}!{}{}{STRING} kohast {STRING} kohta {STRING} teenuse eest makstakse järgmisel {NUM} aastal 50% rohkem! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLACK}Teenusetoetust makstakse ettevõttele {STRING}!{}{}{STRING} kohast {STRING} kohta {STRING} teenuse eest makstakse järgmisel {NUM} aastal kahekordselt! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}Teenusetoetust makstakse ettevõttele {STRING}!{}{}{STRING} kohast {STRING} kohta {STRING} teenuse eest makstakse järgmise {NUM} aasta jooksul kolmekordselt! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE :{BIG_FONT}{BLACK}Teenusetoetust makstakse ettevõttele {STRING}!{}{}{STRING} kohast {STRING} kohta {STRING} teenuse eest makstakse järgmise {NUM} aasta jooksul neljakordselt! STR_NEWS_ROAD_REBUILDING :{BIG_FONT}{BLACK}Liikluskaos asustuses {TOWN}!{}{}Ettevõtte {STRING} poolt rahastatud teede ümberehitus tekitab 6 kuu jooksul maanteedel liiklushäireid! STR_NEWS_EXCLUSIVE_RIGHTS_TITLE :{BIG_FONT}{BLACK}Transpordimonopol! @@ -1014,36 +1033,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :India ruupia (I STR_GAME_OPTIONS_CURRENCY_IDR :Indoneesia ruupia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaisia ringit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Vasakpoolne liiklus -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Parempoolne liiklus - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Asulanimed: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Vali asulanimede stiil - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Inglise (algne) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Prantsusmaa -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Saksamaa -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Inglise (täiendatud) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Ladina-Ameerika -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Tobedad -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Rootsi -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Hollandi -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Soome -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Poola -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovakkia -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norra -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungari -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austria -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumeenia -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tšehhi -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Šveitsi -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Taani -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Türgi -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Itaalia -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalaani - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Salvestusvälp STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Vali salvestamise välp @@ -1074,22 +1063,20 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Seade om STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Märgi, et ekraani v-sync sisse lülitada. Seade kohaldub alles pärast mängu taaskäivitust. Töötab vaid, kui riistvarakiirendus on peal +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Hetke draiver: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Liidese suurus -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Vali kasutatav liideseelementide suurus +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Liidese suurus +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Tuvasta automaatselt suurus +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Märgi see kast, et tuvastada liidese suurus automaatselt -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(automaattuvastus) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Tavaline -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Topeltsuurus -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Neljakordne suurus +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Skaleeri kaldeid +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Skaleeri kaldeid liidese suuruse järgi -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Kirja suurus -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Vali kasutatav liideseelementide suurus - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(automaattuvastus) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Tavaline -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Topeltsuurus -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Neljakordne suurus +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Graafika @@ -1141,8 +1128,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Eelvaad STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 naela (£) sinu valuutas STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Muuda personaalse valuuta parameetreid -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Vastaseid kuni: {ORANGE}{COMMA} - STR_NONE :Pole STR_FUNDING_ONLY :Ainult rahastatud STR_MINIMAL :Vähene @@ -1192,6 +1177,12 @@ STR_SUBSIDY_X2 :2x STR_SUBSIDY_X3 :3x STR_SUBSIDY_X4 :4x +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Parasvöötme maastik +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Lähisarktiline maastik +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Troopiline maastik +STR_CLIMATE_TOYLAND_LANDSCAPE :Mänguasjamaa + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Väga tasane STR_TERRAIN_TYPE_FLAT :Tasane @@ -1202,9 +1193,10 @@ STR_TERRAIN_TYPE_CUSTOM :Määratud kõr STR_TERRAIN_TYPE_CUSTOM_VALUE :Määratud kõrgus ({NUM}) ###length 4 +STR_CITY_APPROVAL_LENIENT :Leebe STR_CITY_APPROVAL_TOLERANT :Salliv STR_CITY_APPROVAL_HOSTILE :Vaenulik -STR_CITY_APPROVAL_PERMISSIVE :Soodustav +STR_CITY_APPROVAL_PERMISSIVE :Lubav (ei oma mõju firma tegevustele) STR_WARNING_NO_SUITABLE_AI :{WHITE}Sobiv AI puudub...{}Mitmesuguseid AI-sid saab alla laadida 'aineste allalaadimise' kaudu @@ -1270,6 +1262,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Paremal STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Stardilaenu ülempiirang: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Suurim summa, mida ettevõte saab laenata (arvestamata inflatsiooni) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Laenudeta {RED}GameScript peab andma esmase rahastuse STR_CONFIG_SETTING_INTEREST_RATE :Intressimäär: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Laenu intressimäär; ühtlasi juhib inflatsiooni, kui inflatsioon on aktiveeritud @@ -1286,8 +1281,12 @@ STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT :Muudab hooldama STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER :Toetuse kordaja: {STRING} STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :Määra ära kui palju makstakse toetatud liinide eest +STR_CONFIG_SETTING_SUBSIDY_DURATION :Toetuse kestus: {STRING} +STR_CONFIG_SETTING_SUBSIDY_DURATION_HELPTEXT :Sea aastate arv, kui kaua toetust makstakse +STR_CONFIG_SETTING_SUBSIDY_DURATION_VALUE :{NUM} aasta{P "" d} ###setting-zero-is-special +STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED :Toetusteta STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Ehituse hinnad: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Määrab ehitus- ja ostukulude hinnataseme @@ -1301,8 +1300,8 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Kui on aktiveer STR_CONFIG_SETTING_DISASTERS :Katastroofid: {STRING} STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Lülita sisse/välja katastroofid, mis aeg-ajalt hävitavad sõidukeid ja taristut -STR_CONFIG_SETTING_CITY_APPROVAL :Astuse omavalitsuse suhtumine pinnase restruktureerimisse: {STRING} -STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Vali kui suurt mõju tekitavad müra ning keskkonna muudatused ettevõtte mainele ja edasistele ehitustoimingutele antud piirkonnas +STR_CONFIG_SETTING_CITY_APPROVAL :Kohaliku omavalitsuse suhtumine: {STRING} +STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Vali kui suurt mõju tekitavad müra ning keskkonna muudatused ettevõtte mainele ja edasistele ehitustoimingutele asulas STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :Kaardi kõrguspiir: {STRING} STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_HELPTEXT :Määra ülempiir kaardil oleva maastiku kõrgusele. "(Auto)" leiab sobiva väärtuse pärast, kui maastik on tekitatud @@ -1372,7 +1371,7 @@ STR_CONFIG_SETTING_INDUSTRY_PLATFORM :Tasane ala ümb STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :Summa kui palju tasast maad on ümber tehase. See tagab et ruumi jääb saadavale ehitiste jaoks STR_CONFIG_SETTING_MULTIPINDTOWN :Mitu samalaadset tööstust ühe asula piires: {STRING} -STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :Tavaliselt asula ei taha rohkem kui ühte tööstustharu igast liigist. Selle seadega lubatakse rohkem kui üks samalaadne tööstus ühe asula piires +STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :Tavaliselt asula ei taha rohkem kui ühte tööstusharu igast liigist. Selle seadega lubatakse rohkem kui üks samalaadne tööstus ühe asula piires STR_CONFIG_SETTING_SIGNALSIDE :Signaale näidatakse: {STRING} STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :Vali kummale poole rada signaalid paigutatakse @@ -1492,6 +1491,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Graafikutes kas STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Näita sõidukiehitusaknas NewGRF-i nime: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Lisa sõidukiehitusaknasse uus rida, mis näitab millisest NewGRF-ist sõiduk on pärit. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Näita kaupasid, mida sõidukid saavad vedada nimekirja aknas {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Kui aktiveeritud, siis kuvatakse sõidukite nimekirjas sõiduki kohal selle veos STR_CONFIG_SETTING_LANDSCAPE :Maastik: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Maastikud määravad põhilised mängustsenaariumid erinevate veoste ja nõuetega asulate kasvamiseks. NewGRF ja GameScript abil saab siiski täpsemalt kontrollida @@ -1546,6 +1547,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Täiustatud STR_CONFIG_SETTING_ROAD_SIDE :Sõidukid: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Vali liikluse suund +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Vasakpoolne liiklus +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Parempoolne liiklus + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Kõrguskaardi pööre: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Vastupäeva @@ -1572,7 +1577,13 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Roheline STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Tumeroheline STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violetne +STR_CONFIG_SETTING_LINKGRAPH_COLOURS :Kaubavoo ülekatte värvid: {STRING} +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_HELPTEXT :Vali värvilahendus, mida kasutatakse kaubavoo ülekattel ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :Rohelisest punaseni (esialgne) +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Rohelisest siniseni +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Hallist punaseni +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :Halltoonides STR_CONFIG_SETTING_SCROLLMODE :Vaate liigutamine: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Kaardil liikumise viis @@ -1616,7 +1627,12 @@ STR_CONFIG_SETTING_OSK_ACTIVATION_DOUBLE_CLICK :Topeltklõpsuga STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK_FOCUS :Ühe klõpsuga (kui on fookuses) STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK :Ühe klõpsuga (koheselt) +STR_CONFIG_SETTING_USE_RELAY_SERVICE :Kasuta vahendajateenust : {STRING} +STR_CONFIG_SETTING_USE_RELAY_SERVICE_HELPTEXT :Kui serveriga ühenduse loomine ebaõnnestub, võib kasutada vahendajateenust ühenduse loomiseks. "Mitte kunagi" keelab selle, "küsi" küsib esmalt, "luba" lubab selle küsimata ###length 3 +STR_CONFIG_SETTING_USE_RELAY_SERVICE_NEVER :Mitte kunagi +STR_CONFIG_SETTING_USE_RELAY_SERVICE_ASK :Küsi +STR_CONFIG_SETTING_USE_RELAY_SERVICE_ALLOW :Luba STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU :Paremklõpsu matkimine: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT :Vali meetod mille järgi emuleeritakse hiite paremklõpse @@ -1713,8 +1729,8 @@ STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT :Maastikult, tö STR_CONFIG_SETTING_MAX_TRAINS :Ettevõtte rongide ülempiirang: {STRING} STR_CONFIG_SETTING_MAX_TRAINS_HELPTEXT :Ettevõttele kuuluvate rongide arvu ülempiirang -STR_CONFIG_SETTING_MAX_ROAD_VEHICLES :Ettevõtte mootorsõidukite ülempiirang: {STRING} -STR_CONFIG_SETTING_MAX_ROAD_VEHICLES_HELPTEXT :Ettevõttele kuuluvate mootorsõidukite arvu ülempiirang +STR_CONFIG_SETTING_MAX_ROAD_VEHICLES :Ettevõtte maanteesõidukite ülempiirang: {STRING} +STR_CONFIG_SETTING_MAX_ROAD_VEHICLES_HELPTEXT :Ettevõttele kuuluvate maanteesõidukite arvu ülempiirang STR_CONFIG_SETTING_MAX_AIRCRAFT :Ettevõtte õhusõidukite ülempiirang: {STRING} STR_CONFIG_SETTING_MAX_AIRCRAFT_HELPTEXT :Ettevõttele kuuluvate õhusõidukite arvu ülempiirang @@ -1783,6 +1799,8 @@ STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER_HELPTEXT :Kui vastasettev STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS :Õnnetused / katastroofid: {STRING} STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT :Õnnetusi või katastroofi esinemisel näidatakse seda ajalehes +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER :Õnnetused konkurentide sõidukitega: {STRING} +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER_HELPTEXT :Kuva ajalehe teated konkurentide sõidukitega juhtunud õnnetuste kohta STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION :Ettevõtte teave: {STRING} STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT :Kui uus ettevõte alustab, või ettevõte riskib pankrotiga, näidatakse seda ajalehes @@ -1860,12 +1878,16 @@ STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Semafore ehitat STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Määra aasta alates millest hakatakse kasutama elektriga foore. Ennem seda aastat kasutatakse semafoore (mis täidavad sama eesmärki, aga näevad teist moodi välja) STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Vaheta signaalide liike: {STRING} -STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Muuda saadaval signaaliliike, kui «Ctrl»+klõpsu abil muuta signaali liiki +STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Muuda valitavaid signaaliliike, kui «Ctrl»+klõpsu abil muudetakse ehitatud signaali liiki ###length 2 STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :Ainult täiustatud -STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :Kõik +STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :Kõik nähtavad +STR_CONFIG_SETTING_SIGNAL_GUI_MODE :Näita signaali tüüpe: {STRING} +STR_CONFIG_SETTING_SIGNAL_GUI_MODE_HELPTEXT :Vali milliseid signaale kuvatakse signaalide tööribal ###length 2 +STR_CONFIG_SETTING_SIGNAL_GUI_MODE_PATH :Rajasignaalid ainult +STR_CONFIG_SETTING_SIGNAL_GUI_MODE_ALL_CYCLE_PATH :Kõik signaalid STR_CONFIG_SETTING_TOWN_LAYOUT :Uute asulate teeplaneering: {STRING} STR_CONFIG_SETTING_TOWN_LAYOUT_HELPTEXT :Teedevõrgu paigutus asulates @@ -1962,13 +1984,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Jaotusgraafikud STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Aega ahelgraafiku osa koostamiseks. Koostamise algul käivitatakse protsess, mis võib töötada määratud arv päevi. Väiksema väärtusega on suurem võimalus, et protsess lõppe. Kui protsess ei ole lõppenud, siis mäng seisatakse protsessi lõppemiseni (tekib viivitusi). Suurema arvuga läheb kauem, kuni muudetud teel uuendatakse kaubajaotust. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Reisijate jaotuse viis: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Kui jaamast A läheb jaama B umbes sama hulk reisijaid, kui jaamast B jaama A, siis jaotus on «sümeetriline». Kui mõlemas suunas võib liikuda ükskõik, kui palju resijaid, siis jaotus on «asümeetriline». Kui reisijate liikumist ei jaotata, siis jaotus on «väljas». +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Kui jaamast A läheb jaama B umbes sama hulk reisijaid, kui jaamast B jaama A, siis jaotus on «Sümeetriline». Kui mõlemas suunas võib liikuda ükskõik, kui palju resijaid, siis jaotus on «Asümeetriline». Kui reisijate liikumist ei jaotata, siis jaotus on «Väljas». STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Posti jaotuse viis: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :Kui jaamast A viiakse jaama B umbes sama hulk posti, kui jaamast B jaama A, siis jaotus on «sümeetriline». Kui mõlemas suunas viiakse ükskõik, kui palju posti, siis jaotus on «asümeetriline». Kui posti liikumist ei jaotata, siis jaotus on «väljas». +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :Kui jaamast A viiakse jaama B umbes sama hulk posti, kui jaamast B jaama A, siis jaotus on «Sümeetriline». Kui mõlemas suunas viiakse ükskõik, kui palju posti, siis jaotus on «Asümeetriline». Kui posti liikumist ei jaotata, siis jaotus on «Väljas». STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :SOOMUSTATUD veoseliigi jaotuse viis: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Parasvöötmes on SOOMUSTATUD veoseliik väärisesemed, lähistroopikas teemandid, ning lähisartikas kuld. Neid saab lisada NewGRF-iga. Kui jaamast A viiakse jaama B umbes sama hulk kaupa, kui jaamast B jaama A, siis jaotus on «sümeetriline». Kui mõlemas suunas viiakse ükskõik, kui palju kaupa, siis jaotus on «asümeetriline». Kui posti liikumist ei jaotata, siis jaotus on «väljas». Lähisartikas valida asümeetriline või väljas, sest pankadest kulda tagasi ei tule. Parasvöötmes ja lähistroopikas on võimalik valida ka sümeetriline, sest pangad saadavad lähtepanka väärisesemed tagasi. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Parasvöötmes on SOOMUSTATUD veoseliik väärisesemed, lähistroopikas teemandid, ning lähisartikas kuld. Neid saab lisada NewGRF-iga. Kui jaamast A viiakse jaama B umbes sama hulk kaupa, kui jaamast B jaama A, siis jaotus on «Sümeetriline». Kui mõlemas suunas viiakse ükskõik, kui palju kaupa, siis jaotus on «Asümeetriline». Kui posti liikumist ei jaotata, siis jaotus on «Väljas». Lähisartikas valida asümeetriline või väljas, sest pankadest kulda tagasi ei tule. Parasvöötmes ja lähistroopikas on võimalik valida ka sümeetriline, sest pangad saadavad lähtepanka väärisesemed tagasi. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Teiste veoseliikide jaotuse viis: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :Kui jaamast A viiakse jaama B umbes sama hulk kaupa, kui jaamast B jaama A, siis jaotus on «sümeetriline». Kui mõlemas suunas viiakse ükskõik, kui palju kaupa, siis jaotus on «asümeetriline». Kui posti liikumist ei jaotata, siis jaotus on «väljas». Tavaliselt on head valikud «asümeetriline» ja «väljas». +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :Kui jaamast A viiakse jaama B umbes sama hulk kaupa, kui jaamast B jaama A, siis jaotus on «Sümeetriline». Kui mõlemas suunas viiakse ükskõik, kui palju kaupa, siis jaotus on «Asümeetriline». Kui posti liikumist ei jaotata, siis jaotus on «Väljas». Tavaliselt on head valikud «Asümeetriline» ja «Väljas». ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :väljas STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asümeetriline @@ -2051,6 +2073,7 @@ STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Tööst STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Kaubajaotus STR_CONFIG_SETTING_AI :{ORANGE}Konkurendid STR_CONFIG_SETTING_AI_NPC :{ORANGE}Arvuti +STR_CONFIG_SETTING_NETWORK :{ORANGE}Võrk STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS :Rongide marsruudileidja: {STRING} STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS_HELPTEXT :Marsruudileidja rongide jaoks @@ -2062,7 +2085,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automaatne taga STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Luba rongidel ümber pöörata kui nad on pikka aega foori taga oodanud ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(soovitatud) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(soovitatud) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Määra seade väärtus @@ -2105,7 +2128,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Edetabel STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Seaded STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF-i seadistus STR_INTRO_ONLINE_CONTENT :{BLACK}Aineste allalaadimine -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI/GameScripti seaded +STR_INTRO_AI_SETTINGS :{BLACK}TI Seaded +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}GameScript'i seaded STR_INTRO_QUIT :{BLACK}Välju STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Alusta uut mängu. Ctrl+klõps jätab kaardi seadistamise vahele @@ -2125,7 +2149,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Ava edet STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Ava seaded STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Ava NewGRF-i seadistamine STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Otsi allalaadimiseks uusi ja uuendatud aineseid -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Ava AI/GameScripti seaded +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Näita TI seadeid +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Näita GameSript'i seadeid STR_INTRO_TOOLTIP_QUIT :{BLACK}Välju 'OpenTTD'st STR_INTRO_BASESET :{BLACK}Hetkel valitud lähtegraafikakogust puudub {NUM} sprite{P "" 'i}. Kontrolli, kas lähtekogule on uuendusi. @@ -2157,12 +2182,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Muuda k STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Muuda jooksvat aastaarvu STR_CHEAT_SETUP_PROD :{LTBLUE}Tootmisväärtuste muutmine: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Parasvöötme maastik -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Lähisarktiline maastik -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Troopiline maastik -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Mänguasjamaa - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Värvivalik @@ -2260,7 +2279,9 @@ STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Vaheta k # Matches ServerGameType ###length 3 +STR_NETWORK_SERVER_VISIBILITY_LOCAL :Kohalik STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Avalik +STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :Kutsega # Network server list STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Mitmikmäng @@ -2291,11 +2312,15 @@ STR_NETWORK_SERVER_LIST_LANDSCAPE :{SILVER}Maastik STR_NETWORK_SERVER_LIST_MAP_SIZE :{SILVER}Kaardi mõõtmed: {WHITE}{COMMA}x{COMMA} STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}Serveri versioon: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}Serveri aadress: {WHITE}{STRING} +STR_NETWORK_SERVER_LIST_INVITE_CODE :{SILVER}Kutse kood: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_START_DATE :{SILVER}Aeg alguses: {WHITE}{DATE_SHORT} STR_NETWORK_SERVER_LIST_CURRENT_DATE :{SILVER}Aeg hetkel: {WHITE}{DATE_SHORT} +STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}GameScript: {WHITE}{STRING} (v{NUM}) STR_NETWORK_SERVER_LIST_PASSWORD :{SILVER}Kaitstud salasõnaga! STR_NETWORK_SERVER_LIST_SERVER_OFFLINE :{SILVER}SERVER ON MAAS STR_NETWORK_SERVER_LIST_SERVER_FULL :{SILVER}SERVER ON TÄIS +STR_NETWORK_SERVER_LIST_SERVER_BANNED :{SILVER}SERVER BÄNNIS SINU +STR_NETWORK_SERVER_LIST_SERVER_TOO_OLD :SILVER}SERVER ON LIIGA VANA STR_NETWORK_SERVER_LIST_VERSION_MISMATCH :{SILVER}ÜHILDUMATUD VERSIOONID STR_NETWORK_SERVER_LIST_GRF_MISMATCH :{SILVER}NEWGRF SOBIMATUS @@ -2308,7 +2333,7 @@ STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}Internet STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}Otsing LANis STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}Kohtvõrgus serverite otsimine STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Sisesta server -STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Sisesta loendisse uus server, milles toimuvaid mänge jälgida +STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Lisab loendisse uue serveri. See võib olla kas serveri aadress või kutse kood STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Tee server STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Tee oma server @@ -2359,9 +2384,10 @@ STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Ettevõt # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Ühendatud mängijad +STR_NETWORK_COMPANY_LIST_SPECTATE :Vaatle # Network client list -STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}Mitmikmäng +STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}Võrgumäng STR_NETWORK_CLIENT_LIST_SERVER :{BLACK}Server STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}Nimi STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}Serveri nimi, kus sa mängid @@ -2369,6 +2395,10 @@ STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Muuda om STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Serveri nimi STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Nähtavus STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Kas sinu server on kõikidele teistele avalikult nähtav +STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE :{BLACK}Kutse kood +STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}Kutse kood, mille abil teised mängijad saavad serveriga liituda +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE :{BLACK}Ühenduse tüüp +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}Kas ja kuidas saavad teised sinu serveriga ühendust STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Mängija STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Nimi STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Sinu mängija nimi @@ -2388,6 +2418,11 @@ STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Tema on # Matches ConnectionType ###length 5 +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN :{BLACK}Kohalik +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}Välised mängijad ei saa ühenduda +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Avalik +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_STUN :{BLACK}NAT'i taga +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TURN :{BLACK}Läbi vahendaja STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Viska välja STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Keela @@ -2400,6 +2435,11 @@ STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Kas ole STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Kas oled kindel, et tahad kustutada ettevõtte '{COMPANY}'? STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Kas oled kindel, et soovid nullida ettevõtte '{COMPANY}' salasõna? +STR_NETWORK_ASK_RELAY_CAPTION :{WHITE}Kasuta vahendajat? +STR_NETWORK_ASK_RELAY_TEXT :{YELLOW}Ühenduse loomine sinu ja serveri '{STRING}' vahel ebaõnnestus .{}Kas sa soovid seda sesiooni vahendada läbi '{STRING}'? +STR_NETWORK_ASK_RELAY_NO :{BLACK}Ei +STR_NETWORK_ASK_RELAY_YES_ONCE :{BLACK}Jah, ainult seekord +STR_NETWORK_ASK_RELAY_YES_ALWAYS :{BLACK}jah, ära küsi uuesti STR_NETWORK_SPECTATORS :Vaatlejad @@ -2428,11 +2468,12 @@ STR_NETWORK_CHAT_TO_COMPANY :[Team] kohta {S STR_NETWORK_CHAT_CLIENT :[Private] {STRING}: {WHITE}{STRING} STR_NETWORK_CHAT_TO_CLIENT :[Private] kohta {STRING}: {WHITE}{STRING} STR_NETWORK_CHAT_ALL :[All] {STRING}: {WHITE}{STRING} +STR_NETWORK_CHAT_EXTERNAL :[{3:STRING}] {0:STRING}: {WHITE}{1:STRING} STR_NETWORK_CHAT_OSKTITLE :{BLACK}Sisesta tekst võrgus suhtlemiseks # Network messages STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Võrgukaarti ei leitud või kompileeritud ilma võtmeta ENABLE_NETWORK -STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Server ei vastanud päringule +STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Ühendus serveriga aegus või sellest keelduti STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Ühendus ebaõnnestus NewGRF-i sobimatuse tõttu STR_NETWORK_ERROR_DESYNC :{WHITE}Mitmikmängu sünkroonimine ebaõnnestus STR_NETWORK_ERROR_LOSTCONNECTION :{WHITE}Mitmikmängu ühendus katkes @@ -2440,6 +2481,7 @@ STR_NETWORK_ERROR_SAVEGAMEERROR :{WHITE}Salvesta STR_NETWORK_ERROR_SERVER_START :{WHITE}Ei saa uut serverit alustada STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Tekkis protokolliviga ja ühendus katkes STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}Sinu mängijale ei ole nime määratud. Nime saab määrata mitmikmägu akna ülaosas +STR_NETWORK_ERROR_BAD_SERVER_NAME :{WHITE}Sinu serverile ei ole nime antud. Nime saab määrata mitmikmägu akna ülaosas STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}Kliendi osa ei vasta serveri osaga STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Vale salasõna STR_NETWORK_ERROR_SERVER_FULL :{WHITE}Server on täis @@ -2499,17 +2541,21 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :transpordisõlm STR_NETWORK_MESSAGE_CLIENT_LEAVING :lahkub STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} liitus mänguga -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} liitus mänguga ({2:NUM}. klient) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} liitus {2:NUM}. ettevõttega +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} liitus mänguga ({2:NUM}. klient) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} liitus {2:NUM}. ettevõttega 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_CLIENT_COMPANY_NEW :*** {0:STRING} alustas uue ettevõtte (nr {2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} lahkus mängust ({2: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_GIVE_MONEY :*** {0: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... STR_NETWORK_MESSAGE_KICKED :*** {STRING} visati välja. Põhjendus: ({STRING}) +STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Serveri registreerimine ebaõnnestus +STR_NETWORK_ERROR_COORDINATOR_REUSE_OF_INVITE_CODE :{WHITE}Teine server registreeris end sama kutse koodiga. "Kohalikule" mängu tüübile lülitumine. +STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Sinu server ei luba väliseid ühendusi +STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Teised mängijad ei saa sinu serveriga ühenduda # Content downloading window STR_CONTENT_TITLE :{WHITE}Aineste allalaadimine @@ -2615,6 +2661,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}küllastunud STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}ülekoormatud +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} transporditud kuus jaamast {STATION} jaama {STATION} ({COMMA}% kogumahust){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} mida transporditakse tagasi ({COMMA}% kogumahust) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Keskmine sõidukestus: {NUM}{NBSP}päev{P "" a} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Mõjupiirkonna näitamine STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Väljas @@ -2623,6 +2674,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Lülita STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Lülita sisse jaama mõjupiirkonna näitamine STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Võtab vastu: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Tarnib: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Hoolduse maksumus: {GOLD}{CURRENCY_SHORT}/a # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Liida jaamale @@ -2683,6 +2735,7 @@ STR_STATION_CLASS_WAYP :Meldepunktid # Signal window STR_BUILD_SIGNAL_CAPTION :{WHITE}Signaali valik +STR_BUILD_SIGNAL_TOGGLE_ADVANCED_SIGNAL_TOOLTIP :{BLACK}Lülita sisse keerukate signaalitüüpide näitamine STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Läbisõidusignaal (semafor){}Signaale läheb tarvis vältimaks kokkupõrkeid enam kui ühe rongiga rööbasteedel STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}Sissesõidusignaal (semafor){}Roheline, kuni vähemalt üks väljasõidusignaal on roheline. Muudel juhtudel näitab punast STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Väljasõidusignaal (semafor){}Käitub samamoodi, nagu läbisõidusignaal, kuid läheb vaja et sissesõidu- ja mitmik-hoiatussignaalid näitaksid õiget värvi @@ -2704,8 +2757,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Suurenda STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Vali raudteesild STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Vali sillatüüp STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Silla valik - ehitamiseks klõpsi sobival sillal -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Rippsild, terasest STR_BRIDGE_NAME_GIRDER_STEEL :Raamistikuga, terasest STR_BRIDGE_NAME_CANTILEVER_STEEL :Konsool, terasest @@ -2808,12 +2863,12 @@ STR_STATION_BUILD_NOISE :{BLACK}Tekitatu STR_LANDSCAPING_TOOLBAR :{WHITE}Maastik STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Maapinna madaldamine. Hiirega lohistades langetatakse esimesena valitud punkt ja ülejäänud ala tasandatakse vastavalt selle kõrgusele. Ctrl valib ala diagonaalselt. Shift valib ehitamise/hinna kuvamise režiimi STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Maapinna kõrgendamine. Hiirega lohistades tõstetakse esimesena valitud punkti ja tasandatakse ülejäänud ala selle järgi. Ctrl valib ala diagonaalselt. Shift valib ehitamise/hinna kuvamise režiimi -STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Tasanda maapinda esimesena valitud punkti kõrgusel. Ctrl valib piirkonna diagonaalselt. Shift valib ehitamise/hinna kuvamise režiimi -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Maa ostmine tulevaseks kasutamiseks. Shift valib ehitamise/eeldatava maksumuse kuvamise režiimi +STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Tasanda maapinda esimesena valitud punkti kõrgusel. Ctrl valib ala diagonaalselt. Shift valib ehitamise/hinna kuvamise režiimi +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Maa ostmine tulevaseks kasutamiseks. Shift valib ehitamise/eeldatava maksumuse kuvamise režiimi vahel # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Objekti valik -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Vali ehitatav objekt. Shift valib ehitamise/hinna kuvamise režiimi +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Vali ehitatav objekt. Ctrl valib ala diagonaaliti. Shift valib ehitamise/hinna kuvamise režiimi vahel STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Vali ehitatava objekti järk STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Objekti eelvaade STR_OBJECT_BUILD_SIZE :{BLACK}Suurus: {GOLD}{NUM} x {NUM} ruutu @@ -2825,7 +2880,7 @@ STR_OBJECT_CLASS_TRNS :Saatejaamad STR_PLANT_TREE_CAPTION :{WHITE}Puud STR_PLANT_TREE_TOOLTIP :{BLACK}Vali istutatava puu liik. Kui ruudus juba on puu, siis lisatakse rohkem eri liikide puid, olenemata valikust STR_TREES_RANDOM_TYPE :{BLACK}Suvalised puutüübid -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Istutab suvalisi puid. Shift valib ehitamise/hinna kuvamise režiimi +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Istutab suvalisi puid. Ctrl valib ala diagonaaliti. Shift valib ehitamise/hinna kuvamise režiimi vahel STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Suvalised puud STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Istutab puid suvaliselt üle kogu maa-ala STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Tavaline @@ -2857,6 +2912,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Suvaline STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Raja asula suvalisse kohta STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Palju suvalisi asulaid STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Kaardi katmine suvaliselt paigutatud asulatega +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Laienda kõiki asulaid +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Kõik asulad kasvavad vaikselt STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Asula nimi: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Sisesta asula nimi @@ -3135,6 +3192,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kaardi m STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Määrab kaardi mõõtmed ruutudes. Ruute, mida saab kasutada, on pisut vähem STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Asustuste arv: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Asulanimed: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Vali asulanimede stiil STR_MAPGEN_DATE :{BLACK}Algus: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Tööstustihedus: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Kõrgpunkt: @@ -3148,13 +3207,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Kõrbeka STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Suurenda kõrbekatvust kümne protsendi võrra STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Vähenda kõrbekatvust kümne protsendi võrra STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Maatekituse meetod: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Maapinna tüüp: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Merepinna tase: +STR_MAPGEN_SEA_LEVEL :{BLACK}Merepinna tase: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Jõgesid: STR_MAPGEN_SMOOTHNESS :{BLACK}Laugus: STR_MAPGEN_VARIETY :{BLACK}Iseärasuste jaotus: STR_MAPGEN_GENERATE :{WHITE}Tekita +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF-i seadistus +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :Näita NewGRF-i seadeid +STR_MAPGEN_AI_SETTINGS :{BLACK}TI Seaded +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Näita TI seadeid +STR_MAPGEN_GS_SETTINGS :{BLACK}GameScript'i Seaded +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Näita GameSript'i seadeid + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Inglise (algne) +STR_MAPGEN_TOWN_NAME_FRENCH :Prantsusmaa +STR_MAPGEN_TOWN_NAME_GERMAN :Saksamaa +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Inglise (täiendatud) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Ladina-Ameerika +STR_MAPGEN_TOWN_NAME_SILLY :Tobedad +STR_MAPGEN_TOWN_NAME_SWEDISH :Rootsi +STR_MAPGEN_TOWN_NAME_DUTCH :Hollandi +STR_MAPGEN_TOWN_NAME_FINNISH :Soome +STR_MAPGEN_TOWN_NAME_POLISH :Poola +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovakkia +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norra +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungari +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austria +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumeenia +STR_MAPGEN_TOWN_NAME_CZECH :Tšehhi +STR_MAPGEN_TOWN_NAME_SWISS :Šveitsi +STR_MAPGEN_TOWN_NAME_DANISH :Taani +STR_MAPGEN_TOWN_NAME_TURKISH :Türgi +STR_MAPGEN_TOWN_NAME_ITALIAN :Itaalia +STR_MAPGEN_TOWN_NAME_CATALAN :Katalaani # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kaardi ääred: @@ -3300,6 +3387,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Eelmine STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Proceed to the previous normal sprite, skipping any pseudo/recolour/font sprites and wrapping around at the begin STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representation of the currently selected sprite. The alignment is ignored when drawing this sprite STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Liiguta spraiti, muutes X ja Y tasakaalu. Ctrl+klõps, et liigutada kaheksa ühiku võrra korraga + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Kõrvalekalletega tsentreerimine +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite keskne + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Rist + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Lähtesta suhteline STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Lähtesta praegused suhtelised kõrvalekalded STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X kõrvalekalle: {NUM}, Y kõrvalekalle: {NUM} (Absoluutne) @@ -3314,18 +3408,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Hoiatus: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Viga: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Saatuslik viga: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Esines raske NewGRF-i tõrge:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Esines viga NewGRF-iga:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE} NewGRF "{STRING}" väljastas raske tõrke:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF "{STRING}" on väljastanud tõrke:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :OpenTTD väitel {1:STRING} ei tööta selle TTDPatch versiooniga. -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} on {STRING} TTD osa jaoks. -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} on mõeldud kasutamiseks {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :kõlbmatu «{1:STRING}» parameeter: parameeter {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} peab olema laetud enne {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} peab olema laetud pärast {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} nõuab OpenTTD versiooni {STRING} või uuemat +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} on {2:STRING} TTD osa jaoks. +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} on mõeldud kasutamiseks {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :kõlbmatu «{1:STRING}» parameeter: parameeter {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} peab olema laetud enne {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} peab olema laetud pärast {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} nõuab OpenTTD versiooni {2:STRING} või uuemat STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF fail, mis tehti tõlkimiseks, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Liiga palju NewGRF-e on laaditud -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Laadides {1:STRING} staatilise NewGRF-na koos {STRING} võib põhjustada sünkrooni katkemist. +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Laadides {1:STRING} staatilise NewGRF-na koos {2:STRING} võib põhjustada sünkrooni katkemist. STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Ootamatu sprite (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Ootamatu tegevus 0 property {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Kasutati kõlbmatut ID-d («sprite» {3:NUM}) @@ -3457,14 +3551,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Osta monopoolse STR_LOCAL_AUTHORITY_ACTION_BRIBE :Paku kohalikule omavalitsusele altkäemaksu ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Pisikese kohaliku reklaamikampaania korraldamine meelitab rohkem reisijaid ja kaupu sinu veoteenuseid kasutama.{}Tõstab asulakeskuse lähiümbruses ajutiselt jaamade tegevushinnanguid.{}Maksumus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Keskmise reklaamikampaania korraldamine, et meelitada rohkem reisijaid ja kaupu sinu teenuste juurede.{}Tõstab ajutiselt asulakeskuse ümbruses jaamade tegevushinnanguid.{}Maksumus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Suure reklaamikampaania korraldamine, et meelitada rohkem reisijaid ja kaupu sinu teenuste juurede.{}Tõstab asulakeskuse kaugümbruses ajutiselt jaamade tegevushinnanguid.{}Maksumus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Asula teedevõrgu ümberehituse rahastamine.{}Põhjustab liikluses tõsiseid häireid kuni 6 kuuks.{}Maksumus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Oma ettevõtte auks kuju ehitamine.{}Tõstab püsivalt jaamade tegevushinnanguid selles asulas.{}Maksumus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Uute hooneehituste rahastamine selles asulas.{}Tõstab ajutiselt asula kasvutempot selles asulas.{}Maksumus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Üheks aastaks monopoolsete veoõiguste ostmine selles asulas.{}Asula omavalitsus lubab reisijate ja kauba veoks kasutada ainult sinu jaamasid.{}Maksumus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Kohalikule omavalitusele ettevõtte hinnangu tõstmise eesmärgil altkäemaksu pakkumine. Vahele jäädes tuleb trahvi maksta.{}Maksumus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Pisikese kohaliku reklaamikampaania korraldamine meelitab rohkem reisijaid ja kaupu sinu veoteenuseid kasutama.{}Tõstab asulakeskuse lähiümbruses ajutiselt jaamade tegevushinnanguid.{}{POP_COLOUR}Maksumus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :PUSH_COLOUR}{YELLOW}Keskmise reklaamikampaania korraldamine, et meelitada rohkem reisijaid ja kaupu sinu teenuste juurede.{}Tõstab ajutiselt asulakeskuse ümbruses jaamade tegevushinnanguid.{}{POP_COLOUR}Maksumus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Suure reklaamikampaania korraldamine, et meelitada rohkem reisijaid ja kaupu sinu teenuste juurede.{}Tõstab asulakeskuse kaugümbruses ajutiselt jaamade tegevushinnanguid.{}{POP_COLOUR}Maksumus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Asula teedevõrgu ümberehituse rahastamine.{}Põhjustab liikluses tõsiseid häireid kuni 6 kuuks.{}{POP_COLOUR}Maksumus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Oma ettevõtte auks kuju ehitamine.{}Tõstab püsivalt jaamade tegevushinnanguid selles asulas.{}{POP_COLOUR}Maksumus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Uute hooneehituste rahastamine selles asulas.{}Tõstab ajutiselt asula kasvutempot selles asulas.{}{POP_COLOUR}Maksumus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Üheks aastaks monopoolsete veoõiguste ostmine selles asulas.{}Asula omavalitsus lubab reisijate ja kauba veoks kasutada ainult sinu jaamasid.{}{POP_COLOUR}Maksumus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Kohalikule omavalitusele ettevõtte hinnangu tõstmise eesmärgil altkäemaksu pakkumine. Vahele jäädes tuleb trahvi maksta.{}{POP_COLOUR}Maksumus: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} eesmärgid @@ -3617,24 +3711,38 @@ STR_FINANCES_CAPTION :{WHITE}{COMPANY STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}Tulu +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Opereerimiskulud +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Kapitalikulud ###length 13 STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Ehituskulud STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Uus veerem -STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Rongide käituskulud -STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Mootorsõidukite käituskulud -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Õhusõidukite käituskulud -STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Laevade käituskulud +STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Rongid +STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Maanteesõidukite käituskulud +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Õhusõidukid +STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Laevad +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Taristu +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Rongid +STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}Maanteesõidukid +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Õhusõidukid +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Laevad STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Laenuintressid STR_FINANCES_SECTION_OTHER :{GOLD}Muud -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} -STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_TOTAL_CAPTION :{WHITE}Kokku +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} +STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Tulu STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Kontojääk +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Omavahendid STR_FINANCES_LOAN_TITLE :{WHITE}Laen +STR_FINANCES_INTEREST_RATE :{WHITE}Laenuintress: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Laenulimiit: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Laena {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Laena raha STR_FINANCES_REPAY_BUTTON :{BLACK}Tagasimakse {CURRENCY_LONG} @@ -3735,7 +3843,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Toodab: STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Nõuab: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} ootel{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Tootlikuse muutmine (kaheksaga jaguv, kuni 2040) @@ -3765,6 +3873,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Saada ju STR_VEHICLE_LIST_REPLACE_VEHICLES :Asenda veovahendeid STR_VEHICLE_LIST_SEND_FOR_SERVICING :Saada hooldusesse STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Selle aasta kasum: {CURRENCY_LONG} (eelneval: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Saada depoose STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Saada depoose @@ -3797,7 +3907,7 @@ STR_GROUP_CREATE_TOOLTIP :{BLACK}Klõpsa STR_GROUP_DELETE_TOOLTIP :{BLACK}Eemalda valitud jagu STR_GROUP_RENAME_TOOLTIP :{BLACK}Ümbernimeta valitud jagu STR_GROUP_LIVERY_TOOLTIP :{BLACK}Muuda valitud jao värvistikku -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Klõpsa, et kaitsta seda jagu globaalse automaatasenduse eest +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Klõpsa, et kaitsta seda jagu globaalse automaatasenduse eest. Ctrl+klõps kaitsmaks ka alamkategooriaid. STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Kõrvalda jagu STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Kas oled kindel, et tahad kustutada selle grupi ja kõik järglased? @@ -3819,7 +3929,7 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Uus elektriraud STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Uus monorelsssõiduk STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Uus magnethõljuksõiduk -STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Uued mootorsõidukid +STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Uued maanteesõidukid STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Uued trammid # Vehicle availability @@ -3856,6 +3966,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Suurim v STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Tegevusradius: {GOLD}{COMMA} ruutu STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Õhusõiduki liik: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Kõik veoseliigid +STR_CARGO_TYPE_FILTER_FREIGHT :Kaubad +STR_CARGO_TYPE_FILTER_NONE :Puudub + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Nimekiri raudteesõidukitest - andmete saamiseks klõpsa raudteesõidukile STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Mootorsõidukite nimekiri - andmete saamiseks klõpsa sõidukile @@ -4024,7 +4139,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :õhusõiduki STR_ENGINE_PREVIEW_SHIP :laeva STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Hind: {CURRENCY_LONG} Tühimass: {WEIGHT_SHORT}{}Tippkiirus: {VELOCITY} Võimsus: {POWER}{}Käituskulud: {CURRENCY_LONG}/aastas{}Kandevõime: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Hind: {CURRENCY_LONG} Tühimass: {WEIGHT_SHORT}{}Kiirus: {VELOCITY} Võimsus: {POWER} Veojõud: {6:FORCE}{}Käituskulud: {4:CURRENCY_LONG}/aasta{}Mahutavus: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Hind: {0:CURRENCY_LONG} Tühimass: {1:WEIGHT_SHORT}{}Kiirus: {2:VELOCITY} Võimsus: {3:POWER} Veojõud: {6:FORCE}{}Käituskulud: {4:CURRENCY_LONG}/aasta{}Mahutavus: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Hind: {CURRENCY_LONG} Tippkiirus: {VELOCITY}{}Kandevõime: {CARGO_LONG}{}Käituskulud: {CURRENCY_LONG}/a STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Maksumus: {CURRENCY_LONG} Tippkiirus: {VELOCITY}{}Õhusõiduki liik: {STRING}{}Mahutavus: {CARGO_LONG}, {CARGO_LONG}{}Käituskulud: {CURRENCY_LONG}/aasta STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Hind: {CURRENCY_LONG} Tippkiirus: {VELOCITY}{}Õhusõiduki liik: {STRING}{}kandevõime: {CARGO_LONG}{}Käitluskulud: {CURRENCY_LONG}/a @@ -4078,7 +4193,9 @@ 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 ({STRING}): {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Automaatne asendamine hoiab rongi pikkuse samana, vajadusel kõrvaldab vaguneid (alates esiotsast), kui muidu rongikoosseis suureneks +STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+klõps, et rakendada ka alamgruppidele # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -4147,6 +4264,10 @@ STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Suundub STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL :{ORANGE}Suundub {DEPOT}, {VELOCITY} STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL :{LTBLUE}Järelevaatus: {DEPOT}, {VELOCITY} +STR_VEHICLE_STATUS_CANNOT_REACH_STATION_VEL :{LTBLUE}Ei leita teed jaama {STATION}, {VELOCITY} +STR_VEHICLE_STATUS_CANNOT_REACH_WAYPOINT_VEL :{LTBLUE}Ei leita teed sihtkohta {WAYPOINT}, {VELOCITY} +STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_VEL :{ORANGE}Ei leita teed sihtkohta {DEPOT}, {VELOCITY} +STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_SERVICE_VEL :{LTBLUE}Ei leia teed sihtkohta {DEPOT}, {VELOCITY} # Vehicle stopped/started animations ###length 2 @@ -4177,12 +4298,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Tühimas STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Tühimass: {LTBLUE}{WEIGHT_SHORT} {BLACK}Võimsus: {LTBLUE}{POWER}{BLACK} Tippkiirus: {LTBLUE}{VELOCITY} {BLACK}Veojõud: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Kasum sel aastal: {LTBLUE}{CURRENCY_LONG} (eelmisel: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Kasum sellel aastal: {LTBLUE}{CURRENCY_LONG} (eelmisel aastal: {CURRENCY_LONG}) {BLACK}Min. jõudlus: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Tehnoseisund: {LTBLUE}{COMMA}% {BLACK}Rikkeid eelmisest hooldusest: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Valmistatud: {LTBLUE}{NUM}{BLACK} Väärtus: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Mahutavus: {LTBLUE}Pole{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Kandevõime: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kandevõime: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Kandevõime: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kandevõime: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Kandevõime: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Ülekantud tulu: {LTBLUE}{CURRENCY_LONG} @@ -4208,8 +4330,8 @@ STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Väärtus: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Selle rongi kandevõime: -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Tühi STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} jaamast {STATION} @@ -4451,22 +4573,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Alguskuu STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Vali graafiku alguskuupäev. Ctrl-klõps määrab graafiku alguskuupäeva ja jaotab sõidukid ühtlaselt, kasutades järjestust, kui sihid on planeeritud STR_TIMETABLE_CHANGE_TIME :{BLACK}Muuda aega -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Muuda märgitud korraldusele määratud aega +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Muuda märgitud korraldusele määratud aega. Ctrl+klõps seab aja kõigile korraldustele STR_TIMETABLE_CLEAR_TIME :{BLACK}Tühista aeg -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Tühista korralduse täitmiseks määratud aeg +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Tühista korralduse täitmiseks määratud aeg. Ctrl+klõps tühistab kõik korraldustele määratud ajad STR_TIMETABLE_CHANGE_SPEED :{BLACK}Muuda kiiruspiirangut -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Muuda märgitud korralduse kiiruspiirangut +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Muuda märgitud korralduse kiiruspiirangut. Ctrl+klõps seab kiiruspiirangu kõigile korraldustele STR_TIMETABLE_CLEAR_SPEED :{BLACK}Kustuta kiiruspiirang -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Eemalda märgitud korralduse kiiruspiirang +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Eemalda märgitud korralduse kiiruspiirang. Ctrl+klõps tühistab kõik korraldustele määratud kiiruspiirangud STR_TIMETABLE_RESET_LATENESS :{BLACK}Nulli hilinemisarvesti STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Nulli hilinemisarvesti, nii et sõiduk oleks graafikus STR_TIMETABLE_AUTOFILL :{BLACK}Isetäituv -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Kasuta liiniplaani täitmiseks järgmise sõidu andmeid (Ctrl+klõps säilitab ooteajad) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Kasuta liiniplaani täitmiseks järgmise sõidu andmeid. Ctrl+klõps proovib säilitab ooteajad STR_TIMETABLE_EXPECTED :{BLACK}Eeldatav STR_TIMETABLE_SCHEDULED :{BLACK}Plaanis @@ -4510,12 +4632,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Üks skr STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/GameScripti debugimise akent saab kasutada ainult serveris # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI/Game Script seadistus +STR_AI_CONFIG_CAPTION_AI :{WHITE}TI Konfiguratsioon +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}GameScript'i Konfiguratsioon STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Järgmises mängus laaditav GameScript STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AI-d järgmises mängus STR_AI_CONFIG_HUMAN_PLAYER :Inimene STR_AI_CONFIG_RANDOM_AI :Suvaline AI STR_AI_CONFIG_NONE :(mitte ühtegi) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Vastaseid kuni: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Tõsta STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Tõsta valitud AI loendis kõrgemale @@ -4523,12 +4647,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Langeta STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Langeta valitud AI loendis madalamale STR_AI_CONFIG_GAMESCRIPT :{SILVER}GameScript +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parameetrid STR_AI_CONFIG_AI :{SILVER}AI-d -STR_AI_CONFIG_CHANGE :{BLACK}{STRING.g} valimine -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :GameScript +STR_AI_CONFIG_CHANGE_AI :{BLACK} Vali TI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK} Vali GameScript STR_AI_CONFIG_CHANGE_GAMESCRIPT.g :GameScripti STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Lae teine skript STR_AI_CONFIG_CONFIGURE :{BLACK}Seadistamine @@ -4557,8 +4680,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Terve ka STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Kõrguskaardi ekraanipilt STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Pisikaardi ekraanipilt -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} parameetrid +# Script Parameters +STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameetrid STR_AI_SETTINGS_CAPTION_AI :AI STR_AI_SETTINGS_CAPTION_GAMESCRIPT :GameScript STR_AI_SETTINGS_CLOSE :{BLACK}Sulge @@ -4641,8 +4764,8 @@ STR_WARNING_HEIGHTMAP_SCALE_MESSAGE :{YELLOW}Kaardi STR_WARNING_FALLBACK_SOUNDSET :{WHITE}Mäng ei leidnud helisid. Helid saad paigaldada Internetisisu laadimise aknast # Screenshot related messages -STR_WARNING_SCREENSHOT_SIZE_CAPTION :{WHITE}Hiiglaslik kuvapaugutus -STR_WARNING_SCREENSHOT_SIZE_MESSAGE :{YELLOW}Kuvapaugutuse mõõtmed saavad olema {COMMA} x {COMMA} pikslit. Kuvapaugutuse tegemine võib võtta tükk aega. Kas sa oled kindel, et sa soovid jätkata? +STR_WARNING_SCREENSHOT_SIZE_CAPTION :{WHITE}Hiigelsuur ekraanipilt +STR_WARNING_SCREENSHOT_SIZE_MESSAGE :{YELLOW}Ekraanipildi mõõtmed saavad olema {COMMA} x {COMMA} pikslit. Ekraanipildi tegemine võib võtta tükk aega. Kas sa oled kindel, et sa soovid jätkata? STR_MESSAGE_HEIGHTMAP_SUCCESSFULLY :{WHITE}Kõrguskaart edukalt salvestatud, kui '{STRING}'. Kõrgpunkt on {NUM} STR_MESSAGE_SCREENSHOT_SUCCESSFULLY :{WHITE}Ekraanipilt on edukalt salvestatud nimega '{STRING}' @@ -4724,6 +4847,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... liig STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Tööstust ei saa tekitada... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}{STRING} ei saa siia ehitada... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Seda tüüpi tööstust ei saa siia ehitada... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Tööstust ei saa rahastada... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... liiga lähedal mõnele teisele tööstusele STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... enne pead asula rajama STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... iga asula kohta lubatud ainult üks @@ -4738,6 +4862,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... mets STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... saab ehitada ainult ülespoole lumepiiri STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... saab ehitada ainult allapoole lumepiiri +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Halva õnne tõttu ei viinud rahastus tööstuse rajamiseni; proovi uuesti +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Antud tööstusele ei leitud perspektiivikat asukohta STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE} '{STRING}' tööstuste jaoks polnud sobivaid asukohti STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Muuda kaardigeneratsiooni parameetreid, et saada parem kaart @@ -4905,6 +5031,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Mingi ob STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... ettevõtte peakorter on ees STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Seda maad ei saa osta... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... see on juba sinu oma! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... objekti rajamise limiit täis # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Ei saa jagu luua... @@ -4977,6 +5104,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Hooldusv STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... sõiduk hävitatud +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... kõik sõidukid ei ole identsed + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Ühtegi sõidukit ei ole saadaval STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Muuda NewGRF-i seadistust STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Sõidukeid ei ole veel saadaval @@ -5003,6 +5132,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Teisi ko STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}sõiduk ei saa igasse jaama minna STR_ERROR_CAN_T_ADD_ORDER :{WHITE}sõiduk ei saa antud jaama minna STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... seda korraldust jagav sõiduk ei saa sinna jaama minna +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... kõigil sõidukitel ei ole ühesugused korraldused +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... mitte kõik sõidukid ei jaga korraldusi STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Sihtpunktide nimekirja ei saa jagada... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Korralduste jagamist ei saa peatada... @@ -5010,6 +5141,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Sihtpunk STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... liiga kaugel eelmisest sihtpunktist STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... ebapiisav õhusõiduki lennuulatus +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Sõidukile ei saa graafikut määrata... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Sõidukid saavad ainult peatustes oodata diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index b65863312ecd3..c33caf91c0938 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -198,6 +198,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}hp STR_UNITS_POWER_METRIC :{COMMA}hp STR_UNITS_POWER_SI :{COMMA}kW + STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -354,9 +355,8 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Gevst # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Spæl møguleikar -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Spæl script innstillingar STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF innstillingar STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Gjøgnumskygnis møguleikar STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Bygdarnøvn víst @@ -896,36 +896,6 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :Sjálvgjørt... STR_GAME_OPTIONS_CURRENCY_GEL :Georgiskur Lari STR_GAME_OPTIONS_CURRENCY_IRR :Iranskur Rial -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Vinstrakoyring -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Høgrakoyring - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Bygdar nøvn -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Áset slag av bygdar nøvnum - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Ensk (Upprunalig) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Fronsk -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Týsk -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Ensk (Meiri) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latin-Amerikonsk -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Fjákut -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Svensk -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Niðurlendsk -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finsk -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polsk -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovakisk -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norsk -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungarsk -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Eysturrísk -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumensk -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tjekkisk -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Sveisisk -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Donsk -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turkisk -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiensk -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalanisk - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Sjálvgoymsla STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Vel títtleika av sjálvgoymslu @@ -955,7 +925,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :annað - STR_GAME_OPTIONS_BASE_GRF :{BLACK}Base grafikk sett STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Vel ta base grafikk setti tú vil brúka STR_GAME_OPTIONS_BASE_GRF_STATUS :{RED}{NUM} vantandi/oyðiløgd fíl{P a ir} @@ -998,8 +967,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Undanv STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pund (£) í tínum gjaldsoyra STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Broyt parametur í sjálvgjørda gjaldsoyranum -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Hægsta tali av kappingarneytum: {ORANGE}{COMMA} - STR_NONE :Einki STR_FUNDING_ONLY :Fíggjing einans STR_MINIMAL :Minst @@ -1049,6 +1016,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Lýtt landslag +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Undir-arktiskt landslag +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Undir-tropiskt landslag +STR_CLIMATE_TOYLAND_LANDSCAPE :Leikuland landslag + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Sera flatt STR_TERRAIN_TYPE_FLAT :Flatt @@ -1114,6 +1087,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Høgra STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Hægst loyvda byrjunar lán: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Mest loyvda upphæddin ein fyritøka kann lána (uttan at taka virðisminkan til eftirtektar) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Rentu stigi: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Rentustigi á láni, stýrir eisini virðisminkan um hon er sligin til @@ -1355,6 +1329,10 @@ STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :Upprunalig STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Betra +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Vinstrakoyring +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Høgrakoyring + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Hæddarkort snarðing: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Í móti klokkunu @@ -1732,7 +1710,7 @@ STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS :Leiðbeinari fy STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS_HELPTEXT :Leið beinari at nýta fyri skip ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Viðmældur) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Viðmældur) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Broyt ásetings virði @@ -1761,7 +1739,6 @@ STR_INTRO_GAME_OPTIONS :{BLACK}Spæli m STR_INTRO_HIGHSCORE :{BLACK}Hástigs yvirlit STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF innstillingar STR_INTRO_ONLINE_CONTENT :{BLACK}Kanna online tilfar -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI/Spæli script innstillingar STR_INTRO_QUIT :{BLACK}Gevst STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Byrja eitt nýtt spæl. Ctrl+trýst leypur um uppseting av korti @@ -1780,7 +1757,6 @@ STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Vís sp STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Vís hástigs yvirlit STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Vís NewGRF innstillingar STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Kanna um nýtt og betra tilfar er klárt at heinta niður -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Vís AI/Spæli script innstillingar STR_INTRO_TOOLTIP_QUIT :{BLACK}Gevst at spæla 'OpenTTD' STR_INTRO_TRANSLATION :{BLACK}Hesi umseting vantar {NUM} str{P ong eingir}. Vinarliga hjálp til við at gera OpenTTD betri, tekna teg sum umsetara. Sí readme.txt viðvíkjandi smálutum. @@ -1807,12 +1783,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Broyt d STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Broyt núverðandi ár STR_CHEAT_SETUP_PROD :{LTBLUE}Gilda broytingar av framleiðslu virðum: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Lýtt landslag -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Undir-arktiskt landslag -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Undir-tropiskt landslag -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Leikuland landslag - # Livery window STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Vís vanligu lit samansetingarnar @@ -2202,6 +2172,8 @@ STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Ger luti # Linkgraph legend window and linkgraph legend in smallmap +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Hálýsing av deknings øki STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Sløkt @@ -2262,8 +2234,6 @@ STR_BUILD_SIGNAL_CAPTION :{WHITE}Úrval a STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Vel jarnbreyta brúgv STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Vel vega brúgv STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Brúgva úrval - trýst á ta brúnna tær dámar fyri at byggja hana -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Heingibrúgv, stál STR_BRIDGE_NAME_GIRDER_STEEL :Bjálkabrúgv, stál STR_BRIDGE_NAME_CANTILEVER_STEEL :Cantilever, stál @@ -2573,16 +2543,40 @@ STR_MAPGEN_MAPSIZE :{BLACK}Stødd STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Vel stødd av korti í puntum. Talið av tøkum puntum verur eitt sindur minni STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Nr. av bygdum: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Bygdar nøvn +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Áset slag av bygdar nøvnum STR_MAPGEN_DATE :{BLACK}Dato: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Nr. av ídnaðum: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Lendis framleiðari: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Slag av lendi: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Sjóvarmáli: +STR_MAPGEN_SEA_LEVEL :{BLACK}Sjóvarmáli: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Løkar: STR_MAPGEN_SMOOTHNESS :{BLACK}Mjúkleiki: STR_MAPGEN_VARIETY :{BLACK}Fjølbroytnis útluting: STR_MAPGEN_GENERATE :{WHITE}Framleið +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Ensk (Upprunalig) +STR_MAPGEN_TOWN_NAME_FRENCH :Fronsk +STR_MAPGEN_TOWN_NAME_GERMAN :Týsk +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Ensk (Meiri) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latin-Amerikonsk +STR_MAPGEN_TOWN_NAME_SILLY :Fjákut +STR_MAPGEN_TOWN_NAME_SWEDISH :Svensk +STR_MAPGEN_TOWN_NAME_DUTCH :Niðurlendsk +STR_MAPGEN_TOWN_NAME_FINNISH :Finsk +STR_MAPGEN_TOWN_NAME_POLISH :Polsk +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovakisk +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norsk +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungarsk +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Eysturrísk +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumensk +STR_MAPGEN_TOWN_NAME_CZECH :Tjekkisk +STR_MAPGEN_TOWN_NAME_SWISS :Sveisisk +STR_MAPGEN_TOWN_NAME_DANISH :Donsk +STR_MAPGEN_TOWN_NAME_TURKISH :Turkisk +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiensk +STR_MAPGEN_TOWN_NAME_CATALAN :Katalanisk + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kort eggir: STR_MAPGEN_NORTHWEST :{BLACK}Útnyrðingur @@ -2701,6 +2695,10 @@ STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}NewGRF v STR_SPRITE_ALIGNER_CAPTION :{WHITE}Aligning sprite {COMMA} ({STRING}) STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}Next sprite +###length 2 + + + # NewGRF (self) generated warnings/errors STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING} @@ -3121,6 +3119,8 @@ STR_PURCHASE_INFO_ALL_BUT :Alt uttan {CARG STR_PURCHASE_INFO_MAX_TE :{BLACK}Maks. Dráttar ómak: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Vídd: {GOLD}{COMMA} puntar +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Tok úrvals yvirlit - trýst á eitt flutningstól fyri kunning STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Akfar úrvals yvirlit - trýst á eitt akfar fyri kunning @@ -3647,12 +3647,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Eitt av STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/Game script debug gluggi er einans tøkur fyri servaran # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI/Spæli script innstillingar STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Spæli scripti sum verður heinta í næsta spæli STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AI sum verða heintaði í næsta spæli STR_AI_CONFIG_HUMAN_PLAYER :Menniskja spælari STR_AI_CONFIG_RANDOM_AI :Tilvildarligt AI STR_AI_CONFIG_NONE :(einki) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Hægsta tali av kappingarneytum: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Flyt upp STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Flyt valda AI upp í listanum @@ -3662,8 +3662,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Flyt val STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spæli script STR_AI_CONFIG_AI :{SILVER}AI -STR_AI_CONFIG_CHANGE :{BLACK}Vel {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :AI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Spæli script STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Heinta eitt annað script @@ -3686,10 +3684,8 @@ STR_AI_LIST_CANCEL :{BLACK}Angra STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ikki broyta scripti -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametur +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spæl Script STR_AI_SETTINGS_CLOSE :{BLACK}Lat aftur STR_AI_SETTINGS_RESET :{BLACK}Endurstilla STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4089,6 +4085,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Kann ikk STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... akfar smildra sundur + # Specific vehicle errors STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Kann ikki fáa tok at fara framvið jarnbreytatekin tá vandi er... STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN :{WHITE}Kann ikki venda toki vi... @@ -4117,6 +4114,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Kann ikk STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... ov langt frá fyrra staði STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... flogfarið røkkur ikki +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kann ikki gera tíðarætlan fyri akfrar... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Akfør kunnu bara bíða við støðir diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index eb90dd50d6b67..53bb64333d8d3 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hv STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hv STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hv/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hv/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hv/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hv/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hv/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hv/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -225,9 +235,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Suodatinteksti: -STR_LIST_FILTER_OSKTITLE :{BLACK}Syötä suodatinteksti -STR_LIST_FILTER_TOOLTIP :{BLACK}Syötä avainsana suodattaaksesi listan +STR_LIST_FILTER_TITLE :{BLACK}Suodatin: +STR_LIST_FILTER_OSKTITLE :{BLACK}Syötä yksi tai useampi avainsana listan suodattamiseksi +STR_LIST_FILTER_TOOLTIP :{BLACK}Syötä yksi tai useampi avainsana listan suodattamiseksi STR_TOOLTIP_GROUP_ORDER :{BLACK}Valitse ryhmittelytapa STR_TOOLTIP_SORT_ORDER :{BLACK}Valitse järjestys (laskeva/nouseva) @@ -376,9 +386,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Kuntien STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Teollisuuden luonti STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Tienrakennus STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Raitiotien rakentaminen -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Istuta puita. Shift vaihtaa istutustilan ja kustannusarvion välillä +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Istuta puita. Ctrl valitsee alueen vinottain. Shift vaihtaa istutustilan ja kustannusarvion välillä STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Sijoita kyltti -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Sijoita objekti. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Sijoita objekti. Ctrl valitsee alueen vinottain. Shift vaihtaa rakennustilan ja kustannusarvion välillä # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Lopeta # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Pelin valinnat STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Asetukset -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Tekoälyn/peliskriptin asetukset +STR_SETTINGS_MENU_AI_SETTINGS :Tekoälyasetukset +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Peliskriptiasetukset STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF-asetukset STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Läpinäkyvyysasetukset STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Kuntien nimet näkyvissä @@ -498,8 +509,8 @@ STR_ABOUT_MENU_SCREENSHOT :Kuvakaappaus STR_ABOUT_MENU_SHOW_FRAMERATE :Näytä kuvataajuus STR_ABOUT_MENU_ABOUT_OPENTTD :Tietoja OpenTTD:stä STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite-kohdistaja -STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Reunat päälle/pois -STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Likaisten ruutujen värjäys päälle/pois +STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Rajakehikot päälle/pois +STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Likaisten lohkojen värjäys päälle/pois # Place in highscore window ###length 15 @@ -669,7 +680,7 @@ STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKG STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Musiikkia ei ole saatavilla -STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" +STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}”{STRING}” STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Raita STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Nimi STR_MUSIC_SHUFFLE :{TINY_FONT}{BLACK}Sekoita @@ -690,7 +701,7 @@ STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Näytä # Playlist window STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Soittolista – ”{STRING}” -STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" +STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} ”{STRING}” STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Raita STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Soittolista – ”{STRING}” STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Tyhjennä @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Intian rupia (I STR_GAME_OPTIONS_CURRENCY_IDR :Indonesian rupia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malesian ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Vasemmanpuolinen liikenne -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Oikeanpuolinen liikenne - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Kuntien nimet: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Valitse kuntien nimien tyyli - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Englantilainen -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Ranskalainen -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Saksalainen -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Englantilainen 2 -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latinalaisamerikkalainen -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Hassu -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Ruotsalainen -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Hollantilainen -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Suomalainen -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Puolalainen -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovakialainen -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norjalainen -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Unkarilainen -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Itävaltalainen -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romanialainen -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tšekkiläinen -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Sveitsiläinen -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Tanskalainen -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turkkilainen -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italialainen -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalonialainen - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automaattitallennus STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Valitse aikaväli automaattisille pelitallennuksille @@ -1027,21 +1008,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Valitse STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Nykyinen ajuri: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Käyttöliittymän koko -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Valitse käyttöliittymäelementtien koko +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Käyttöliittymän koko +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Vedä liukusäädintä asettaaksesi käyttöliittymän koon. Pidä Ctrl-näppäintä painettuna säätääksesi portaattomasti +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Tunnista koko automaattisesti +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Valitse tämä ruutu käyttöliittymän koon tunnistamiseksi automaattisesti -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(tunnista automaattisesti) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Tavallinen -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Kaksinkertainen -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Nelinkertainen +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Skaalaa viisteet +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Valitse tämä ruutu reunusten skaalaamiseksi käyttöliittymän koon mukaan -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Kirjasinkoko -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Valitse käyttöliittymän kirjasinkoko - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(tunnista automaattisesti) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normaali -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Kaksinkertainen koko -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Nelinkertainen koko +STR_GAME_OPTIONS_GUI_SCALE_1X :1× +STR_GAME_OPTIONS_GUI_SCALE_2X :2× +STR_GAME_OPTIONS_GUI_SCALE_3X :3× +STR_GAME_OPTIONS_GUI_SCALE_4X :4× +STR_GAME_OPTIONS_GUI_SCALE_5X :5× STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafiikka @@ -1093,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Esikats STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10 000 puntaa (£) valuutassasi STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Vaihda oman valuutan parametria. -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Vastustajien enimmäismäärä: {ORANGE}{COMMA} - STR_NONE :Ei mitään STR_FUNDING_ONLY :Vain rahoitetut STR_MINIMAL :Minimi @@ -1144,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :lauhkea maasto +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :pohjoinen maasto +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :subtrooppinen maasto +STR_CLIMATE_TOYLAND_LANDSCAPE :Lelumaan maasto + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Hyvin tasainen STR_TERRAIN_TYPE_FLAT :Tasainen @@ -1163,7 +1146,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}Ei sovel # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Asetukset -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Suodatinteksti: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Suodatin: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Avaa kaikki STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Sulje kaikki STR_CONFIG_SETTING_RESET_ALL :{BLACK}Palauta oletukset @@ -1223,6 +1206,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :oikealla STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Suurin mahdollinen laina alussa: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Suurin mahdollinen yhtiön ottama laina (ottamatta huomioon inflaatiota) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Ei lainaa {RED}Vaatii peliskriptin, joka tarjoaa alkupääoman STR_CONFIG_SETTING_INTEREST_RATE :Korko: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Lainan korko; ohjaa myös inflaatiota mikäli käytössä @@ -1288,10 +1274,10 @@ STR_CONFIG_SETTING_SMOKE_AMOUNT :Kulkuneuvon sav STR_CONFIG_SETTING_SMOKE_AMOUNT_HELPTEXT :Määrittää kuinka paljon savua tai kipinöitä kulkuneuvot saavat aikaan STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL :Junien kiihdytysmalli: {STRING} -STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL_HELPTEXT :Valitsee junien käyttämän fysiikkamallin. "Alkuperäinen" malli hidastaa junia mäissä tasapuolisesti. "Realistinen" malli hidastaa junia mäissä ja mutkissa junan ominaisuuksista riippuen +STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL_HELPTEXT :Valitsee junien kiihtyvyyden fysiikkamallin. ”Alkuperäisessä” mallissa mäet vaikuttavat kaikkiin juniin samalla tavalla. ”Realistinen” malli hidastaa junia mäissä ja kaarteissa riippuen kokoonpanon ominaisuuksista, kuten pituudesta ja vetovoimasta STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL :Ajoneuvojen kiihdytysmalli: {STRING} -STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL_HELPTEXT :Valitsee ajoneuvojen käyttämän fysiikkamallin. "Alkuperäinen" malli hidastaa ajoneuvoja mäissä tasapuolisesta. "Realistinen" malli hidastaa ajoneuvoja mäissä niiden ominaisuuksista riippuen +STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL_HELPTEXT :Valitsee ajoneuvojen kiihtyvyyden fysiikkamallin. ”Alkuperäisessä” mallissa mäet vaikuttavat kaikkiin ajoneuvoihin samalla tavalla. ”Realistinen” malli ottaa huomioon ajoneuvon ominaisuudet, kuten esimerkiksi vetovoiman STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS :Mäkien jyrkkyys junille: {STRING} STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Mäkien jyrkkyys junille. Korkeammat arvot tekevät mäkien nousemisesta vaikeampaa @@ -1345,7 +1331,7 @@ STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT :Uudet käskyt o STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT :Normaalisti kulkuneuvo pysähtyy jokaisella läpikulkemallaan asemalla. Mikäli tämä asetus on käytössä kulkuneuvot eivät pysähdy ajaessaan asemien läpi. Huomioi, että tämä asetus määrittää oletusarvoisen toiminnon uusille kulkuneuvoille. Asetusta voidaan muuttaa erikseen kunkin kulkuneuvon kohdalla STR_CONFIG_SETTING_STOP_LOCATION :Uudet junien käskyt pysäyttävät junan aseman {STRING} -STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :Paikka, johon juna pysähtyy oletuksena asemalla. ”Alkuun” tarkoittaa, että junan viimeinen vaunu pysähtyy laiturin alkuun; ”keskelle” tarkoittaa junan pysähtymistä keskelle laituria; ja ”loppuun” tarkoittaa, että veturi pysähtyy laiturin päähän. Huomaa, että tämä asetus määrittää vain oletusarvon uusille määräyksille. Yksittäisten määräysten kohdalla käyttäytymistä voi muuttaa tästä asetuksesta huolimatta +STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :Paikka, johon juna pysähtyy oletuksena asemalla. ”Alkuun” tarkoittaa, että junan viimeinen vaunu pysähtyy laiturin alkuun; ”keskelle” tarkoittaa junan pysähtymistä keskelle laituria; ja ”loppuun” tarkoittaa, että veturi pysähtyy laiturin päähän. Huomaa, että tämä asetus määrittää vain oletusarvon uusille käskyille. Yksittäisten käskyjen kohdalla käyttäytymistä voi muuttaa tästä asetuksesta huolimatta ###length 3 STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END :alkuun STR_CONFIG_SETTING_STOP_LOCATION_MIDDLE :keskelle @@ -1407,7 +1393,7 @@ STR_CONFIG_SETTING_WARN_LOST_VEHICLE :Varoita, jos ku STR_CONFIG_SETTING_WARN_LOST_VEHICLE_HELPTEXT :Lähetä viesti, jos kulkuneuvo ei löydä reittiä määränpäähänsä STR_CONFIG_SETTING_ORDER_REVIEW :Tarkista kulkuneuvojen pysähdykset: {STRING} -STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT :Mikäli käytössä, kulkuneuvojen määräykset tarkistetaan väliajoin ja havaituista ongelmista ilmoitetaan uutisviestillä +STR_CONFIG_SETTING_ORDER_REVIEW_HELPTEXT :Mikäli käytössä, kulkuneuvojen käskyjä tarkastetaan väliajoin, ja havaituista ongelmista ilmoitetaan uutisviestillä ###length 3 STR_CONFIG_SETTING_ORDER_REVIEW_OFF :Ei STR_CONFIG_SETTING_ORDER_REVIEW_EXDEPOT :Kyllä, mutta ei pysäytetyille @@ -1449,6 +1435,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Viivan leveys k STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Näytä NewGRF:n nimi kulkuneuvoikkunassa: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Lisää kulkuneuvovalikoimaikkunaan rivin, joka kertoo mistä NewGRF:stä valittu kulkuneuvo on peräisin. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Näytä kulkuneuvojen kuljetettavissa olevat rahdit listaikkunoissa {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Mikäli käytössä, kuljetettavissa oleva rahti näytetään kulkuneuvolistoissa kulkuneuvon yllä STR_CONFIG_SETTING_LANDSCAPE :Maasto: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Maasto vaikuttaa useisiin pelin peruselementteihin, kuten rahtiin ja kuntien kasvuedellytyksiin. NewGRF:t ja peliskriptit voivat kuitenkin vaikuttaa tarkemmin pelin kulkuun. @@ -1503,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Parannettu STR_CONFIG_SETTING_ROAD_SIDE :Ajoneuvot: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Valitse ajokaista +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Vasemmanpuolinen liikenne +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Oikeanpuolinen liikenne + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Korkeuskartan pyöritys:{STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Vastapäivään @@ -1909,9 +1901,9 @@ STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X :8x STR_CONFIG_SETTING_SPRITE_ZOOM_MIN :Korkein käytettävä sprite-resoluutio: {STRING} STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT :Rajoita suurinta spriteille käytettävää resoluutiota. Resoluution rajoittaminen estää korkean tarkkuuden grafiikoiden käyttämisen vaikka niitä olisi saatavilla. Tämä voi auttaa pitämään pelin ulkoasun yhtenäisenä käytettäessä sekaisin GRF-tiedostoja, joista osalla on ja osalla ei ole korkean tarkkuuden grafiikoita. ###length 3 -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_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 :Kuntien kasvunopeus: {STRING} STR_CONFIG_SETTING_TOWN_GROWTH_HELPTEXT :Kunnan kasvunopeus @@ -1936,13 +1928,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Käytä {STRING STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Jokaisen yhteyskuvaajan komponentin uudelleenlaskemiseen käytettävä aika. Uudelleenlaskun alkaessa käynnistetään uusi säie, jonka annetaan toimia näin monta päivää. Mitä lyhyemmäksi määrität tämän, sitä todennäköisempää on, että säie ei ole valmis ajoissa. Tällöin peli pysähtyy kunnes lasku on suoritettu loppuun (peli pätkii). Mitä pidemmäksi määrität asetuksen, sitä pitempään rahdin jakauman päivittämiseen kuluu aikaa reittien muuttuessa. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Matkustajien jakautuminen: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :”Symmetrinen” tarkoittaa, että suunnilleen sama määrä matkustajia kulkee asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että eri suuntiin voi kulkea eriävä määrä matkustajia. ”Manuaalinen” tarkoittaa, että automaattinen rahdin jakautuminen on pois käytöstä matkustajilla. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :”Symmetrinen” tarkoittaa, että suunnilleen sama määrä matkustajia kulkee asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että matkustajia voi kulkea mielivaltainen määrä kumpaankin suuntaan. ”Manuaalinen” tarkoittaa, että automaattista jakautumista ei sovelleta matkustajiin. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Postin jakautuminen: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :”Symmetrinen” tarkoittaa, että suunnilleen sama määrä postia lähetetään asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että eri suuntiin voidaan lähettää eriävä määrä postia. ”Manuaalinen” tarkoittaa, että automaattinen rahdin jakautuminen on pois käytöstä postilla. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :”Symmetrinen” tarkoittaa, että suunnilleen sama määrä postia kulkee asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että postia voi kulkea mielivaltainen määrä kumpaankin suuntaan. ”Manuaalinen” tarkoittaa, että automaattista jakautumista ei sovelleta postiin. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Arvokuljetusten jakautuminen: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Arvokuljetuksiin kuuluvat arvotavarat lauhkeassa ilmastossa, timantit subtrooppisessa ilmastossa ja kulta pohjoisessa ilmastossa. NewGRF:t voivat kuitenkin muuttaa näitä rahteja. ”Symmetrinen” tarkoittaa, että suunnilleen sama määrä rahtia lähetetään asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että eri suuntiin voidaan lähettää eriävä määrä rahtia. ”Manuaalinen” tarkoittaa, että automaattinen rahdin jakautuminen on poistettu käytöstä rahdilta. Suositeltavia asetuksia ovat ”epäsymmetrinen” tai ”manuaalinen” pelattaessa pohjoisessa ilmastossa, sillä pankit eivät lähetä kultaa takaisin kaivoksille. Lauhkeassa ja subtrooppisessa ilmastossa pelatessa voidaan myös valita ”symmetrinen”, sillä pankit lähettävät arvotavaroita takaisin alkuperäiselle pankille. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Arvokuljetuksiin kuuluvat arvotavarat lauhkeassa ilmastossa, timantit subtrooppisessa ilmastossa ja kulta pohjoisessa ilmastossa. NewGRF:t voivat kuitenkin muuttaa näitä rahteja. ”Symmetrinen” tarkoittaa, että suunnilleen sama määrä rahtia lähetetään asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että tätä rahtia lähetetään mielivaltainen määrä kumpaankin suuntaan. ”Manuaalinen” tarkoittaa, että automaattista jakautumista ei sovelleta tähän rahtiin. Suositeltavia asetuksia ovat ”epäsymmetrinen” tai ”manuaalinen” pelattaessa pohjoisessa tai subtrooppisessa ilmastossa, sillä näissä pankit ottavat ainoastaan vastaan rahtia. Lauhkeassa ilmastossa pelatessa voidaan myös valita ”symmetrinen”, sillä pankit myös lähettävät arvotavaroita takaisin lähtöpankille. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Muiden rahtityyppien jakautuminen: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :”Epäsymmetrinen” tarkoittaa, että eri suuntiin voidaan lähettää eriäviä määriä rahtia. ”Manuaalinen” tarkoittaa, että automaattinen jakautuminen ei ole käytössä rahdille. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :”Epäsymmetrinen” tarkoittaa, että rahtia lähetetään mielivaltainen määrä kumpaankin suuntaan. ”Manuaalinen” tarkoittaa, että automaattista jakautumista ei sovelleta näihin rahteihin. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuaalinen STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :epäsymmetrinen @@ -2037,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automaattinen k STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Sallii junien kääntymisen opastimen edessä pitkän odotusajan jälkeen ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Suositeltu) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Suositeltu) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Muuta asetusarvo @@ -2059,7 +2051,7 @@ STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND :{WHITE}... ohit STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND :{WHITE}... ohitetaan äänipaketti ”{STRING}”: ei löydetty STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND :{WHITE}... ohitetaan musiikkipaketti ”{STRING}”: ei löydetty STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}Muisti lopussa -STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}{BYTES} sprite-välimuistin varaaminen epäonnistui. Sprite-välimuistin kooksi valittiin {BYTES}. Tämä heikentää OpenTTD:n suorituskykyä. Vähentääksesi muistivaatimuksia voit kokeilla poistaa käytöstä 32bpp-grafiikat ja/tai lähennystasoja +STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}{BYTES} sprite-välimuistin varaaminen epäonnistui. Sprite-välimuistin kooksi valittiin {BYTES}. Tämä heikentää OpenTTD:n suorituskykyä. Vähentääksesi muistivaatimuksia voit kokeilla poistaa käytöstä 32 bpp -grafiikat ja/tai lähennystasoja # Video initalization errors STR_VIDEO_DRIVER_ERROR :{WHITE}Virhe näyttöasetuksissa… @@ -2080,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Pistetau STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Asetukset STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF-asetukset STR_INTRO_ONLINE_CONTENT :{BLACK}Tarkista online-sisältö -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Tekoälyn/peliskriptin asetukset +STR_INTRO_AI_SETTINGS :{BLACK}Tekoälyasetukset +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Peliskriptiasetukset STR_INTRO_QUIT :{BLACK}Sulje STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Aloita uusi peli. Ctrl+napsautus ohittaa kartan asetusten valinnan. @@ -2100,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Näytä STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Näytä asetukset STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Näytä NewGRF-asetukset STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Tarkista uutta ja päivitettyä sisältöä ladattavaksi -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Näytä tekoäly/peliskriptiasetukset +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Näytä tekoälyasetukset +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Näytä peliskriptiasetukset STR_INTRO_TOOLTIP_QUIT :{BLACK}Lopeta OpenTTD STR_INTRO_BASESET :{BLACK}Valitusta perusgrafiikkapaketista puuttuu {NUM} sprite{P "" ä}. Tarkista, onko sille päivityksiä. @@ -2132,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Muuta p STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Muuta nykyistä vuotta STR_CHEAT_SETUP_PROD :{LTBLUE}Salli tuotantomäärien muuttaminen: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :lauhkea maasto -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :pohjoinen maasto -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :subtrooppinen maasto -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Lelumaan maasto - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY}: Väriteema @@ -2370,7 +2358,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Uusi yhtiö) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Perusta uusi yhtiö ja liity siihen STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Tämä olet sinä STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Tämä on pelin ylläpitäjä -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} pelaaja{P "" a} / {NUM} yhtiö{P "" tä} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} pelaaja{P "" a} – {NUM}/{NUM} yhtiö{P "" tä} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Tällä hetkellä kytkeytyneiden asiakkaiden määrä, yhtiöiden määrä sekä palvelimen ylläpitäjän sallima yhtiöiden enimmäismäärä # Matches ConnectionType ###length 5 @@ -2497,13 +2486,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :odotetaan yhtey STR_NETWORK_MESSAGE_CLIENT_LEAVING :poistutaan STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} on liittynyt peliin -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} liittyi peliin (asiakas nro {2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} on liittynyt yhtiöön nro {2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} liittyi peliin (asiakas nro{NBSP}{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} on liittynyt yhtiöön nro {2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} on liittynyt katselijoihin -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} on aloittanut uuden yhtiön (nro {2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} on poistunut pelistä ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} on aloittanut uuden yhtiön (nro{NBSP}{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} on poistunut pelistä ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} on muuttanut nimekseen {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} antoi {2:CURRENCY_LONG} yhtiölle {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} antoi {2:CURRENCY_LONG} yhtiölle {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Palvelin sulki istunnon STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Palvelin käynnistyy uudelleen...{}Odota, ole hyvä... STR_NETWORK_MESSAGE_KICKED :{STRING} potkaistiin ulos. Syy: ({STRING}) @@ -2555,7 +2544,7 @@ STR_CONTENT_DETAIL_FILESIZE :{SILVER}Latauks STR_CONTENT_DETAIL_SELECTED_BECAUSE_OF :{SILVER}Valittu seuraavan takia: {WHITE}{STRING} STR_CONTENT_DETAIL_DEPENDENCIES :{SILVER}Vaatimukset: {WHITE}{STRING} STR_CONTENT_DETAIL_TAGS :{SILVER}Avainsanat: {WHITE}{STRING} -STR_CONTENT_NO_ZLIB :{WHITE}OpenTTD on käännetty ilman "zlib"-tukea... +STR_CONTENT_NO_ZLIB :{WHITE}OpenTTD on käännetty ilman ”zlib”-tukea… STR_CONTENT_NO_ZLIB_SUB :{WHITE}... sisällön lataus ei ole mahdollista! # Order of these is important! @@ -2617,6 +2606,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}sopiva STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}kuormittunut +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} kuljetettavana kuukausittain asemalta {STATION} asemalle {STATION} ({COMMA}%{NBSP} kapasiteetista){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} kuljetettavana takaisin ({COMMA}{NBSP}% kapasiteetista) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Keskimääräinen matka-aika: {NUM}{NBSP}vrk + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Vaikutusalueen korostus STR_STATION_BUILD_COVERAGE_OFF :{BLACK}pois @@ -2625,6 +2619,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Älä ko STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Korosta ehdotetun tontin vaikutusalue STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Vastaanottaa: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Tuottaa: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Maintenance cost: {GOLD}{CURRENCY_SHORT}/v # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Liitä asema @@ -2689,13 +2684,13 @@ STR_BUILD_SIGNAL_TOGGLE_ADVANCED_SIGNAL_TOOLTIP :{BLACK}Edistyne STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Suojastusopastin (siipiopastin){}Kaikkein alkeellisin opastin, joka sallii vain yhden junan samalla osuudella kerrallaan STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}Tulo-opastin (siipiopastin){}Näyttää vihreää aina, kun yksi tai useampi seuraavista poistumisopastimista näyttää vihreää. Muutoin se näyttää punaista STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Poistumisopastin (siipiopastin){}Käyttäytyy samalla tavalla kuin suojastusopastin, mutta on välttämätön oikean valon näyttämiseen tulo- ja yhdistelmäopastimissa -STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Yhdistelmäopastin (siipiopastin){}Yhdistelmäopastin toimii yhtä aikaa tulo- ja poistumisopastimena. Tämän avulla on mahdollista luoda suuria "opastinpuita" +STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Yhdistelmäopastin (siipiopastin){}Yhdistelmäopastin toimii yhtä aikaa tulo- ja poistumisopastimena. Tämän avulla on mahdollista luoda suuria ”opastinpuita” STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}Reittiopastin (siipiopastin){}Reittiopastin varmistaa junille turvallisen reitin ja siten mahdollistaa useampien junien yhtäaikaisen liikenteen moniraiteisissa risteyksissä. Tavalliset reittiopastimet voi ohittaa takakautta STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP :{BLACK}Yksisuuntainen reittiopastin (siipiopastin){}Reittiopastin varmistaa junille turvallisen reitin ja siten mahdollistaa useampien junien yhtäaikaisen liikenteen moniraiteisissa risteyksissä. Yksisuuntaisia opastimia ei voi ohittaa takakautta STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Suojastusopastin (valo-opastin){}Kaikkein alkeellisin opastin, joka sallii vain yhden junan osuudella kerrallaan STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}Tulo-opastin (valo-opastin){}Näyttää vihreää aina, kun yksi tai useampi seuraavista poistumisopastimista näyttää vihreää. Muutoin se näyttää punaista STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Poistumisopastin (valo-opastin){}Käyttäytyy samalla tavalla kuin suojastusopastin, mutta on välttämätön oikean valon näyttämiseen tulo- ja yhdistelmäopastimissa -STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Yhdistelmäopastin (valo-opastin){}Yhdistelmäopastin toimii yhtä aikaa tulo- ja poistumisopastimena. Tämän avulla on mahdollista luoda suuria "opastinpuita" +STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Yhdistelmäopastin (valo-opastin){}Yhdistelmäopastin toimii yhtä aikaa tulo- ja poistumisopastimena. Tämän avulla on mahdollista luoda suuria ”opastinpuita” STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Reittiopastin (valo-opastin){}Reittiopastin varmistaa junille turvallisen reitin ja siten mahdollistaa useampien junien yhtäaikaisen liikenteen moniraiteisissa risteyksissä. Tavalliset reittiopastimet voi ohittaa takakautta STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Yksisuuntainen reittiopastin (valo-opastin){}Reittiopastin varmistaa junille turvallisen reitin ja siten mahdollistaa useampien junien yhtäaikaisen liikenteen moniraiteisissa risteyksissä. Yksisuuntaisia opastimia ei voi ohittaa takakautta STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Opastinten muuntaminen{}Kun tämä on valittu, olemassaolevan opastimen napsauttaminen muuntaa sen valituntyyppiseksi ja -muotoiseksi. Ctrl+napsautus vaihtaa nykyistä opastimen muotoa. Vaihto+napsautus näyttää muuntamisen kustannusarvion. @@ -2707,8 +2702,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Suurenna STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Valitse rautatiesilta STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Valitse maantiesilta STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Sillan valinta – napsauta valittua siltaa rakentaaksesi sen -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Riippusilta, terästä STR_BRIDGE_NAME_GIRDER_STEEL :Palkki, terästä STR_BRIDGE_NAME_CANTILEVER_STEEL :Ulokepalkki, terästä @@ -2812,11 +2809,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Maastonm STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Laske ruudun kulmaa. Vetäminen laskee ensimmäistä valittua kulmaa ja tasoittaa valitun alueen kulman korkeudelle. Ctrl valitsee alueen vinottain. Shift vaihtaa muokkaustilan ja kustannusarvion välillä STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Nosta ruudun kulmaa. Vetäminen nostaa ensimmäistä valittua kulmaa ja tasoittaa valitun alueen kulman korkeudelle. Ctrl valitsee alueen vinottain. Shift vaihtaa muokkaustilan ja kustannusarvion välillä STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Tasoita maata ensimmäisen valitun kulman korkeudelle. Ctrl valitsee alueen vinottain. Shift vaihtaa muokkaustilan ja kustannusarvion välillä -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Osta maata tulevaa käyttöä varten. Shift vaihtaa ostotilan ja kustannusarvion välillä +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Osta maata tulevaa käyttöä varten. Ctrl valitsee alueen vinottain. Shift vaihtaa ostotilan ja kustannusarvion välillä # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Objektin valinta -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Valitse rakennettava objekti. Shift vaihtaa rakennustilan ja kustannusarvion välillä +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Valitse rakennettava objekti. Ctrl valitsee alueen vinottain. Shift vaihtaa rakennustilan ja kustannusarvion välillä STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Valitse rakennettavan objektin luokka STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Objektin esikatselu STR_OBJECT_BUILD_SIZE :{BLACK}Koko: {GOLD}{NUM}×{NUM} ruutua @@ -2828,7 +2825,7 @@ STR_OBJECT_CLASS_TRNS :Lähettimet STR_PLANT_TREE_CAPTION :{WHITE}Puita STR_PLANT_TREE_TOOLTIP :{BLACK}Valitse istutettava puutyyppi. Jos ruudussa on jo puu, tämä lisää uusia puita riippumatta valitun puun tyypistä STR_TREES_RANDOM_TYPE :{BLACK}Sattumanvaraisia puita -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Aseta sattumanvaraisia puita. Shift vaihtaa istutustilan ja kustannusarvion välillä +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Istuta sattumanvaraisia puulajeja. Ctrl valitsee alueen vinottain. Shift vaihtaa istutustilan ja kustannusarvion välillä STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Satunnaisia puita. STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Istuta puita satunnaisesti maastoon STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Tavallinen @@ -2860,6 +2857,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Satunnai STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Perusta kunta satunnaiseen paikkaan STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Monta satunnaista kuntaa STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Täytä kartta satunnaisesti sijoitetuilla kunnilla +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Laajenna kaikkia kuntia +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Kasvata kaikkia kuntia hieman STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Kunnan nimi: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Syötä kunnan nimi @@ -3124,7 +3123,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Tietoja STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Tietoja ei ole saatavilla STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Suodatinteksti: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Suodatin: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Tiedosto on jo olemassa STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Haluatko varmasti korvata olemassaolevan tiedoston? STR_SAVELOAD_DIRECTORY :{STRING} (hakemisto) @@ -3138,6 +3137,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kartan k STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Valitse kartan koko ruutuina. Saatavilla olevien ruutujen määrä on hieman alhaisempi STR_MAPGEN_BY :{BLACK}× STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Kuntien määrä: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Kuntien nimet: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Valitse kuntien nimien tyyli STR_MAPGEN_DATE :{BLACK}Päivämäärä: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Teollisuuden määrä: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Korkein huippu: @@ -3151,13 +3152,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Aavikon STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Kasvata aavikon peittoa 10 prosentilla STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Vähennä aavikon peittoa 10 prosentilla STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}{NBSP}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Maastogeneraattori: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Maaston tyyppi: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Merenpinta: +STR_MAPGEN_SEA_LEVEL :{BLACK}Merenpinta: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Joet: STR_MAPGEN_SMOOTHNESS :{BLACK}Tasaisuus: STR_MAPGEN_VARIETY :{BLACK}Vaihtelu: STR_MAPGEN_GENERATE :{WHITE}Generoi +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF-asetukset +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Näytä NewGRF-asetukset +STR_MAPGEN_AI_SETTINGS :{BLACK}Tekoälyasetukset +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Näytä tekoälyasetukset +STR_MAPGEN_GS_SETTINGS :{BLACK}Peliskriptiasetukset +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Näytä peliskriptiasetukset + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Englantilainen +STR_MAPGEN_TOWN_NAME_FRENCH :Ranskalainen +STR_MAPGEN_TOWN_NAME_GERMAN :Saksalainen +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Englantilainen 2 +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latinalaisamerikkalainen +STR_MAPGEN_TOWN_NAME_SILLY :Hassu +STR_MAPGEN_TOWN_NAME_SWEDISH :Ruotsalainen +STR_MAPGEN_TOWN_NAME_DUTCH :Hollantilainen +STR_MAPGEN_TOWN_NAME_FINNISH :Suomalainen +STR_MAPGEN_TOWN_NAME_POLISH :Puolalainen +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovakialainen +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norjalainen +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Unkarilainen +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Itävaltalainen +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romanialainen +STR_MAPGEN_TOWN_NAME_CZECH :Tšekkiläinen +STR_MAPGEN_TOWN_NAME_SWISS :Sveitsiläinen +STR_MAPGEN_TOWN_NAME_DANISH :Tanskalainen +STR_MAPGEN_TOWN_NAME_TURKISH :Turkkilainen +STR_MAPGEN_TOWN_NAME_ITALIAN :Italialainen +STR_MAPGEN_TOWN_NAME_CATALAN :Katalonialainen # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kartan reunat: @@ -3216,7 +3245,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Tarkat N STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Käytössä olevat NewGRF-tiedostot STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Pois käytöstä olevat NewGRF-tiedostot STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Valitse valmislista: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Suodatinteksti: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Suodatin: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Lataa valittu valmislista STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Tallenna valmislistaksi STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Tallenna nykyinen lista valmislistaksi @@ -3296,17 +3325,24 @@ STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}NewGRF m # Sprite aligner window STR_SPRITE_ALIGNER_CAPTION :{WHITE}Kohdistetaan spriteä {COMMA} ({STRING}) STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}Seuraava sprite -STR_SPRITE_ALIGNER_NEXT_TOOLTIP :{BLACK}Mene seuraavaan tavalliseen spriteen ja hyppää yli pseudo-/uudelleenväritetyt/fontti- spritet ja mene alkuun kun päästään viimeiseen +STR_SPRITE_ALIGNER_NEXT_TOOLTIP :{BLACK}Siirry seuraavaan tavalliseen spriteen; mahdolliset pseudo-, uudelleenväritys- ja fonttispritet ohitetaan; viimeisen spriten jälkeen siirrytään ensimmäiseen STR_SPRITE_ALIGNER_GOTO_BUTTON :{BLACK}Mene spriteen -STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK}Mene valittuun spriteen. Jos sprite ei ole tavallinen, jatka seuraavaan tavalliseen spriteen -STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Edelinen sprite +STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK}Siirry valittuun spriteen. Jos sprite ei ole tavallinen, jatka seuraavaan tavalliseen spriteen +STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Edellinen sprite STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Jatka edelliseen tavalliseen spriteen ja hyppää yli kaikki pseudo-/uudelleenväritetyt/fontti- spritet ja mene loppuun kun päästään ensimmäiseen -STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Valitun spriten näyttö. Sijaintia ei huomioida spriteä piirrettäessä +STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Valitun spriten esitys. Siirrosta ei huomioida tätä spriteä piirrettäessä STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Liikuta spriteä ympäriinsä, muuttaen X- ja Y-sijainteja. Ctrl+napsautus siirtää spriteä kahdeksan yksikköä kerralla. + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Siirros keskitetty +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite keskitetty + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Hiusristikko + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Nollaa suhteelliset -STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Nollaa suhteelliset erotukset -STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X-erotus: {NUM}, Y-erotus: {NUM} (absoluuttinen) -STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}X-erotus: {NUM}, Y-erotus: {NUM} (suhteellinen) +STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Nollaa tämänhetkiset suhteelliset siirrokset +STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X-siirros: {NUM}, Y-siirros: {NUM} (absoluuttinen) +STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}X-siirros: {NUM}, Y-siirros: {NUM} (suhteellinen) STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Valitse sprite STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Valitse sprite ruudulta @@ -3317,18 +3353,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Varoitus: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Virhe: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Virhe: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Vakava NewGRF-virhe on tapahtunut:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF-virhe on tapahtunut:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}NewGRF ”{STRING}” on kohdannut vakavan virheen:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF ”{STRING}” on kohdannut virheen:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} ei toimi OpenTTD:n ilmoittaman TTDPatch-version kanssa -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} on TTD:n {STRING}-versiota varten -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} ja {STRING} on suunniteltu toimimaan yhdessä -STR_NEWGRF_ERROR_INVALID_PARAMETER :Virheellinen parametri: {1:STRING}: {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} tulee ladata ennen kuin {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} tulee ladata {STRING} jälkeen -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} vaatii OpenTTD:n version {STRING} tai uudemman +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} on TTD:n {2:STRING}-versiota varten +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} on suunniteltu toimimaan lisäosan {2:STRING} kanssa +STR_NEWGRF_ERROR_INVALID_PARAMETER :Virheellinen parametri lisäosalle {1:STRING}: {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} on ladattava ennen kuin {2:STRING} voidaan ladata +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} tulee ladata lisäosan {2:STRING} jälkeen +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} vaatii OpenTTD:n version {2:STRING} tai uudemman STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF-tiedosto, jonka se muuntaa STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Liian monta NewGRF:ää on ladattu -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :NewGRF:n {1:STRING} lataaminen staattisena NewGRF:nä {STRING}:n kanssa saattaa aiheuttaa nykimistä +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Lisäosan {1:STRING} lataaminen staattisena NewGRF:nä lisäosan {2:STRING} kanssa voi johtaa tahdistusvirheisiin STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Odottamaton sprite (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Tuntematon Action 0-ominaisuus {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Yritys käyttää virheellistä ID:tä (sprite {3:NUM}) @@ -3339,7 +3375,7 @@ STR_NEWGRF_ERROR_GRM_FAILED :Pyydetyt GRF-re STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{2:STRING} poisti käytöstä NewGRF:n {1:STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Virheellinen/tuntematon spriten asettelumuoto (sprite {3:NUM}) STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Liian monta elementtiä ominaisuusarvolistassa (sprite {3:NUM}, ominaisuus {4:HEX}) -STR_NEWGRF_ERROR_INDPROD_CALLBACK :Virhe teollisuuden tuotannon takaisinkutsussa (sprite {3:NUM}, "{2:STRING}") +STR_NEWGRF_ERROR_INDPROD_CALLBACK :Virheellinen teollisuuslaitoksen tuotannon takaisinkutsu (sprite {3:NUM}, ”{2:STRING}”) # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Varoitus! @@ -3460,14 +3496,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Osta yksinoikeu STR_LOCAL_AUTHORITY_ACTION_BRIBE :Lahjo viranomaisia ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Käynnistä pieni mainoskampanja hoikutellaksesi lisää matkustajia ja rahtia kuljetuspalveluihisi.{}Tämä kasvattaa tilapäisesti asemien arvioita pienellä säteellä kunnan keskustan ympärillä.{}Kustannus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Käynnistä keskikokoinen mainoskampanja houkutellaksesi lisää matkustajia ja rahtia kuljetuspalveluihisi.{}Tämä kasvattaa tilapäisesti asemien arvioita keskikokoisella säteellä kunnan keskustan ympärillä.{}Kustannus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Käynnistä suuri mainoskampanja hoikutellaksesi lisää matkustajia ja rahtia kuljetuspalveluihisi.{}Tämä kasvattaa tilapäisesti asemien arvioita suurella säteellä kunnan keskustan ympärillä.{}Kustannus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Rahoita tieverkon uudelleenrakentamista.{}Aiheuttaa huomattavaa häiriötä tieliikenteessä jopa kuuden kuukauden ajan.{}Kustannus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Rakenna patsas yhtiösi kunniaksi.{}Parantaa asemien arvioita pysyvästi tässä kunnassa.{}Kustannus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Rahoita uusien liikerakennusten rakentamista kunnassa.{}Tämä kiihdyttää tämän kunnan kasvua tilapäisesti.{}Kustannus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Osta vuoden yksinoikeudet kunnan liikennöintiin.{}Tällöin paikallisviranomaiset eivät salli matkustajien ja rahdin käyttää kilpailijoittesi asemia.{}Kustannus: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Lahjo viranomaisia lisätäksesi arviotasi; rangaistus voi olla kuitenkin suuri, jos jäät kiinni.{}Kustannus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Käynnistä pieni mainoskampanja houkutellaksesi lisää matkustajia ja rahtia kuljetuspalveluihisi.{}Tämä kasvattaa tilapäisesti asemien arvioita pienellä säteellä kunnan keskustan ympärillä.{}{POP_COLOUR}Kustannus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Käynnistä keskikokoinen mainoskampanja houkutellaksesi lisää matkustajia ja rahtia kuljetuspalveluihisi.{}Tämä kasvattaa tilapäisesti asemien arvioita keskikokoisella säteellä kunnan keskustan ympärillä.{}{POP_COLOUR}Kustannus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Käynnistä suuri mainoskampanja hoikutellaksesi lisää matkustajia ja rahtia kuljetuspalveluihisi.{}Tämä kasvattaa tilapäisesti asemien arvioita suurella säteellä kunnan keskustan ympärillä.{}{POP_COLOUR}Kustannus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Rahoita tieverkon uudelleenrakentamista.{}Aiheuttaa huomattavaa häiriötä tieliikenteessä jopa kuuden kuukauden ajan.{}{POP_COLOUR}Kustannus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Rakenna patsas yhtiösi kunniaksi.{}Parantaa asemien arvioita pysyvästi tässä kunnassa.{}{POP_COLOUR}Kustannus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Rahoita uusien rakennusten rakentamista kunnassa.{}Tämä kiihdyttää tämän kunnan kasvua tilapäisesti.{}{POP_COLOUR}Kustannus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Osta vuodeksi yksinoikeudet kunnan liikennöintiin.{}Tällöin paikallisviranomaiset eivät salli matkustajien ja rahdin käyttää kilpailijoittesi asemia.{}{POP_COLOUR}Kustannus: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Lahjo viranomaisia lisätäksesi arviotasi; rangaistus voi kuitenkin olla ankara, jos jäät kiinni.{}{POP_COLOUR}Kustannus: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Tavoitteet @@ -3640,15 +3676,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Laivat STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Lainan korko STR_FINANCES_SECTION_OTHER :{GOLD}Muut +STR_FINANCES_TOTAL_CAPTION :{WHITE}Yhteensä STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Puhdas voitto +STR_FINANCES_PROFIT :{WHITE}Tuotto STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Tilin saldo STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Omat varat STR_FINANCES_LOAN_TITLE :{WHITE}Laina STR_FINANCES_INTEREST_RATE :{WHITE}Lainan korko: {BLACK}{NUM}{NBSP}% STR_FINANCES_MAX_LOAN :{WHITE}Laina enintään: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Nosta lainaa {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Ota lisää lainaa. Ctrl+napsautus nostaa lainaa niin paljon kuin mahdollista. STR_FINANCES_REPAY_BUTTON :{BLACK}Lyhennä lainaa {CURRENCY_LONG} @@ -3749,7 +3788,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Tuottaa: STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Tarvitsee: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} odottamassa{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Muokkaa tuotantoa (8:n kerroin, 2040:een asti) @@ -3779,6 +3818,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Ohjaa ka STR_VEHICLE_LIST_REPLACE_VEHICLES :Korvaa kulkuneuvoja STR_VEHICLE_LIST_SEND_FOR_SERVICING :Lähetä huoltoon STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Tuotto tänä vuonna: {CURRENCY_LONG} (viime vuonna: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Lähetä varikolle STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Lähetä varikolle @@ -3866,10 +3907,15 @@ STR_PURCHASE_INFO_ALL_TYPES :Kaikki rahtityy STR_PURCHASE_INFO_NONE :Ei mitään STR_PURCHASE_INFO_ENGINES_ONLY :Vain veturit STR_PURCHASE_INFO_ALL_BUT :Kaikki paitsi {CARGO_LIST} -STR_PURCHASE_INFO_MAX_TE :{BLACK}Suurin vetovoima: {GOLD}{FORCE} +STR_PURCHASE_INFO_MAX_TE :{BLACK}Maksimivetovoima: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Toimintasäde: {GOLD}{COMMA} ruutua STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Ilma-alustyyppi: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Kaikki rahtityypit +STR_CARGO_TYPE_FILTER_FREIGHT :Rahti +STR_CARGO_TYPE_FILTER_NONE :Ei mikään + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Raideliikennevälineiden valintaluettelo. Napsauta kulkuneuvoa saadaksesi lisää tietoa. Ctrl+napsautus näyttää tai piilottaa kulkuneuvon tyypin. STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Ajoneuvojen valintaluettelo. Napsauta ajoneuvoa saadaksesi lisää tietoja. Ctrl+napsautus näyttää tai piilottaa ajoneuvon tyypin. @@ -3948,7 +3994,7 @@ STR_DEPOT_VEHICLE_TOOLTIP_CHAIN :{BLACK}{NUM} ku STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} ({CARGO_SHORT}) ###length VEHICLE_TYPES -STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Junat - vedä kulkuneuvoa vasemmalla hiiren painikkella lisätäksesi/poistaaksesi junasta, oikealla painikkeella lisätietoja. Pidä pohjassa Ctrl-näppäintä toteuttaaksesi molemmat toiminnot seuraavaan ketjuun +STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Junat – vedä kulkuneuvoa vasemmalla hiiren painikkella lisätäksesi/poistaaksesi junasta, oikealla painikkeella lisätietoja. Pidä pohjassa Ctrl-näppäintä toteuttaaksesi molemmat toiminnot seuraavaan ketjuun STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Ajoneuvot – napsauta ajoneuvoa oikealla hiiren painikkeella saadaksesi tietoja STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}Laivat – napsauta laivaa oikealla hiiren painikkeella saadaksesi tietoja. STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Lentokoneet – napsauta lentokonetta oikealla hiiren painikkeella saadaksesi tietoja @@ -4038,12 +4084,12 @@ STR_ENGINE_PREVIEW_AIRCRAFT :ilma-alus STR_ENGINE_PREVIEW_SHIP :laiva STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Hinta: {CURRENCY_LONG} Paino: {WEIGHT_SHORT}{}Nopeus: {VELOCITY} Teho: {POWER}{}Käyttökustannukset: {CURRENCY_LONG}/vuosi{}Kapasiteetti: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Hinta: {CURRENCY_LONG} Paino: {WEIGHT_SHORT}{}Nopeus: {VELOCITY} Teho: {POWER} Maks. vetovoima: {6:FORCE}{}Käyttökustannukset: {4:CURRENCY_LONG}/v{}Kapasiteetti: {5:CARGO_LONG} -STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Hinta: {CURRENCY_LONG} Maks. nopeus: {VELOCITY}{}Kapasiteetti: {CARGO_LONG}{}Käyttökustannukset: {CURRENCY_LONG}/v -STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Hinta: {CURRENCY_LONG} Maks. nopeus: {VELOCITY}{}Ilma-alustyyppi: {STRING}{}Kapasiteetti: {CARGO_LONG}, {CARGO_LONG}{}Käyttökustannukset: {CURRENCY_LONG}/v -STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Hinta: {CURRENCY_LONG} Maks. nopeus: {VELOCITY}{}Ilma-alustyyppi: {STRING}{}Kapasiteetti: {CARGO_LONG}{}Käyttökustannukset: {CURRENCY_LONG}/v -STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}Hinta: {CURRENCY_LONG} Maks. nopeus: {VELOCITY}{}Ilma-alustyyppi: {STRING} Toimintamatka: {COMMA} ruutua{}Kapasiteetti: {CARGO_LONG}, {CARGO_LONG}{}Käyttökustannukset: {CURRENCY_LONG}/v -STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :{BLACK}Hinta: {CURRENCY_LONG} Maks. nopeus: {VELOCITY}{}Ilma-alustyyppi: {STRING} Toimintamatka: {COMMA} ruutua{}Kapasiteetti: {CARGO_LONG}{}Käyttökustannukset: {CURRENCY_LONG}/v +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Hinta: {0:CURRENCY_LONG} Paino: {1:WEIGHT_SHORT}{}Nopeus: {2:VELOCITY} Teho: {3:POWER} Maksimivetovoima: {6:FORCE}{}Käyttökustannukset: {4:CURRENCY_LONG}/yr{}Kapasiteetti: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Hinta: {CURRENCY_LONG} Huippunopeus: {VELOCITY}{}Kapasiteetti: {CARGO_LONG}{}Käyttökustannukset: {CURRENCY_LONG}/v +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Hinta: {CURRENCY_LONG} Huippunopeus: {VELOCITY}{}Ilma-alustyyppi: {STRING}{}Kapasiteetti: {CARGO_LONG}, {CARGO_LONG}{}Käyttökustannukset: {CURRENCY_LONG}/v +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Hinta: {CURRENCY_LONG} Huippunopeus: {VELOCITY}{}Ilma-alustyyppi: {STRING}{}Kapasiteetti: {CARGO_LONG}{}Käyttökustannukset: {CURRENCY_LONG}/v +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}Hinta: {CURRENCY_LONG} Huippunopeus: {VELOCITY}{}Ilma-alustyyppi: {STRING} Toimintamatka: {COMMA} ruutua{}Kapasiteetti: {CARGO_LONG}, {CARGO_LONG}{}Käyttökustannukset: {CURRENCY_LONG}/v +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :{BLACK}Hinta: {CURRENCY_LONG} Huippunopeus: {VELOCITY}{}Ilma-alustyyppi: {STRING} Toimintamatka: {COMMA} ruutua{}Kapasiteetti: {CARGO_LONG}{}Käyttökustannukset: {CURRENCY_LONG}/v # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}Korvaa {STRING} – {STRING} @@ -4193,16 +4239,17 @@ STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} vu STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Huippunopeus: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Huippunopeus: {LTBLUE}{VELOCITY} {BLACK}Ilma-alustyyppi: {LTBLUE}{STRING} STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Huippunopeus: {LTBLUE}{VELOCITY} {BLACK}Ilma-alustyyppi: {LTBLUE}{STRING} {BLACK}Toimintamatka: {LTBLUE}{COMMA} ruutua -STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Paino: {LTBLUE}{WEIGHT_SHORT} {BLACK}Teho: {LTBLUE}{POWER}{BLACK} Maks. nopeus: {LTBLUE}{VELOCITY} -STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Paino: {LTBLUE}{WEIGHT_SHORT} {BLACK}Teho: {LTBLUE}{POWER}{BLACK} Maks. nopeus: {LTBLUE}{VELOCITY} {BLACK}Maks. vetovoima: {LTBLUE}{FORCE} +STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Paino: {LTBLUE}{WEIGHT_SHORT} {BLACK}Teho: {LTBLUE}{POWER}{BLACK} Huippunopeus: {LTBLUE}{VELOCITY} +STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Paino: {LTBLUE}{WEIGHT_SHORT} {BLACK}Teho: {LTBLUE}{POWER}{BLACK} Huippunopeus: {LTBLUE}{VELOCITY} {BLACK}Maksimivetovoima: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Tuotto tänä vuonna: {LTBLUE}{CURRENCY_LONG} (viime vuonna: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Tuotto tänä vuonna: {LTBLUE}{CURRENCY_LONG} (viime vuonna: {CURRENCY_LONG}) {BLACK}Vähimmäissuorituskyky: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Luotettavuus: {LTBLUE}{COMMA}{NBSP}% {BLACK}Hajoamiset viime huollon jälkeen: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Rakennettu: {LTBLUE}{NUM}{BLACK} Arvo: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Kapasiteetti: {LTBLUE}-{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapasiteetti: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapasiteetti: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapasiteetti: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapasiteetti: {LTBLUE}{0:CARGO_LONG}{3:STRING} (×{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Kapasiteetti: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Siirron arvo: {LTBLUE}{CURRENCY_LONG} @@ -4471,22 +4518,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Aloitusp STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Valitse päivämäärä aikataulun aloitusajankohdaksi. Ctrl+napsautus levittää kaikki tämän käskyjoukon jakavat kulkuneuvot tasaisesti niiden keskinäisen järjestyksen mukaan, mikäli käskyjoukko on kokonaan aikataulutettu STR_TIMETABLE_CHANGE_TIME :{BLACK}Muuta aikaa -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Aseta kuinka kauan käskyn tulisi kestää +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Muuta aikaa, jonka valitun käskyn tulisi kestää. Ctrl+napsautus asettaa keston kaikille käskyille STR_TIMETABLE_CLEAR_TIME :{BLACK}Nollaa aika -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Nollaa tämän rivin aika +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Nollaa valitun käskyn keston. Ctrl+napsautus nollaa kaikkien käskyjen kestot STR_TIMETABLE_CHANGE_SPEED :{BLACK}Muuta nopeusrajoitusta -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Muuta valitun määräyksen suurinta sallittua nopeutta +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Muuta suurinta sallittua nopeutta valitulle käskylle. Ctrl+napsautus asettaa nopeusrajoituksen kaikille käskyille STR_TIMETABLE_CLEAR_SPEED :{BLACK}Tyhjennä nopeusrajoitus -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Tyhjennä valitun määräyksen suurin sallittu nopeus +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Poista suurin sallittu nopeus valitulta käskyltä. Ctrl+napsautus poistaa kaikkien käskyjen nopeusrajoitukset STR_TIMETABLE_RESET_LATENESS :{BLACK}Nollaa myöhästymislaskuri -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Nollaa myöhästymislaskuri, jotta vaunu olisi taas aikataulussa +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Nollaa myöhästymislaskuri, jotta kulkuneuvo olisi taas aikataulussa. Ctrl+napsautus nollaa koko ryhmän, minkä jälkeen eniten myöhässä ollut kulkuneuvo on aikataulussa ja muut ovat etuajassa STR_TIMETABLE_AUTOFILL :{BLACK}Automaattinen -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Täytä aikataulu automaattisesti seuraavan matkan arvoilla (Ctrl+napsautus: yritä säilyttää odotusajat) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Täytä aikataulu automaattisesti seuraavan matkan arvoilla. Ctrl+napsautus: yritä säilyttää odotusajat STR_TIMETABLE_EXPECTED :{BLACK}Odotettu STR_TIMETABLE_SCHEDULED :{BLACK}Aikataulu @@ -4530,12 +4577,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Yksi kä STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Tekoälyn/peliskriptin virheenjäljitysikkuna on vain palvelimen käytettävissä # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Tekoälyn/peliskriptin määritteet +STR_AI_CONFIG_CAPTION_AI :{WHITE}Tekoälyasetukset +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Peliskriptiasetukset STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Seuraavassa pelissä ladattava peliskripti STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Seuraavassa pelissä ladattavat tekoälyt STR_AI_CONFIG_HUMAN_PLAYER :Ihmispelaaja STR_AI_CONFIG_RANDOM_AI :Sattumanvarainen tekoäly STR_AI_CONFIG_NONE :(ei mitään) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Vastustajien enimmäismäärä: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Siirrä ylöspäin STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Siirrä valittua tekoälyä ylöspäin listalla @@ -4543,20 +4592,19 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Siirrä STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Siirrä valittua tekoälyä alaspäin listalla STR_AI_CONFIG_GAMESCRIPT :{SILVER}Peliskripti +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametrit STR_AI_CONFIG_AI :{SILVER}Tekoälyt -STR_AI_CONFIG_CHANGE :{BLACK}Valitse {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :Tekoäly -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Peliskripti +STR_AI_CONFIG_CHANGE_AI :{BLACK}Valitse tekoäly +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Valitse peliskripti STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Lataa toinen skripti STR_AI_CONFIG_CONFIGURE :{BLACK}Määritä STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Määritä skriptin parametrit # Available AIs window -STR_AI_LIST_CAPTION :{WHITE}Saatavilla {STRING} -STR_AI_LIST_CAPTION_AI :Tekoälyt -STR_AI_LIST_CAPTION_GAMESCRIPT :Peliskriptit +STR_AI_LIST_CAPTION :{WHITE}Saatavilla olevat {STRING} +STR_AI_LIST_CAPTION_AI :tekoälyt +STR_AI_LIST_CAPTION_GAMESCRIPT :peliskriptit STR_AI_LIST_TOOLTIP :{BLACK}Napsauta valitaksesi skriptin STR_AI_LIST_AUTHOR :{LTBLUE}Tekijä: {ORANGE}{STRING} @@ -4576,7 +4624,7 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Koko kar STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Korkeuskartan kuvakaappaus STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Pienoiskartan kuvakaappaus -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametrit STR_AI_SETTINGS_CAPTION_AI :Tekoäly STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Peliskripti @@ -4743,6 +4791,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... liik STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Teollisuuslaitoksia ei voi luoda... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}{STRING}: tähän ei voi rakentaa... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Teollisuustyyppiä ei voi rakentaa tähän... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Ei voida koekaivaa… STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... liian lähellä toista teollisuuslaitosta STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... kunta pitää perustaa ensin STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... vain yksi on sallittu kuntaa kohden @@ -4757,6 +4806,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... mets STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... voidaan rakentaa vain lumirajan yläpuolelle STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... voidaan rakentaa vain lumirajan alapuolelle +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Rahoittamasi koekaivaus epäonnistui; yritä uudelleen +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Ei ollut sopivia paikkoja tämän teollisuuslaitoksen koekaivauksille STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Ei ollut sopivia paikkoja ”{STRING}”-teollisuuslaitoksille STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Muuta kartan parametreja saadaksesi paremman kartan @@ -4924,6 +4975,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objekti STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... yhtiön päärakennus on tiellä. STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Maa-aluetta ei voi hankkia... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... omistat sen jo! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}… objektien rakentamisen raja saavutettu # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Ei voi luoda ryhmää. @@ -4996,6 +5048,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Huoltov STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... kulkuneuvo on tuhoutunut +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}… kaikki kulkuneuvot eivät ole identtisiä + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Yhtään kulkuneuvoa ei ole saatavilla STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Muuta NewGRF-asetuksiasi STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Kulkuneuvoja ei ole vielä saatavilla @@ -5022,6 +5076,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Tähän STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... kulkuneuvo ei pääse kaikille asemille STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... kulkuneuvo ei pääse tälle asemalle STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... kulkuneuvo, jonka kanssa käskyt on jaettu, ei pääse tälle asemalle +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}… kaikkien kulkuneuvojen käskyt eivät ole samat +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}… kaikki kulkuneuvot eivät jaa käskyjä STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Käskyjä ei voida jakaa... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Käskyjen jakamista ei voida lopettaa... @@ -5029,6 +5085,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Käskyj STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... liian kaukana edellisestä määränpäästä STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... ilma-aluksen toimintasäde ei riitä +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Rautatieasemaa ei ole +STR_ERROR_NO_BUS_STATION :{WHITE}Linja-autopysäkkiä ei ole +STR_ERROR_NO_TRUCK_STATION :{WHITE}Lastauslaituria ei ole +STR_ERROR_NO_DOCK :{WHITE}Satamaa ei ole +STR_ERROR_NO_AIRPORT :{WHITE}Lento-/helikopterikenttää ei ole +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Ei ole pysäkkejä sopivalla tien tyypillä +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Ei ole pysäkkejä sopivalla raitiotien tyypillä +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Ei ole nivelajoneuvoille sopivia pysäkkejä.{}Nivelletyt ajoneuvot vaativat pysäkin, joka ei ole kääntöpysäkki vaan läpiajettava +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Tämä lentokone ei voi laskeutua tälle helikopterikentälle +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Tämä helikopteri ei voi laskeutua tälle lentokentälle +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Rautatien reittipistettä ei ole +STR_ERROR_NO_BUOY :{WHITE}Poijua ei ole + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Ei voi asettaa aikataulua. STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Kulkuneuvo voi odottaa vain asemalla diff --git a/src/lang/french.txt b/src/lang/french.txt index e156453a932a0..42478487bf648 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}ch STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{G=f}{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{G=f}{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -227,8 +237,8 @@ STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Filtre{NBSP}: -STR_LIST_FILTER_OSKTITLE :{BLACK}Entrer le filtre -STR_LIST_FILTER_TOOLTIP :{BLACK}Entrer un mot-clé pour filtrer la liste +STR_LIST_FILTER_OSKTITLE :{BLACK}Entrer un ou plusieurs mot-clés pour filtrer la liste +STR_LIST_FILTER_TOOLTIP :{BLACK}Entrer un ou plusieurs mot-clés pour filtrer la liste STR_TOOLTIP_GROUP_ORDER :{BLACK}Ordre de regroupement STR_TOOLTIP_SORT_ORDER :{BLACK}Choisir l'ordre de tri (croissant/décroissant) @@ -377,9 +387,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Créatio STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Création des industries STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Construction routière STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Construction de tramway -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Planter des arbres.{}Shift pour afficher seulement le coût estimé. +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Planter des arbres.{}Ctrl pour sélectionner en diagonale.{}Shift pour afficher seulement le coût estimé. STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Placer un panneau -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Placer un objet.{}Shift pour afficher seulement le coût estimé. +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Placer un objet.{}Ctrl pour sélectionner en diagonale.{}Shift pour afficher seulement le coût estimé. # Scenario editor file menu ###length 7 @@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Quitter # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Options du Jeu STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Paramètres -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Configuration des scripts +STR_SETTINGS_MENU_AI_SETTINGS :Configuration des IAs +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Configuration du script de jeu STR_SETTINGS_MENU_NEWGRF_SETTINGS :Paramètres NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Options de transparence STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Afficher le nom des villes @@ -966,36 +977,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Roupie indienne STR_GAME_OPTIONS_CURRENCY_IDR :Roupie indonésienne (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaysian Ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Conduite à gauche -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Conduite à droite - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nom des villes{NBSP}: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Sélectionner la nationalité des noms des villes - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Anglais (originaux) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Français -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Allemands -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Anglais (additionnels) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latino-américains -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Drôles -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Suédois -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Hollandais -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandais -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polonais -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovaques -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norvégiens -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hongrois -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Autrichiens -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Roumains -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tchèques -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Suisses -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danois -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turcs -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiens -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalans - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Sauvegarde automatique STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Sélectionner l'intervalle de temps entre les sauvegardes automatiques @@ -1028,21 +1009,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Cochez c STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Pilote actif{NBSP}: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Taille d'interface -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Choisir la taille d'élément d'interface à utiliser +STR_GAME_OPTIONS_GUI_SCALE_FRAME :Taille de l'interface +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Faites glisser la souris pour définir la taille de l'interface. Maintenir Ctrl pour un réglage en continu +STR_GAME_OPTIONS_GUI_SCALE_AUTO :détection automatique de la taille +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Cochez cette case pour détecter automatiquement la taille de l'interface -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(auto-détection) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Taille double -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Taille quadruple +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Mettre à l’échelle les bordures +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Cochez cette case pour mettre les bordures à l'échelle avec la taille de l'interface -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Taille de police -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Choisir la taille de police d'interface à utiliser - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(auto-détection) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Taille double -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Taille quadruple +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :x5 STR_GAME_OPTIONS_GRAPHICS :{BLACK} Graphiques @@ -1094,8 +1073,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Prévis STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10{NBSP}000 livres (£) dans cette devise STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Changer les paramètres de la devise personnalisée -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Nombre maximal de concurrents{NBSP}: {ORANGE}{COMMA} - STR_NONE :Aucune STR_FUNDING_ONLY :Financement uniquement STR_MINIMAL :Minimal @@ -1145,6 +1122,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Environnement «{NBSP}Tempéré{NBSP}» +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Environnement «{NBSP}Arctique{NBSP}» +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Environnement «{NBSP}Tropical{NBSP}» +STR_CLIMATE_TOYLAND_LANDSCAPE :Environnement «{NBSP}Monde des jouets{NBSP}» + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Très plat STR_TERRAIN_TYPE_FLAT :Plat @@ -1224,6 +1207,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :À droite STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Emprunt initial maximum{NBSP}: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Montant maximum qu'une compagnie peut emprunter (sans tenir compte de l'inflation) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Pas d'emprunt {RED}Nécessite un script de jeu qui fournit les fonds initiaux STR_CONFIG_SETTING_INTEREST_RATE :Taux d'intérêt{NBSP}: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Taux d’intérêt de l'emprunt{NBSP}; contrôle également l'inflation si activé @@ -1450,6 +1436,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Épaisseur de l STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Afficher le nom du NewGRF dans la fenêtre d'achat des véhicules{NBSP}: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Ajoute une ligne à la fenêtre d'achat des véhicules, montrant de quel NewGRF provient le véhicule sélectionné. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Afficher les cargaisons que peuvent transporter les véhicules dans les fenêtres de liste {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Quand il est actif, ce qu'un véhicule peut transporter est affiché au dessus de lui dans les listes de véhicules STR_CONFIG_SETTING_LANDSCAPE :Paysage{NBSP}: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Les paysages définissent les scénarios de jouabilité classique avec différentes marchandises et exigences pour la croissance des villes. Les NewGRFs et les scripts de jeux autorisent cependant un contrôle plus fin @@ -1504,6 +1492,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Amélioré STR_CONFIG_SETTING_ROAD_SIDE :Véhicules routiers{NBSP}: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Choisir le côté de circulation +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Conduite à gauche +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Conduite à droite + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotation de la carte d'altitude{NBSP}: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Anti-horaire @@ -1937,13 +1929,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Prendre {STRING STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Durée maximale (en jours) du recalcul d'une composante du graphe. À chaque itération, un thread est initié, qui a une durée maximale définie par ce réglage. Plus celui-ci est court, plus la probabilité que le thread ne termine pas sa tâche à temps est élevée. Le jeu s'interrompt alors jusqu'à la fin du recalcul ("lag"). Plus le réglage est long, et moins rapidement la distribution sera réactualisée en cas de changement de routes. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Type de distribution pour les passagers{NBSP}: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symétrique" signifie qu'autant de passagers iront d'une station A vers une station B, que de la station B vers la station A. "asymétrique" signifie qu'un nombre arbitraire de passagers peut être envoyé dans les deux directions. "manuel" signifie qu'aucune distribution n'est mise en place pour les passagers. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symétrique" signifie qu'autant de passagers iront d'une station A vers une station B, que de la station B vers la station A. "Asymétrique" signifie qu'un nombre arbitraire de passagers peut être envoyé dans les deux directions. "Manuel" signifie qu'aucune distribution n'est mise en place pour les passagers. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Type de distribution pour le courrier{NBSP}: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"symétrique" signifie qu'autant de courrier ira d'une station A vers une station B, que de la station B vers la station A. "asymétrique" signifie qu'une quantité arbitraire de courrier peut être envoyée dans les deux directions. "manuel" signifie qu'aucune distribution n'est mise en place pour le courrier. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Symétrique" signifie qu'autant de courrier ira d'une station A vers une station B, que de la station B vers la station A. "Asymétrique" signifie qu'une quantité arbitraire de courrier peut être envoyée dans les deux directions. "Manuel" signifie qu'aucune distribution n'est mise en place pour le courrier. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Type de distribution pour les cargaisons de classe ARMOURED{NBSP}: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La classe de cargaison ARMOURED contient des biens de valeur dans les climats tempéré, des diamants dans le climat subtropical, et de l'or dans le climat subarctique. Les NewGRFs peuvent changer ça. "symétrique" signifie qu'autant de ces cargaisons iront d'une station A vers une station B, que de la station B vers la station A. "asymétrique" signifie qu'une quantité arbitraire de ces cargaisons peut être envoyée dans les deux directions. "manuel" signifie qu'aucune distribution n'est mise en place pour ces cargaisons. Il est conseillé de choisir "asymétrique" ou "manuel" dans le climat subarctique, car les banques n'enverront pas d'or en retour vers les mines d'or. Dans les climats tempéré et subtropical, on peut choisir aussi "symétrique", car les banques peuvent renvoyer en retour des biens de valeurs aux banques qui en envoient à l'origine. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La classe de cargaison ARMOURED contient des biens de valeur dans les climats tempéré, des diamants dans le climat subtropical, et de l'or dans le climat subarctique. Les NewGRFs peuvent changer ça. "Symétrique" signifie qu'autant de ces cargaisons iront d'une station A vers une station B, que de la station B vers la station A. "Asymétrique" signifie qu'une quantité arbitraire de ces cargaisons peut être envoyée dans les deux directions. "Manuel" signifie qu'aucune distribution n'est mise en place pour ces cargaisons. Il est conseillé de choisir "asymétrique" ou "manuel" dans les climats subarctique ou subtropical, car les banques ne font que recevoir des marchandises dans ces climats. Dans le climat tempéré, on peut choisir aussi "symétrique", car les banques peuvent renvoyer en retour des biens de valeurs aux banques qui en envoient à l'origine. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Type de distribution pour les autres classes de cargaison{NBSP}: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asymétrique" signifie qu'une quantité arbitraire de cargaison peut être envoyée dans les deux directions. "manuel" signifie qu'aucune distribution n'est mise en place pour la cargaison. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asymétrique" signifie qu'une quantité arbitraire de cargaison peut être envoyée dans les deux directions. "Manuel" signifie qu'aucune distribution n'est mise en place pour la cargaison. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuel STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asymétrique @@ -2038,7 +2030,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Demi-tour autom STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Autoriser les trains a faire demi-tour à un signal, si ils attendent depuis un long moment ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(recommandé) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(recommandé) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Changer la valeur du paramètre @@ -2069,19 +2061,20 @@ STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE} ... auc # Intro window STR_INTRO_CAPTION :{WHITE}OpenTTD {REV} -STR_INTRO_NEW_GAME :{BLACK}Nouvelle partie +STR_INTRO_NEW_GAME :{BLACK}Jouer une nouvelle partie STR_INTRO_LOAD_GAME :{BLACK}Charger une partie STR_INTRO_PLAY_SCENARIO :{BLACK}Jouer un scénario STR_INTRO_PLAY_HEIGHTMAP :{BLACK}Jouer une carte d'altitude STR_INTRO_SCENARIO_EDITOR :{BLACK}Éditeur de scénario -STR_INTRO_MULTIPLAYER :{BLACK}Mode multijoueurs +STR_INTRO_MULTIPLAYER :{BLACK}Jouer en multijoueur -STR_INTRO_GAME_OPTIONS :{BLACK}Options +STR_INTRO_GAME_OPTIONS :{BLACK}Options globales STR_INTRO_HIGHSCORE :{BLACK}Meilleurs scores -STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Paramètres +STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Paramètres de jeu STR_INTRO_NEWGRF_SETTINGS :{BLACK}Paramètres NewGRF -STR_INTRO_ONLINE_CONTENT :{BLACK}Vérifier le contenu en ligne -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Paramètres des IA/script jeu +STR_INTRO_ONLINE_CONTENT :{BLACK}Contenue additionnel en ligne +STR_INTRO_AI_SETTINGS :{BLACK}Configuration des IAs +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Configuration du script de jeu STR_INTRO_QUIT :{BLACK}Quitter STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Démarrer une nouvelle partie. Ctrl-clic pour passer outre la configuration du terrain. @@ -2101,7 +2094,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Afficher STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Afficher les paramètres STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Afficher la configuration des NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Vérifier les contenus nouveaux ou mis à jour téléchargeables -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Afficher la configuration des scripts +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Afficher la configuration des IAs +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Afficher la configuration du script de jeu STR_INTRO_TOOLTIP_QUIT :{BLACK}Quitter OpenTTD STR_INTRO_BASESET :{BLACK}{NUM} sprite{P "" s} manque{P "" "nt"} dans les graphiques de base actuellement sélectionnés. Veuillez vérifier les mises à jours pour les graphiques de base. @@ -2133,12 +2127,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Changer STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Modifier l'année courante STR_CHEAT_SETUP_PROD :{LTBLUE}Permettre la modification des valeurs de production{NBSP}: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Environnement «{NBSP}Tempéré{NBSP}» -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Environnement «{NBSP}Arctique{NBSP}» -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Environnement «{NBSP}Tropical{NBSP}» -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Environnement «{NBSP}Monde des jouets{NBSP}» - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Couleur @@ -2242,18 +2230,18 @@ STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :Invitation uniq # Network server list STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multijoueurs -STR_NETWORK_SERVER_LIST_PLAYER_NAME :{BLACK}Nom du joueur{NBSP}: +STR_NETWORK_SERVER_LIST_PLAYER_NAME :{BLACK}Votre nom de joueur : STR_NETWORK_SERVER_LIST_ENTER_NAME_TOOLTIP :{BLACK}Ceci est le nom sous lequel vous serez connu des autres joueurs -STR_NETWORK_SERVER_LIST_GAME_NAME :{BLACK}Nom +STR_NETWORK_SERVER_LIST_GAME_NAME :{BLACK}Nom de la partie STR_NETWORK_SERVER_LIST_GAME_NAME_TOOLTIP :{BLACK}Nom de la partie STR_NETWORK_SERVER_LIST_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA} -STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION :{BLACK}Clients +STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION :{BLACK}Clients - Compagnies STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION_TOOLTIP :{BLACK}Clients en ligne / clients max.{}Compagnies en ligne / compagnies max. STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT :{BLACK}{COMMA}{NBSP}×{NBSP}{COMMA} STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION :{BLACK}Taille STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION_TOOLTIP :{BLACK}Taille de la carte{}Cliquer pour trier par surface -STR_NETWORK_SERVER_LIST_DATE_CAPTION :{BLACK}Date +STR_NETWORK_SERVER_LIST_DATE_CAPTION :{BLACK}Année en jeu STR_NETWORK_SERVER_LIST_DATE_CAPTION_TOOLTIP :{BLACK}Date courante STR_NETWORK_SERVER_LIST_YEARS_CAPTION :{BLACK}Années STR_NETWORK_SERVER_LIST_YEARS_CAPTION_TOOLTIP :{BLACK}Nombre d'années{}écoulées dans le jeu @@ -2287,11 +2275,11 @@ STR_NETWORK_SERVER_LIST_REFRESH_TOOLTIP :{BLACK}Actualis STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET :{BLACK}Recherche internet STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}Rechercher des serveurs publiés sur internet -STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}Recherche LAN +STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN :{BLACK}Recherche sur le réseau local STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}Rechercher des serveurs sur le réseau local STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Ajouter un serveur STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Ajouter un serveur à la liste. Ce peut être soit une adresse de serveur, soit un code d'invitation -STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Héberger/créer un serveur de jeu +STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Créer un serveur de jeu STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Démarrer son propre serveur, sur cet ordinateur-ci STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Entrer votre nom @@ -2371,7 +2359,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nouvelle compa STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Créer une nouvelle compagnie et la rejoindre STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}C'est vous STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}C'est l'hôte du jeu -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} compagnie{P "" s} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} - {NUM}/{NUM} companie{P "" s} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Actuellement, le nombre de clients connectés, le nombre d'entreprises et le nombre d'entreprises maximum autorisées par l'administrateur du serveur est atteint. # Matches ConnectionType ###length 5 @@ -2498,13 +2487,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :en attente du r STR_NETWORK_MESSAGE_CLIENT_LEAVING :départ STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} a rejoint la partie -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} a rejoint la partie (Client n°{NBSP}{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} a rejoint la compagnie n°{NBSP}{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} a rejoint la partie (Client n°{NBSP}{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} a rejoint la compagnie n°{NBSP}{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} a rejoint les spectateurs -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} a lancé une nouvelle compagnie (n°{NBSP}{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} a quitté la partie ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} a lancé une nouvelle compagnie (n°{NBSP}{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} a quitté la partie ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} a changé son nom en {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} a donné {2:CURRENCY_LONG} à {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} a donné {2:CURRENCY_LONG} à {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Le serveur a fermé la session STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Le serveur redémarre...{}Veuillez patienter... STR_NETWORK_MESSAGE_KICKED :*** {STRING} a été exclu. Raison{NBSP}: ({STRING}) @@ -2618,6 +2607,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}saturé STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}surchargé +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} à transporter par mois de {STATION} à {STATION} ({COMMA}% de la capacité){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} à transporter en retour ({COMMA}% de la capacité) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Temps de trajet moyen{NBSP}: {NUM}{NBSP}jour{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Afficher la zone couverte STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Désactivé @@ -2626,6 +2620,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Ne pas a STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Afficher la zone couverte STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Accepte{NBSP}: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Fournit{NBSP}: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Coût d'entretien{NBSP}: {GOLD}{CURRENCY_SHORT}/an # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Joindre une station @@ -2708,8 +2703,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Augmente STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Choisir un pont ferroviaire STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Choisir un pont routier STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Sélection de pont - Cliquer sur le type de pont désiré pour le construire. -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Suspendu en acier STR_BRIDGE_NAME_GIRDER_STEEL :À poutres en acier STR_BRIDGE_NAME_CANTILEVER_STEEL :Porte-à-faux en acier @@ -2813,11 +2810,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Manipula STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Abaisser le terrain.{}Glisser abaisse le premier coin sélectionné et nivelle la zone sélectionnée à cette nouvelle hauteur.{}Ctrl pour sélectionner en diagonale.{}Shift pour afficher seulement le coût estimé. STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Élever le terrain.{}Glisser élève le premier coin sélectionné et nivelle la zone sélectionnée à cette nouvelle hauteur.{}Ctrl pour sélectionner en diagonale.{}Shift pour afficher seulement le coût estimé. STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Niveler le terrain à la hauteur du premier coin sélectionné.{}Ctrl pour sélectionner en diagonale.{}Shift pour afficher seulement le coût estimé. -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Acheter le terrain pour une utilisation ultérieure.{}Shift pour afficher seulement le coût estimé. +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Acheter le terrain pour une utilisation ultérieure.{}Ctrl pour sélectionner en diagonale.{}Shift pour afficher seulement le coût estimé. # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Sélection de l'objet -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Sélectionner l'objet à construire.{}Shift pour afficher seulement le coût estimé. +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Sélectionner l'objet à construire.{}Ctrl pour sélectionner en diagonale.{}Shift pour afficher seulement le coût estimé. STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Choisir le type d'objet à construire STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Aperçu de l'objet STR_OBJECT_BUILD_SIZE :{BLACK}Taille{NBSP}: {GOLD}{NUM}{NBSP}×{NBSP}{NUM} cases @@ -2829,7 +2826,7 @@ STR_OBJECT_CLASS_TRNS :Transmetteurs STR_PLANT_TREE_CAPTION :{WHITE}Arbres STR_PLANT_TREE_TOOLTIP :{BLACK}Choix du type d'arbre. S'il y a déjà un arbre dans la case, plusieurs arbres de types différents y seront ajoutés, indépendamment du type sélectionné. STR_TREES_RANDOM_TYPE :{BLACK}Au hasard -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Planter des arbres provenant d'espèces choisies au hasard.{}Shift pour afficher seulement le coût estimé. +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Planter des arbres provenant d'espèces choisies au hasard.{}Ctrl pour sélectionner en diagonale.{}Shift pour afficher seulement le coût estimé. STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Ajouter des arbres au hasard STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Semer des arbres au hasard sur l'ensemble du terrain STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2861,6 +2858,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Créer u STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Fonder une ville à un emplacement choisi au hasard STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Beaucoup de villes au hasard STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Couvrir la carte de villes placées au hasard +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Étendre toutes les villes +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Faire croître toutes les villes légèrement STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nom de la ville{NBSP}: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Entrer un nom de ville @@ -3139,6 +3138,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Taille d STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Définir la taille de la carte en cases. Le nombre de cases utilisables sera légèrement plus petit STR_MAPGEN_BY :{BLACK}{NBSP}× STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Nb. de villes{NBSP}: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nom des villes{NBSP}: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Sélectionner la nationalité des noms des villes STR_MAPGEN_DATE :{BLACK}Date{NBSP}: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Nb. d'industries{NBSP}: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Sommet le plus élevé: @@ -3152,13 +3153,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Couvertu STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Augmenter la couverture du désert de dix pour cent STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Diminuer la couverture du désert de dix pour cent STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Générateur{NBSP}: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Type de terrain{NBSP}: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Niveau de la mer{NBSP}: +STR_MAPGEN_SEA_LEVEL :{BLACK}Niveau de la mer{NBSP}: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Nb. de rivières{NBSP}: STR_MAPGEN_SMOOTHNESS :{BLACK}Lissage{NBSP}: STR_MAPGEN_VARIETY :{BLACK}Variété de distribution{NBSP}: STR_MAPGEN_GENERATE :{WHITE}Créer +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Paramètres NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Afficher la configuration des NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Paramètres des IAs +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Afficher la configuration des IAs +STR_MAPGEN_GS_SETTINGS :{BLACK}Configuration du script de jeu +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Afficher la configuration du script de jeu + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Anglais (originaux) +STR_MAPGEN_TOWN_NAME_FRENCH :Français +STR_MAPGEN_TOWN_NAME_GERMAN :Allemands +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Anglais (additionnels) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latino-américains +STR_MAPGEN_TOWN_NAME_SILLY :Drôles +STR_MAPGEN_TOWN_NAME_SWEDISH :Suédois +STR_MAPGEN_TOWN_NAME_DUTCH :Hollandais +STR_MAPGEN_TOWN_NAME_FINNISH :Finlandais +STR_MAPGEN_TOWN_NAME_POLISH :Polonais +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovaques +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norvégiens +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hongrois +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Autrichiens +STR_MAPGEN_TOWN_NAME_ROMANIAN :Roumains +STR_MAPGEN_TOWN_NAME_CZECH :Tchèques +STR_MAPGEN_TOWN_NAME_SWISS :Suisses +STR_MAPGEN_TOWN_NAME_DANISH :Danois +STR_MAPGEN_TOWN_NAME_TURKISH :Turcs +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiens +STR_MAPGEN_TOWN_NAME_CATALAN :Catalans # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Bords de la carte{NBSP}: @@ -3304,6 +3333,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Sprite p STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Se rendre au précédent sprite normal, en ignorant les pseudo-sprites et les sprites de recoloration et de police, et en bouclant du premier vers le dernier STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representation du sprite actuellement séléctionné. L'alignement est ignoré lors de l'affichage de ce sprite STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Déplacer le sprite, en modifiant les décalages X et Y. Ctrl-clic pour déplacer le sprite de 8 unités à la fois. + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Décalage centré +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centré + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Croix + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Réinitialiser les relatifs STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Réinitialiser les décalages relatifs courants STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Décalage X{NBSP}: {NUM}, décalage Y{NBSP}: {NUM} (Absolu) @@ -3318,18 +3354,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Attention{NBSP}: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Erreur{NBSP}: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Erreur fatale{NBSP}: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Une erreur NewGRF fatale est survenue{NBSP}:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Une erreur NewGRF est survenue{NBSP}:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Le NewGRF "{STRING}" a retourné une erreur fatale{NBSP}:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}Le NewGRF "{STRING}" a retourné une erreur{NBSP}:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} ne fonctionnera pas avec la version de TTDPatch rapportée par OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} est conçu pour la version {STRING} de TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} est conçu pour être utilisé avec {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Paramètre invalide pour {1:STRING}{NBSP}: paramètre {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} doit être chargé avant {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} doit être chargé après {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} nécessite OpenTTD version {STRING} ou supérieure +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} est conçu pour la version {2:STRING} de TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} est conçu pour être utilisé avec {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Paramètre invalide pour {1:STRING}{NBSP}: paramètre {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} doit être chargé avant {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} doit être chargé après {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} nécessite OpenTTD version {2:STRING} ou supérieure STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :le fichier GRF qu'il doit traduire STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Trop de NewGRFs sont chargés -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Charger {1:STRING} comme NewGRF statique avec {STRING} peut provoquer des erreurs de synchronisation +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Charger {1:STRING} comme NewGRF statique avec {2:STRING} peut provoquer des erreurs de synchronisation STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Sprite inattendu (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Action 0 avec propriété inconnue {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Tentative d'utilisation d'un identifiant invalide (sprite {3:NUM}) @@ -3461,14 +3497,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Acheter les dro STR_LOCAL_AUTHORITY_ACTION_BRIBE :Corrompre la municipalité ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Lancez une petite campagne de publicité locale pour attirer plus de passagers et de marchandises vers vos services de transport.{} Augmente temporairement le classement des gares dans un petit rayon autour du centre-ville.{}Coût: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Lancer une campagne de publicité moyenne, pour attirer plus de voyageurs et de marchandises sur vos lignes.{}Augmente temporairement le classement de vos gares dans un rayon moyen autour du centre-ville.{}Coût:{CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Lancer une grande campagne de publicité, pour attirer plus de voyageurs et de marchandises sur vos lignes.{}Augmente temporairement le classement des gares dans un rayon important autour du centre-ville.{}Coût: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Financer la reconstruction du réseau routier local. Provoque de nombreux problèmes de trafic routier pendant 6 mois.{}Coût: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Construire une statue en l'honneur de votre compagnie.{}Augmente en permanence le classement de vos stations dans cette ville.{}Coût:{CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Financer la construction de nouveaux immeubles commerciaux.{}Stimule temporairement la croissance dans cette ville.{}Coût:{CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Achetez les droits de transport exclusifs d'un an pour la ville.{} La municipalité n'autorisera pas les passagers et les marchandises à utiliser les gares de vos concurrents.{} Coût: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Corrompre la municipalité pour améliorer votre réputation. Risque de pénalisation si le pot-de-vin est dévoilé.{}Coût{NBSP}: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Lancez une petite campagne de publicité locale pour attirer plus de passagers et de marchandises vers vos services de transport.{}Fournit une amélioration temporaire de la note des gares dans un petit rayon autour du centre-ville.{}{POP_COLOUR}Coût{NBSP}: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Lancer une campagne de publicité moyenne, pour attirer plus de voyageurs et de marchandises sur vos lignes.{}Augmente temporairement le classement de vos gares dans un rayon moyen autour du centre-ville.{}{POP_COLOUR}Coût{NBSP}:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Lancer une grande campagne de publicité, pour attirer plus de voyageurs et de marchandises sur vos lignes.{}Augmente temporairement le classement des gares dans un rayon important autour du centre-ville.{}{POP_COLOUR}Coût{NBSP}: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Financer la reconstruction du réseau routier.{}Provoque une perturbation considérable du trafic pendant 6 mois au maximum.{}{POP_COLOUR}Coût : {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Construire une statue en l'honneur de votre compagnie.{}Augmente en permanence le classement de vos stations dans cette ville.{}{POP_COLOUR}Coût{NBSP}:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Financer la construction de nouveaux immeubles commerciaux.{}Stimule temporairement la croissance dans cette ville.{}{POP_COLOUR}Coût{NBSP}:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Achetez les droits de transport exclusifs d'un an pour la ville.{} La municipalité n'autorisera pas les passagers et les marchandises à utiliser les gares de vos concurrents.{}{POP_COLOUR}Coût{NBSP}: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Corrompre la municipalité pour améliorer votre réputation. Risque de pénalisation si le pot-de-vin est dévoilé.{}{POP_COLOUR}Coût{NBSP}: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}Objectifs de {COMPANY} @@ -3641,15 +3677,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Navires STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Intérêts du prêt STR_FINANCES_SECTION_OTHER :{GOLD}Autres +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Bénéfice net +STR_FINANCES_PROFIT :{WHITE}Profit STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Solde bancaire STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Fonds propres STR_FINANCES_LOAN_TITLE :{WHITE}Emprunt STR_FINANCES_INTEREST_RATE :{WHITE}Taux d'intérêt de l'emprunt{NBSP}: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Emprunt maximum{NBSP}: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Emprunter {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Augmenter l'emprunt. Ctrl-clic pour emprunter autant que possible. STR_FINANCES_REPAY_BUTTON :{BLACK}Rembourser {CURRENCY_LONG} @@ -3750,7 +3789,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produit{ STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Nécessite{NBSP}: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}{NBSP}: {CARGO_SHORT} en attente{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Changer la production (multiple de 8, max. 2040) @@ -3780,6 +3819,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Envoyer STR_VEHICLE_LIST_REPLACE_VEHICLES :Remplacer des véhicules STR_VEHICLE_LIST_SEND_FOR_SERVICING :Envoyer à l'entretien STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Profit cette année{NBSP}: {CURRENCY_LONG} (année précédente{NBSP}: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Envoyer au dépôt STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Envoyer au dépôt @@ -3871,6 +3912,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Effort d STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Rayon d'action{NBSP}: {GOLD}{COMMA}{NBSP}cases STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Type d'aéronef{NBSP}: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Tous les types de cargaison +STR_CARGO_TYPE_FILTER_FREIGHT :Fret +STR_CARGO_TYPE_FILTER_NONE :Aucun + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Choix du véhicule. Cliquer sur un véhicule pour obtenir des informations. Ctrl-clic pour basculer le masquage du type de véhicule STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Choix du véhicule routier. Cliquer sur un véhicule pour obtenir des informations. Ctrl-clic pour basculer le masquage du type de véhicule @@ -4039,7 +4085,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :{G=m2}aéronef STR_ENGINE_PREVIEW_SHIP :{G=m}navire STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Prix{NBSP}: {CURRENCY_LONG} − Poids{NBSP}: {WEIGHT_SHORT}{}Vitesse{NBSP}: {VELOCITY} − Puissance{NBSP}: {POWER}{}Coûts d'entretien{NBSP}: {CURRENCY_LONG}/an{}Capacité{NBSP}: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Prix{NBSP}: {CURRENCY_LONG} − Poids{NBSP}: {WEIGHT_SHORT}{}Vitesse{NBSP}: {VELOCITY} − Puissance{NBSP}: {POWER}{}Effort de traction max.{NBSP}: {6:FORCE}{}Coûts d'entretien{NBSP}: {4:CURRENCY_LONG}/an{}Capacité{NBSP}: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Prix{NBSP}: {0:CURRENCY_LONG} − Poids{NBSP}: {1:WEIGHT_SHORT}{}Vitesse{NBSP}: {2:VELOCITY} − Puissance{NBSP}: {3:POWER}{}Effort de traction max.{NBSP}: {6:FORCE}{}Coûts d'entretien{NBSP}: {4:CURRENCY_LONG}/an{}Capacité{NBSP}: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Prix{NBSP}: {CURRENCY_LONG} − Vitesse max.{NBSP}: {VELOCITY}{}Capacité{NBSP}: {CARGO_LONG}{}Coûts d'entretien{NBSP}: {CURRENCY_LONG}/an STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Prix{NBSP}: {CURRENCY_LONG} - Vitesse max.{NBSP}: {VELOCITY}{}Type d'aéronef{NBSP}: {STRING}{}Capacité{NBSP}: {CARGO_LONG}, {CARGO_LONG}{}Coûts d'entretien{NBSP}: {CURRENCY_LONG}/an STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Prix{NBSP}: {CURRENCY_LONG} - Vitesse max.{NBSP}: {VELOCITY}{}Type d'aéronef{NBSP}: {STRING}{}Capacité{NBSP}: {CARGO_LONG}{}Coûts d'entretien{NBSP}: {CURRENCY_LONG}/an @@ -4198,12 +4244,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Poids{NB STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Poids{NBSP}: {LTBLUE}{WEIGHT_SHORT}{BLACK} − Puissance{NBSP}: {LTBLUE}{POWER}{BLACK} − Vitesse max.{NBSP}: {LTBLUE}{VELOCITY}{BLACK} − E.T. max.{NBSP}: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit cette année{NBSP}: {LTBLUE}{CURRENCY_LONG} (année précédente{NBSP}: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Profit cette année{NBSP}: {LTBLUE}{CURRENCY_LONG} (année précédente{NBSP}: {CURRENCY_LONG}) {BLACK}Performance min.{NBSP}: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilité{NBSP}: {LTBLUE}{COMMA}{NBSP}%{BLACK} − Pannes depuis le dernier entretien{NBSP}: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE}{BLACK} − Construit en{NBSP}: {LTBLUE}{NUM}{BLACK} − Valeur{NBSP}: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacité{NBSP}: {LTBLUE}Aucune{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacité{NBSP}: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacité{NBSP}: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacité{NBSP}: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacité{NBSP}: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacité{NBSP}: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Crédits de transfert{NBSP}: {LTBLUE}{CURRENCY_LONG} @@ -4469,25 +4516,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Cet hora STR_TIMETABLE_STATUS_START_AT :{BLACK}Cet horaire démarrera à {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Date de départ -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Choisir une date comme point de départ de cet horaire. Ctrl-clic pour définir le point de départ de cet horaire et répartir tous les véhicules partageant cet ordre uniformément selon leur ordre relatif, si l'ordre est complétement planifié +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Choisir une date comme point de départ de cet horaire. Ctrl-clic pour répartir tous les véhicules partageant cet ordre uniformément à partir de la date donnée selon leur ordre relatif, si l'ordre est complètement planifié STR_TIMETABLE_CHANGE_TIME :{BLACK}Modifier la durée -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Modifier la durée de l'ordre sélectionné +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Modifier la durée de l'ordre sélectionné. Ctrl-clic pour définir la durée pour tous les ordres STR_TIMETABLE_CLEAR_TIME :{BLACK}Annuler la durée -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Annuler la durée de l'ordre sélectionné +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Annuler la durée de l'ordre sélectionné. Ctrl-clic pour annuler la durée de tous les ordres STR_TIMETABLE_CHANGE_SPEED :{BLACK}Modifier la vitesse limite -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Modifier la vitesse maximale de déplacement de l'ordre sélectionné +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Modifier la vitesse maximale de déplacement de l'ordre sélectionné. Ctrl-Clic pour définir la vitesse pour tous les ordres STR_TIMETABLE_CLEAR_SPEED :{BLACK}Annuler la vitesse limite -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Annuler la vitesse maximale de déplacement de l'ordre sélectionné +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Annuler la vitesse maximale de déplacement de l'ordre sélectionné. Ctrl-clic pour annuler la vitesse de tous les ordres STR_TIMETABLE_RESET_LATENESS :{BLACK}RAZ compteur de retard -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Remettre à zéro le compteur de retard (le véhicule sera donc à l'heure) +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Remettre à zéro le compteur de retard, le véhicule sera donc à l'heure. Ctrl-clic pour remettre à zéro le groupe entier, le véhicule le plus en retard sera donc à l'heure et les autres en avance STR_TIMETABLE_AUTOFILL :{BLACK}Autoremplir -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Remplir l'horaire automatiquement avec les valeurs du prochain trajet (Ctrl-clic pour essayer de préserver les temps d'attente) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Remplir l'horaire automatiquement avec les valeurs du prochain trajet. Ctrl-clic pour essayer de préserver les temps d'attente STR_TIMETABLE_EXPECTED :{BLACK}Attendu STR_TIMETABLE_SCHEDULED :{BLACK}Planifié @@ -4524,19 +4571,21 @@ STR_AI_DEBUG_CONTINUE :{BLACK}Continue STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}Reprendre la partie et continuer l'IA STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}Afficher la sortie de débogage de cette IA STR_AI_GAME_SCRIPT :{BLACK}Script de jeu -STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Examiner le journal des scripts de jeu +STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Examiner le journal du script de jeu STR_ERROR_AI_NO_AI_FOUND :Aucune IA n'a été trouvée.{}Cette IA est factice et ne fera rien.{}Vous pouvez télécharger diverses IA via le système de «{NBSP}Contenu en ligne{NBSP}». STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}L'un des scripts a rencontré un problème. Merci de rapporter ceci à l'auteur du script avec une capture d'écran de la fenêtre de débogage de scripts. STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}La fenêtre de débogage de scripts n'est disponible que pour le serveur # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Configuration d'IA et de scripts de jeu +STR_AI_CONFIG_CAPTION_AI :{WHITE}Configuration d'IA +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Configuration du script de jeu STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Le script de jeu qui sera chargé dans la prochaine partie STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Les IAs qui seront chargées dans la prochaine partie STR_AI_CONFIG_HUMAN_PLAYER :Joueur humain STR_AI_CONFIG_RANDOM_AI :IA aléatoire STR_AI_CONFIG_NONE :(aucun) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Nombre maximal de concurrents{NBSP}: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Déplacer vers le haut STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Déplacer l'IA sélectionnée vers le haut @@ -4544,12 +4593,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Déplace STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Déplacer l'IA sélectionnée vers le bas STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script de jeu +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Paramètres STR_AI_CONFIG_AI :{SILVER}IA -STR_AI_CONFIG_CHANGE :{BLACK}Sélectionner {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :IA -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script de jeu +STR_AI_CONFIG_CHANGE_AI :{BLACK}Sélectionner une IA +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Sélectionner le script de jeu STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Charger un autre script STR_AI_CONFIG_CONFIGURE :{BLACK}Configurer STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configurer les paramètres du script @@ -4577,10 +4625,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Capture STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Capture d'écran de la carte d'altitude STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Capture d'écran de la mini-carte -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Paramètres -STR_AI_SETTINGS_CAPTION_AI :IA -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script de jeu +# Script Parameters +STR_AI_SETTINGS_CAPTION :{WHITE}Paramètres {STRING} +STR_AI_SETTINGS_CAPTION_AI :de l'IA +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :du script de jeu STR_AI_SETTINGS_CLOSE :{BLACK}Fermer STR_AI_SETTINGS_RESET :{BLACK}Réinitialiser STR_AI_SETTINGS_SETTING :{STRING}{NBSP}: {ORANGE}{STRING} @@ -4744,6 +4792,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... trop STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Ne peut pas générer les industries... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Impossible de construire {STRING} ici... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Impossible de construire cette industrie ici... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Impossible de prospecter l'industrie... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... trop proche d'une autre industrie STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... une ville doit d'abord être construite STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... droit à un seul par ville @@ -4758,6 +4807,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... les STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... peut seulement être construit au dessus de l'altitude d'enneigement STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... peut seulement être construit en dessous de l'altitude d'enneigement +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}La prospection a échoué par manque de chance; essayez à nouveau +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Il n'y avait pas d'emplacements appropriés pour la prospection de cette industrie STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Il n'y avait pas d'emplacements appropriés pour les industries '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Modifier les paramètres de la génération de la carte pour obtenir une meilleure carte @@ -4925,6 +4976,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objet pr STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... siège de la compagnie présent STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Impossible d'acheter ce terrain... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... il vous appartient déjà{NBSP}! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}...{NBSP}limite de construction d'objets atteinte # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Impossible de créer le groupe... @@ -4997,6 +5049,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Impossib STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... véhicule détruit +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... les véhicules ne sont pas tous identiques + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Aucun véhicule ne sera disponible STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Modifier votre configuration NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Il n'y a pas encore de véhicules disponibles @@ -5023,6 +5077,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Impossib STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... le véhicule ne peut pas aller dans toutes les stations STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... le véhicule ne peut pas aller dans cette station STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... un véhicule partageant cet ordre ne peut pas aller dans cette station +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... les véhicules n'ont pas tous les même ordres +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... les véhicules ne partagent pas tous les ordres STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Impossible de partager les ordres... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Impossible d'arrêter le partage des ordres... @@ -5030,6 +5086,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Impossib STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... trop loin de la destination précédente STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... l'aéronef n'a pas un rayon d'action suffisant +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :Il n'y a pas de gare +STR_ERROR_NO_BUS_STATION :Il n'y a pas de gare routière +STR_ERROR_NO_TRUCK_STATION :{WHITE}Il n'y a pas de station de camion +STR_ERROR_NO_DOCK :{WHITE}Il n'y a pas de quai +STR_ERROR_NO_AIRPORT :{WHITE}Il n'y a pas d'aéroport/héliport +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Il n'y a pas d'arrêts avec un type de route compatible +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Il n'y a pas d'arrêts avec un type de tram compatible +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Il n'y a pas d'arrêts convenables pour les véhicules routiers articulés. Ce type de véhicule nécessite un arrêt avec passage et non pas en baie +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Cet avion ne peut pas atterrir à cet héliport +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Cet hélicoptère ne peut pas atterrir à cet aéroport +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Il n'y a pas de point de passage ferroviaire +STR_ERROR_NO_BUOY :{WHITE}Il n'y a pas de bouée + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Impossible d'affecter un horaire au véhicule... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Les véhicules ne peuvent attendre qu'aux stations diff --git a/src/lang/frisian.txt b/src/lang/frisian.txt index edc33d5ffcb25..6d765171ff864 100644 --- a/src/lang/frisian.txt +++ b/src/lang/frisian.txt @@ -197,6 +197,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -222,7 +223,7 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filtertekst: +STR_LIST_FILTER_TITLE :{BLACK}Filter: STR_LIST_FILTER_OSKTITLE :{BLACK}Foer filter namme yn STR_LIST_FILTER_TOOLTIP :{BLACK}Typ in wurd yn om de list te filterjen @@ -248,14 +249,14 @@ STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Brek geb ###length VEHICLE_TYPES STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN :{BLACK}Ferburgen treinen sjen litte STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE :{BLACK}Ferburgen weinen sjen litte -STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP :{BLACK}Ferburgen skepen sjen litte +STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP :{BLACK}Ferburgen skippen sjen litte STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT :{BLACK}Ferburgen fleanmasines sjen litte ###length VEHICLE_TYPES STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP :{BLACK}Mei it ynskeakelje fan dizze knop wurde ek ferburgen treinen toand STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE_TOOLTIP :{BLACK}Mei it ynskeakelje fan dizze knop wurde ek ferburgen weinen toand -STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP_TOOLTIP :{BLACK}Mei it ynskeakelje fan dizze knop wurde ek ferburgen skepen toand -STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Mei it ynskeakelje fan dizze knop wurde ek ferburgen fleantúgen toand +STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP_TOOLTIP :{BLACK}Mei it ynskeakelje fan dizze knop wurde ek ferburgen skippen toand +STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Mei it ynskeakelje fan dizze knop wurde ek ferburgen fleantugen toand # Query window STR_BUTTON_DEFAULT :{BLACK}Standert @@ -311,6 +312,7 @@ STR_SORT_BY_POPULATION :Ynwenners STR_SORT_BY_RATING :Rang # Group by options for vehicle list +STR_GROUP_BY_NONE :Neat # Order button in shared orders vehicle list @@ -319,7 +321,7 @@ STR_SORT_BY_RATING :Rang STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}Spul skoftsjen STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}Tiid hurder rinne litte STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Opsjes -STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Opslaan, ferlitte, ôfslúte +STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Opslaan, ferlitte, ôfslute STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Kaar sjen litte, ekstra finster of buordlist STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Lit in list fan alle stêden sjen STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Lit Subsydzjes sjen @@ -333,8 +335,8 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Lit de b STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Betelje de bou fan in nije yndustry STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Lit in list sjen fan de treinen fan dit bedriuw. Ctrl + klik ipent of slût de groep/reau list STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Lit in list sjen fan de auto's fan dit bedriuw. Ctrl + Klik ipent of slût de groep/reau list -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Lit in list sjen fan de skepen fan dit bedriuw. Ctrl + Klik ipent of slût de groep/reau list -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Lit in list sjen fan de fleantúgen fan dit bedriuw. Ctrl+Klik skeakelt tusken de list groep/reau +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Lit in list sjen fan de skippen fan dit bedriuw. Ctrl + Klik ipent of slût de groep/reau list +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Lit in list sjen fan de fleantugen fan dit bedriuw. Ctrl+Klik skeakelt tusken de list groep/reau STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Ynzoome STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}ûtzoome STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Bou spoarwegen @@ -374,10 +376,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Ofslute # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Spulopsjes STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Ynstellings -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Spulskriptynstellings STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF-ynstellings STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Trochsichtigensopsjes STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Stêdsnammen sjen litte @@ -396,7 +397,7 @@ STR_FILE_MENU_SAVE_GAME :Spul opslaan STR_FILE_MENU_LOAD_GAME :Spul lade STR_FILE_MENU_QUIT_GAME :Spul ferlitte STR_FILE_MENU_SEPARATOR : -STR_FILE_MENU_EXIT :Ofslute +STR_FILE_MENU_EXIT :Ôfslute # Map menu ###length 4 @@ -477,6 +478,7 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Skeakel console oan/ût STR_ABOUT_MENU_AI_DEBUG :AI/Gamescript debug STR_ABOUT_MENU_SCREENSHOT :Skermôfbylding +STR_ABOUT_MENU_SHOW_FRAMERATE :Toan byldsnelheid STR_ABOUT_MENU_ABOUT_OPENTTD :Oer 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Flakken rjochtsje STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Skeakel seleksjekaders oan/út @@ -735,6 +737,7 @@ STR_SMALLMAP_LEGENDA_DOCK :{TINY_FONT}{BLA STR_SMALLMAP_LEGENDA_ROUGH_LAND :{TINY_FONT}{BLACK}Rûch Lân STR_SMALLMAP_LEGENDA_GRASS_LAND :{TINY_FONT}{BLACK}Gerslân STR_SMALLMAP_LEGENDA_BARE_LAND :{TINY_FONT}{BLACK}Skraal Lân +STR_SMALLMAP_LEGENDA_RAINFOREST :{TINY_FONT}{BLACK}Reinwâld STR_SMALLMAP_LEGENDA_FIELDS :{TINY_FONT}{BLACK}Fjilden STR_SMALLMAP_LEGENDA_TREES :{TINY_FONT}{BLACK}Beammen STR_SMALLMAP_LEGENDA_ROCKS :{TINY_FONT}{BLACK}Stiennen @@ -767,8 +770,9 @@ STR_STATUSBAR_TOOLTIP_SHOW_LAST_NEWS :{BLACK}Lit lêt STR_STATUSBAR_COMPANY_NAME :{SILVER}- - {COMPANY} - - STR_STATUSBAR_PAUSED :{YELLOW}* * SKOFTE* * STR_STATUSBAR_AUTOSAVE :{RED}Automatysk bewarje -STR_STATUSBAR_SAVING_GAME :{RED}* * SLAAT SPUL OP * * +STR_STATUSBAR_SAVING_GAME :{RED}* * SPUL AN IT BEWARJEN * * +STR_STATUSBAR_SPECTATOR :{WHITE}(taskôger) # News message history STR_MESSAGE_HISTORY :{WHITE}Berjochtenskiednis @@ -828,10 +832,10 @@ STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL :{BIG_FONT}{BLAC STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_COAL :{BIG_FONT}{BLACK}Nije koalier fûn by {INDUSTRY}!{}Produksje wurdt ferwachte te ferdûbeljen! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_OIL :{BIG_FONT}{BLACK}Nije oaljereserves fûn by {INDUSTRY}!{}Produksje wurdt ferwachte te ferdûbeljen! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM :{BIG_FONT}{BLACK}Troch ferbetterde metoades wurdt de produskje fan {INDUSTRY} ferwachte te ferdûbeljen! -STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH :{BIG_FONT}{BLACK}{STRING} Produksje by {INDUSTRY} giet omheech mei {COMMA}%! -STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL :{BIG_FONT}{BLACK} Produksje fan {INDUSTRY} giet omleech mei 50% +STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH :{BIG_FONT}{BLACK}Produksje fan {STRING} troch {INDUSTRY} giet omheech mei {COMMA}%! +STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL :{BIG_FONT}{BLACK}Produksje fan {INDUSTRY} giet omleech mei 50% STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM :{BIG_FONT}{BLACK}Insektenpleach jout gaos by {INDUSTRY}!{}Produksje giet omleech mei 50% -STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH :{BIG_FONT}{BLACK}{STRING} produksje fan {INDUSTRY} wurdt tebekset mei {COMMA}%! +STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH :{BIG_FONT}{BLACK}Produksje fan {STRING} troch {INDUSTRY} wurdt tebekset mei {COMMA}%! ###length VEHICLE_TYPES STR_NEWS_TRAIN_IS_WAITING :{WHITE}{VEHICLE} stiet opsteld yn depot @@ -850,7 +854,7 @@ STR_NEWS_PLANE_USES_TOO_SHORT_RUNWAY :{WHITE}{VEHICLE STR_NEWS_VEHICLE_IS_GETTING_OLD :{WHITE}{VEHICLE} begjint âld te wurden STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD :{WHITE}{VEHICLE} begjint tige âld te wurden STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND :{WHITE}{VEHICLE} begjint tige âld te wurden en is nedich oan ferfanging ta -STR_NEWS_TRAIN_IS_STUCK :{WHITE}{VEHICLE} kin gjin paad finne om fierder te gean +STR_NEWS_TRAIN_IS_STUCK :{WHITE}{VEHICLE} kin gjin paad fine om fierder te gean STR_NEWS_VEHICLE_IS_LOST :{WHITE}{VEHICLE} is it paad kwyt. STR_NEWS_VEHICLE_IS_UNPROFITABLE :{WHITE}{VEHICLE} hie ôfrûne jier in winst fan {CURRENCY_LONG} STR_NEWS_AIRCRAFT_DEST_TOO_FAR :{WHITE}{VEHICLE} kin net op de folgjende bestimming komme, dizze leit bûten de aksjeradius @@ -870,7 +874,12 @@ STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO :{WHITE}{STATION STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED :{BIG_FONT}{BLACK}Subsydzje oanbieding ferrûn:{}{}{STRING} fan {STRING} nei {STRING} sil no net in subsydzje krije. STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE :{BIG_FONT}{BLACK}Subsydzje ôfrûn:{}{}{STRING} tsjinst fan {STRING} nei {STRING} krijt gjin subsydzje mear. +STR_NEWS_SERVICE_SUBSIDY_OFFERED :{BIG_FONT}{BLACK}Subsydzje oanbean:{}{}Earste{STRING} tsjinst fan {STRING} nei {STRING} krijt {NUM} jier subsydzje fan 'e gemeente! ###length 4 +STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF :{BIG_FONT}{BLACK}Subsydzje tawezen oan {STRING}!{}{}{STRING} tsjinst fan {STRING} nei {STRING} krijt 50% ekstra betelle foar {P 4 "it" "de"} kommende {NUM} jier! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLACK}Subsydzje tawezen oan {STRING}!{}{}{STRING} tsjinst fan {STRING} nei {STRING} krijt dûbel betelle foar {P 4 "it" "de"} kommende {NUM} jier! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}Subsydzje tawezen oan {STRING}!{}{}{STRING} tsjinst fan {STRING} nei {STRING} krijt trijedûbel betelle foar {P 4 "it" "de"} kommende {NUM} jier! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE :{BIG_FONT}{BLACK}Subsydzje tawezen oan {STRING}!{}{}{STRING} tsjinst fan {STRING} nei {STRING} krijt fjouwerdûbel betelle foar {P 4 "it" "de"} kommende {NUM} jier! STR_NEWS_ROAD_REBUILDING :{BIG_FONT}{BLACK}Ferkearsgaos yn {TOWN}!{}{}Dykreparaasje betelle troch {STRING} bringt 6 moannen oan ellinde foar ferkearsdielnimmers! STR_NEWS_EXCLUSIVE_RIGHTS_TITLE :{BIG_FONT}{BLACK}Transportmonopoalje! @@ -923,36 +932,14 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Súd-Afrikaansk STR_GAME_OPTIONS_CURRENCY_CUSTOM :Oanpasse... STR_GAME_OPTIONS_CURRENCY_GEL :Georgyske Lari (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Iraanske Rial (IRR) - -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Lofts ride -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Rjochts ride - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Stêdnammen -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Selektearje nammestyl - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Ingelsk (Orizjineel) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Frânsk -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Dútsk -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Ingelsk (Ekstra) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latynsk-Amerikaansk -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Ût mâlens -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Sweedsk -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Nederlânsk -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finsk -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Poalsk -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slowaaks -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Noorsk -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hongaarsk -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Eastenryksk -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Roemeensk -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tsjechysk -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Switsersk -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Deensk -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turksk -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italjaansk -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalaansk +STR_GAME_OPTIONS_CURRENCY_RUB :Neie Russyske Rubels (RUB) +STR_GAME_OPTIONS_CURRENCY_MXN :Meksikaanse Peso (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Neie Taiwanesyske Dollar (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Sineeske Renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Hongkongske Dollar (HKD) +STR_GAME_OPTIONS_CURRENCY_INR :Yndyske rupee (INR) +STR_GAME_OPTIONS_CURRENCY_IDR :Yndonezyske Roepia (IDR) +STR_GAME_OPTIONS_CURRENCY_MYR :Maleizyske Ringgit (MYR) STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatysk opslaan STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selektearje de interval foar automatysk opslaan @@ -971,22 +958,19 @@ STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Selektea STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Folslein skerm STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Finkje dit fakje oan om OpenTTD te boartsje yn in folslein skerm -STR_GAME_OPTIONS_RESOLUTION :{BLACK}Skermresolusje +STR_GAME_OPTIONS_RESOLUTION :{BLACK}Skermresolúsje STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}Selektearje de skermresolutje om te brûken STR_GAME_OPTIONS_RESOLUTION_OTHER :oars +STR_GAME_OPTIONS_RESOLUTION_ITEM :{NUM}x{NUM} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Interfacegrutte - -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normaal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dûbele grutte -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Fjouwerdûbele grutte +STR_GAME_OPTIONS_REFRESH_RATE :{BLACK}Byldferfaskingssnelheid STR_GAME_OPTIONS_BASE_GRF :{BLACK}Basisset for ôfbyldings STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Selektearje de basis ôfbyldingsset om te brûken @@ -1031,8 +1015,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Foarbyl STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pûn (£) yn jo faluta STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Feroarje opsje fan oanpaste faluta -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimum oantal tsjinstanners: {ORANGE}{COMMA} - STR_NONE :Gjin STR_FUNDING_ONLY :Allinnich finansierje STR_MINIMAL :Minimaal @@ -1082,33 +1064,41 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Gêrs lânskip +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Snie lânskip +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropysk lânskip +STR_CLIMATE_TOYLAND_LANDSCAPE :Boartersguodlânskip + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Hiel Sljocht STR_TERRAIN_TYPE_FLAT :Sljocht STR_TERRAIN_TYPE_HILLY :Heuvelich STR_TERRAIN_TYPE_MOUNTAINOUS :Bergich STR_TERRAIN_TYPE_ALPINIST :Alpinist +STR_TERRAIN_TYPE_CUSTOM :Oanpaste hichte ###length 4 +STR_CITY_APPROVAL_LENIENT :Meigeand STR_CITY_APPROVAL_TOLERANT :Tolerant STR_CITY_APPROVAL_HOSTILE :Fijannich -STR_CITY_APPROVAL_PERMISSIVE :Tajouwend +STR_CITY_APPROVAL_PERMISSIVE :Tajouwend (gjin effekt op bedriuwsaktiviteit) STR_WARNING_NO_SUITABLE_AI :{WHITE}Gjin brûkbere AIs beskikber...{}jo kinne ferskillende AIs downloade fia it 'Online Content' systeem # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Ynstellings -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtertekst: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Alles útklappe STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Alles ynklappe STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(gjin útlis beskikber) STR_CONFIG_SETTING_DEFAULT_VALUE :{LTBLUE}Standerdwaarde: {ORANGE}{STRING} STR_CONFIG_SETTING_TYPE :{LTBLUE}Ynstellingstype: {ORANGE}{STRING} -STR_CONFIG_SETTING_TYPE_CLIENT :Kliïntynstellings (wurdt net per spul opslein; hat ynvloed op alle spullen) -STR_CONFIG_SETTING_TYPE_GAME_MENU :Spulynstellings (wurdt per spul opslein; hat allinich effekt op nije spullen) -STR_CONFIG_SETTING_TYPE_GAME_INGAME :Spulynstellings (wurdt per spul opslein; hat allinich effekt op it hjoeddeiske spul) -STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Bedriuwynstellings (wurdt per spul opslein; hat allinich effekt op nije spullen) -STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Bedriuwynstellings (wurdt per spul opslein; hat allinich effekt op it hjoeddeiske bedriuw) +STR_CONFIG_SETTING_TYPE_CLIENT :Kliïntynstellings (wurdt net per spul bewarre; hat ynfloed op alle spullen) +STR_CONFIG_SETTING_TYPE_GAME_MENU :Spulynstellings (wurdt per spul bewarre; hat allinich effekt op nije spullen) +STR_CONFIG_SETTING_TYPE_GAME_INGAME :Spulynstellings (wurdt per spul bewarre; hat allinich effekt op it hjoeddeiske spul) +STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Bedriuwynstellings (wurdt per spul bewarre; hat allinich effekt op nije spullen) +STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Bedriuwynstellings (wurdt per spul bewarre; hat allinich effekt op it hjoeddeiske bedriuw) STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}Kategory: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Type: @@ -1121,11 +1111,11 @@ STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW :Ynstellings dy' STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT :{BLACK}Behein de ûndersteande list ta bepaalde ynstellingtypes STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL :Alle ynstellingtypes -STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT :Kliïntynstellings (wurdt net per spul opslein; hat ynvloed op alle spullen) -STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :Spulynstellings (wurdt per spul opslein; hat allinich effekt op nije spullen) -STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Spulynstellings (wurdt per spul opslein; hat allinich effekt op it hjoeddeiske spul) -STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Bedriuwynstellings (wurdt per spul opslein; hat allinich effekt op nije spullen) -STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Bedriuwynstellings (wurdt per spul opslein; hat allinich effekt op it hjoeddeiske bedriuw) +STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT :Kliïntynstellings (wurdt net per spul bewarre; hat ynfloed op alle spullen) +STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :Spulynstellings (wurdt per spul bewarre; hat allinich effekt op nije spullen) +STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Spulynstellings (wurdt per spul bewarre; hat allinich effekt op it hjoeddeiske spul) +STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Bedriuwynstellings (wurdt per spul bewarre; hat allinich effekt op nije spullen) +STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Bedriuwynstellings (wurdt per spul bewarre; hat allinich effekt op it hjoeddeiske bedriuw) STR_CONFIG_SETTINGS_NONE :{WHITE}- Gjin - ###length 3 @@ -1139,7 +1129,7 @@ STR_CONFIG_SETTING_ON :Oan STR_CONFIG_SETTING_DISABLED :Utskeakele ###length 3 -STR_CONFIG_SETTING_COMPANIES_OFF :Ut +STR_CONFIG_SETTING_COMPANIES_OFF :Út STR_CONFIG_SETTING_COMPANIES_OWN :Eigen bedriuw STR_CONFIG_SETTING_COMPANIES_ALL :Alle bedriuwen @@ -1155,9 +1145,10 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Rjochts STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maksimale startersliening: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maksimale bedrach hokker troch in bedriuw lient wurde kin (sûnder acht te slaan op de ynflaasje) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Rinte: {STRING} -STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Rinte op lienings; behearsket ek ynflaasje at dizze oan stiet +STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Rinte op liening; behearsket ek ynflaasje at dizze oan stiet STR_CONFIG_SETTING_RUNNING_COSTS :Eksploitaasjekosten: {STRING} STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Stel hichte ûnderhâlds- en ekploitaasjekosten fan fiertugen en ynfrastruktuer yn @@ -1171,7 +1162,9 @@ STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT :Behearskje hoe STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER :Subsydzjefermannichfâldiger: {STRING} STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :Stel yn hoefolle der betelle wurdt foar subsidiearre ferbinings +STR_CONFIG_SETTING_SUBSIDY_DURATION_HELPTEXT :Stel it oantal jierren yn wêrfoar subsydzje takend wurdt +STR_CONFIG_SETTING_SUBSIDY_DURATION_VALUE :{NUM} jier ###setting-zero-is-special STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Boukosten: {STRING} @@ -1263,10 +1256,10 @@ STR_CONFIG_SETTING_SHOWFINANCES :Finansjeel oers STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT :By ynskeakeljen wurdt der elts jier in finansjeel jierferlslach sjen litten, dit makket it makliker in oersjoch fan de finansjele steat fan it bedriuw te krijen STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT :Nije oarder binne standert 'non-stop': {STRING} -STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT :Normaalsprutsen sil in fiertúch op alle stasjons dy't hy tsjinkomt stopje. Troch dizze opsje yn te skeakeljen sille nije oarders standerd op non-stop set wurden. Dit hat dus gjin ynvloed op besteande oarders! +STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT :Normaalsprutsen sil in fiertúch op alle stasjons dy't hy tsjinkomt stopje. Troch dizze opsje yn te skeakeljen sille nije oarders standerd op non-stop set wurden. Dit hat dus gjin ynfloed op besteande oarders! STR_CONFIG_SETTING_STOP_LOCATION :Nije treinoarders stopje de trein standert {STRING} fan it perron -STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :Plak wêr't treinen stopje by it binnenriden fan in stasjon. Dit hat allinnich ynvloed op nije oarders en kin altyd yndividueel ynstelt wurde +STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :Plak wêr't treinen stopje by it binnenriden fan in stasjon. Dit hat allinnich ynfloed op nije oarders en kin altyd yndividueel ynstelt wurde ###length 3 STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END :oan it ein STR_CONFIG_SETTING_STOP_LOCATION_MIDDLE :yn it midden @@ -1384,6 +1377,8 @@ STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Oaljeraffinader STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Sniehichte: {STRING} +STR_CONFIG_SETTING_SNOW_COVERAGE :Snie-oerflak: {STRING} +STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE :{NUM}% STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Rûgens fan it terrein: {STRING} @@ -1408,6 +1403,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Ferbettere STR_CONFIG_SETTING_ROAD_SIDE :Weinen: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Kies riidkant +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Lofts ride +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Rjochts ride + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Hichtekaartrotaasje: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Tsjin de klok yn @@ -1435,6 +1434,7 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Donker grien STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Fiolet ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Griis nei read ###length 4 @@ -1485,8 +1485,8 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Ut STR_CONFIG_SETTING_AUTOSAVE :Automatysk bewarje: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Selektearje de tiid tusken automatysk bewarje fan it spul -STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :Brûk it {STRING} datumformaat yn de nammen fan opsleine splullen -STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT :Datumformaat foar de bestânsnammen fan opsleine spullen +STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :Brûk it {STRING} datumformaat yn de nammen fan bewarre spullen +STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT :Datumformaat foar de bestânsnammen fan bewarre spullen ###length 3 STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_LONG :lang (31 Dec 2008) STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_SHORT :koart (31-12-2008) @@ -1518,7 +1518,7 @@ STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Lit oankomst- e STR_CONFIG_SETTING_QUICKGOTO :Flugge oanmaak fan fiertúchoarders: {STRING} STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT :By it iepenjen fan it oardersfinster direktst it 'gean-nei'-ark iepenje -STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE :Standert spoarsoart (by nij of opslein spul): {STRING} +STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE :Standert spoarsoart (by nij of bewarre spul): {STRING} STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :Spoartype om te selektearjen nei it starten fan in nij spul. 'Earst beskikber' selektearret it âldste spoartype, 'Lêst beskikber' selektearret it nijste spoartype en 'Meast brûkt' selektearret is spoartyp hokker it measte brûkt wurdt ###length 3 STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST :Earst beskikber @@ -1533,6 +1533,7 @@ STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :Hâld de bouark ###setting-zero-is-special +STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_ZERO :Gjin limyt (sa rap as dyn kompjûter it talit) STR_CONFIG_SETTING_SOUND_TICKER :Ljochtkrante: {STRING} STR_CONFIG_SETTING_SOUND_TICKER_HELPTEXT :Lit in lûd heare by gearfette nijsberjochten @@ -1567,8 +1568,8 @@ STR_CONFIG_SETTING_MAX_ROAD_VEHICLES_HELPTEXT :Maksimaal oanta STR_CONFIG_SETTING_MAX_AIRCRAFT :Maksimaal oantal fleanmasines per bedriuw: {STRING} STR_CONFIG_SETTING_MAX_AIRCRAFT_HELPTEXT :Maksimaal oantal fleanmasines dat in bedriuw hawwe kin -STR_CONFIG_SETTING_MAX_SHIPS :Maksimaal oantal skepen per bedriuw: {STRING} -STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :Maksimaal oantal skepen dat in bedriuw hawwe kin +STR_CONFIG_SETTING_MAX_SHIPS :Maksimaal oantal skippen per bedriuw: {STRING} +STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :Maksimaal oantal skippen dat in bedriuw hawwe kin STR_CONFIG_SETTING_AI_BUILDS_TRAINS :Ferbied treinen foar computerspilers: {STRING} STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :By ynskeakeljen is it ûnmooglik foar kompjûterspilers om treinen te bouwen @@ -1599,7 +1600,7 @@ STR_CONFIG_SETTING_SERVINT_TRAINS :Standert repara STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :Stel it standert reparaasjeskema yn foar nije treinen dy't gjin eigen reparaasjeskema kenne STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES :Standert reparaasjeskema foar weinen: {STRING} STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES_HELPTEXT :Stel it standert reparaasjeskema yn foar nije weinen dy't gjin eigen reparaasjeskema kenne -STR_CONFIG_SETTING_SERVINT_AIRCRAFT :Standert reparaasjeskema foar fleantúgen: {STRING} +STR_CONFIG_SETTING_SERVINT_AIRCRAFT :Standert reparaasjeskema foar fleantugen: {STRING} STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT :Stel it standert reparaasjeskema yn foar nije fleantugen dy't gjin eigen reparaasjeskema kenne STR_CONFIG_SETTING_SERVINT_SHIPS :Standerd reparaasjeskema foar skippen: {STRING} STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT :Stel it standerd reparaasjeskema yn foar nije skippen dy't gjin eigen reparaasjeskema kenne @@ -1670,12 +1671,14 @@ STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Krante verskien STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :It jier wêrop kranteberjochten oergean op kleur. Foar dit jier oan binne sy swart/wyt STR_CONFIG_SETTING_STARTING_YEAR :Begjin jier: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} ###setting-zero-is-special ###length 3 STR_CONFIG_SETTING_ALLOW_SHARES :Stea it keapjen fan oandielen ta: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Minimale leeftiid fan it bedriuw om oandielen te hanneljen: {STRING} STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :By slepe, pleats seinen eltse: {STRING} @@ -1701,6 +1704,7 @@ STR_CONFIG_SETTING_TOWN_LAYOUT_RANDOM :Soksawat STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :Doarpen en stêden meie dyken boue: {STRING} STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Stêden meie spoaroergongen boue: {STRING} +STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Troch dizze opsje yn te skeakeljen kinne stêden oergongen krúspunten op gelikense hichte bouwe STR_CONFIG_SETTING_NOISE_LEVEL :Wetten oer maximale lûdesdruk foar fleanfjilden: {STRING} @@ -1737,6 +1741,7 @@ STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X :4x STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X :8x ###length 3 +STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_NORMAL :1x STR_CONFIG_SETTING_TOWN_GROWTH :Tempo fan stêdsútwreiding: {STRING} STR_CONFIG_SETTING_TOWN_GROWTH_HELPTEXT :Tempo fan stêdsútwreiding @@ -1820,7 +1825,7 @@ STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION :{ORANGE}konstru STR_CONFIG_SETTING_ADVISORS :{ORANGE}Nijs / Adviseurs STR_CONFIG_SETTING_COMPANY :{ORANGE}Bedriuw STR_CONFIG_SETTING_ACCOUNTING :{ORANGE}Boekhâlding -STR_CONFIG_SETTING_VEHICLES :{ORANGE}Auto's +STR_CONFIG_SETTING_VEHICLES :{ORANGE}Motorreauwen STR_CONFIG_SETTING_VEHICLES_PHYSICS :{ORANGE}Natuerkundig model STR_CONFIG_SETTING_VEHICLES_ROUTING :{ORANGE}Route STR_CONFIG_SETTING_LIMITATIONS :{ORANGE}Beheinings @@ -1833,6 +1838,7 @@ STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}yndustr STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Frachtdistribusje STR_CONFIG_SETTING_AI :{ORANGE}Tsjinstânners STR_CONFIG_SETTING_AI_NPC :{ORANGE}Computer spilers +STR_CONFIG_SETTING_NETWORK :{ORANGE}Netwurk STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS :Pathfinder foar treinen: {STRING} STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES :Pathfinder foar auto's: {STRING} @@ -1841,7 +1847,7 @@ STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS_HELPTEXT :Pathfinder te b STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Omkeare fan treinen by seinen: {STRING} ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recommended) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Feroarje wearde @@ -1851,6 +1857,7 @@ STR_CONFIG_ERROR_INVALID_VALUE :{WHITE}... ûnj STR_CONFIG_ERROR_INVALID_GRF_NOT_FOUND :koe net fûn wurde STR_CONFIG_ERROR_INVALID_GRF_INCOMPATIBLE :Dat strykt net mei dizze ferzje fan OpenTTD STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN :ûnbekind +STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}Gjin geheugen mear # Video initalization errors @@ -1869,11 +1876,10 @@ STR_INTRO_HIGHSCORE :{BLACK}Topskore STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Ynstellings STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF ynstellings STR_INTRO_ONLINE_CONTENT :{BLACK}Sikje online ynhâld -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI/Spulskriptynstellings -STR_INTRO_QUIT :{BLACK}Ôfslúte +STR_INTRO_QUIT :{BLACK}Ôfslute STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Begjin in nei spul. Ctrl + klik slaat kaartynstelling oer -STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}Laad in opslein spul +STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}Laad in bewarre spul STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}Begjin in nij spul, mei de hichtekaart as lânskip STR_INTRO_TOOLTIP_PLAY_SCENARIO :{BLACK}Start in nei spul, mei in selsmakke lânskip STR_INTRO_TOOLTIP_SCENARIO_EDITOR :{BLACK}Meitsje in selsmakke lânskip @@ -1889,12 +1895,12 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Topskore STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Ynstellings sjen litte STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Lit NewGRF ynstellings sjen STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Strún ynternet ôf om nije ynhâld del te heljen -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}AI/Spulskriptynstellings sjen litte STR_INTRO_TOOLTIP_QUIT :{BLACK}Slút 'OpenTTD' ôf # Quit window -STR_QUIT_CAPTION :{WHITE}Ôfslúte +STR_QUIT_CAPTION :{WHITE}Ôfslute +STR_QUIT_ARE_YOU_SURE_YOU_WANT_TO_EXIT_OPENTTD :{YELLOW}Witte jo seker dat jo dit spul ôfslute wolle? STR_QUIT_YES :{BLACK}Ja STR_QUIT_NO :{BLACK}Nee @@ -1910,25 +1916,20 @@ STR_CHEAT_MONEY :{LTBLUE}Stoart STR_CHEAT_CHANGE_COMPANY :{LTBLUE}Spielje as bedriuw: {ORANGE}{COMMA} STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Gigantyske sloopmodus: {ORANGE}{STRING} STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunnels Meie inoar krúse: {ORANGE}{STRING} -STR_CHEAT_NO_JETCRASH :{LTBLUE}Grutte fleantúgen stoarte net faak del op lytse fleanfjilden: {ORANGE}{STRING} +STR_CHEAT_NO_JETCRASH :{LTBLUE}Grutte fleantugen stoarte net faak del op lytse fleanfjilden: {ORANGE}{STRING} STR_CHEAT_EDIT_MAX_HL :{LTBLUE}Feroarje de maksimale kaarthichte: {ORANGE}{NUM} STR_CHEAT_CHANGE_DATE :{LTBLUE}Veroarje tiidstip: {ORANGE}{DATE_SHORT} STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Wizigje dit jier STR_CHEAT_SETUP_PROD :{LTBLUE}Stea oanpassen fan produksje ta: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Gêrs lânskip -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Snie lânskip -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropysk lânskip -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Boartersguodlânskip - # Livery window +STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Kleurenskema STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Lit gewoane kleurskemas sjen STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Lit kleurskema sjen fan treinen STR_LIVERY_ROAD_VEHICLE_TOOLTIP :{BLACK}Lit kleurskema sjen fan bussen en frachtauto's STR_LIVERY_SHIP_TOOLTIP :{BLACK}Lit kleurskema sjen fan skippen -STR_LIVERY_AIRCRAFT_TOOLTIP :{BLACK}Lit kleurskema sjen fan fleantúgen +STR_LIVERY_AIRCRAFT_TOOLTIP :{BLACK}Lit kleurskema sjen fan fleantugen STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Kies de haadkleur foar it selektearre kleurskema. Ctrl+Klik stelt dizze kleur foar alle skema's yn. STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Kies de twadde kleur fan it selektearre kleurskema. Ctrl+Klik stelt dizze kleur yn foar alle skema's @@ -1951,8 +1952,8 @@ STR_LIVERY_TRUCK :Frachtauto STR_LIVERY_PASSENGER_SHIP :Fearboat STR_LIVERY_FREIGHT_SHIP :Frachtskip STR_LIVERY_HELICOPTER :Wjukkelmasjiene -STR_LIVERY_SMALL_PLANE :Lyts fleantúg -STR_LIVERY_LARGE_PLANE :Grut fleantúg +STR_LIVERY_SMALL_PLANE :Lyts fleantúch +STR_LIVERY_LARGE_PLANE :Grut fleantúch STR_LIVERY_PASSENGER_TRAM :Passazjier Tram STR_LIVERY_FREIGHT_TRAM :Fracht Tram @@ -2010,6 +2011,8 @@ STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Feroarje # Matches ServerGameType ###length 3 +STR_NETWORK_SERVER_VISIBILITY_LOCAL :Lokaal +STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :Allinnich op útnûging # Network server list STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Multiplayer @@ -2022,30 +2025,36 @@ STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION :{BLACK}kliïnte STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT :{BLACK}{COMMA}x{COMMA} STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION :{BLACK}Lângrutte STR_NETWORK_SERVER_LIST_DATE_CAPTION :{BLACK}Datum +STR_NETWORK_SERVER_LIST_DATE_CAPTION_TOOLTIP :{BLACK}Wizigje datum STR_NETWORK_SERVER_LIST_YEARS_CAPTION :{BLACK}Jieren +STR_NETWORK_SERVER_LIST_CLICK_GAME_TO_SELECT :{BLACK}Klik in spul út de list om it te selektearjen STR_NETWORK_SERVER_LIST_LAST_JOINED_SERVER :{BLACK}Server wert dast it lêst op spiele hast -STR_NETWORK_SERVER_LIST_CLICK_TO_SELECT_LAST :{BLACK}Klik om tsjinner wert dast it lêst op spiele hast te selektearje +STR_NETWORK_SERVER_LIST_CLICK_TO_SELECT_LAST :{BLACK}Klik om server wert dast it lêst op spiele hast te selektearje STR_NETWORK_SERVER_LIST_GAME_INFO :{SILVER}Spul INFO STR_NETWORK_SERVER_LIST_CLIENTS :{SILVER}Kliïnten: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA} STR_NETWORK_SERVER_LIST_LANDSCAPE :{SILVER}Lânskip: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_MAP_SIZE :{SILVER}Lângrutte: {WHITE}{COMMA}x{COMMA} -STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}Tsjinnerferzje: {WHITE}{STRING} -STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}Tsjinneradres: {WHITE}{STRING} +STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}Serverferzje: {WHITE}{STRING} +STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}Serveradres: {WHITE}{STRING} +STR_NETWORK_SERVER_LIST_INVITE_CODE :{SILVER}Útnûgingskoade: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_START_DATE :{SILVER}Start datum: {WHITE}{DATE_SHORT} +STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}Spulskript: {WHITE}{STRING} (v{NUM}) STR_NETWORK_SERVER_LIST_PASSWORD :{BLACK}Mei wachtwurd beskerme! STR_NETWORK_SERVER_LIST_SERVER_OFFLINE :{SILVER}SERVER NET BESKIKBER -STR_NETWORK_SERVER_LIST_SERVER_FULL :{SILVER}SERVER VOL +STR_NETWORK_SERVER_LIST_SERVER_FULL :{SILVER}SERVER FOL STR_NETWORK_SERVER_LIST_VERSION_MISMATCH :{SILVER}FERKEARDE FERZJE STR_NETWORK_SERVER_LIST_GRF_MISMATCH :{SILVER}FERKEARDE NEWGRF STR_NETWORK_SERVER_LIST_JOIN_GAME :{BLACK}Meidwaan mei spul -STR_NETWORK_SERVER_LIST_REFRESH_TOOLTIP :{BLACK}Laad tsjinner ynfo opnij +STR_NETWORK_SERVER_LIST_REFRESH :{BLACK}Server ferfarskje +STR_NETWORK_SERVER_LIST_REFRESH_TOOLTIP :{BLACK}Serverynfo ferfarskje -STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Tsjinner tafoegje -STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Start tsjinner -STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Start dien eigen tsjinner +STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}Op lokaal netwurk sykje nei server +STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Server tafoegje +STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Start server +STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Start dien eigen server STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Fier dyn namme in @@ -2055,6 +2064,7 @@ STR_NETWORK_START_SERVER_CAPTION :{WHITE}Start in STR_NETWORK_START_SERVER_NEW_GAME_NAME :{BLACK}Spulnamme: STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Wachtwurd ynstelle +STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}Sichtberheid STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} kliïnt{P "" en} STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Maksimaal oantal kliïnten: STR_NETWORK_START_SERVER_COMPANIES_SELECT :{BLACK}{NUM} bedriuw{P "" en} @@ -2065,6 +2075,7 @@ STR_NETWORK_START_SERVER_NEW_GAME_NAME_OSKTITLE :{BLACK}Fier in # Network connecting window STR_NETWORK_CONNECTING_CAPTION :{WHITE}Ferbyning meitsje... +STR_NETWORK_CONNECTING_WAITING :{BLACK}{NUM} klïïnt{P "" en} foar dy STR_NETWORK_CONNECTING_DOWNLOADING_1 :{BLACK}{BYTES} Delhelle oant STR_NETWORK_CONNECTING_DOWNLOADING_2 :{BLACK}{BYTES} / {BYTES} delhelle @@ -2080,23 +2091,33 @@ STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Bedriuws STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}Ferbining ferbrekke -STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Tsjinner is beskerme. Fier wachtwurd yn +STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server is beskerme. Fier wachtwurd yn STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Bedriuw is beskerme. Fier wachtwurd yn # Network company list added strings -STR_NETWORK_COMPANY_LIST_CLIENT_LIST :{WHITE}Client lyst +STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Online spilers # Network client list +STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}Namme +STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}Namme fan de server wêrsto op spilest +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Sichtberheid +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION :Dyn namme +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Dit bisto sels # Matches ConnectionType ###length 5 +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Iepenbier +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Bisto der wis fan bedriuw '{COMPANY}' fuort te smiten? +STR_NETWORK_ASK_RELAY_NO :{BLACK}Nee +STR_NETWORK_ASK_RELAY_YES_ALWAYS :{BLACK}Ja, net wer freegje STR_NETWORK_SPECTATORS :Taskôgers # Network set password +STR_COMPANY_PASSWORD_CANCEL :{BLACK}It ynfulde wachtwurd net bewarje STR_COMPANY_PASSWORD_OK :{BLACK}Jou it bedriuw it nije wachtwurd STR_COMPANY_PASSWORD_CAPTION :{WHITE}Bedriuwswachtwurd STR_COMPANY_PASSWORD_MAKE_DEFAULT_TOOLTIP :{BLACK}Brûk dit bedriuwswachtwurd gewoanwei foar alle nije bedriuwen @@ -2117,19 +2138,23 @@ STR_NETWORK_CHAT_TO_COMPANY :[Team] Oan {STR STR_NETWORK_CHAT_CLIENT :[Privee] {STRING}: {WHITE}{STRING} STR_NETWORK_CHAT_TO_CLIENT :[Privee] Nei {STRING}: {WHITE}{STRING} STR_NETWORK_CHAT_ALL :[Yderiin] {STRING}: {WHITE}{STRING} +STR_NETWORK_CHAT_EXTERNAL :[{3:STRING}] {0:STRING}: {WHITE}{1:STRING} STR_NETWORK_CHAT_OSKTITLE :{BLACK}Skriuw berjocht foar netwurk chat # Network messages STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Koe gjin ferbyning meitsje fanwegen ferkearde NewGRF STR_NETWORK_ERROR_DESYNC :{WHITE}Koe net synchronisearje mei netwurkspul STR_NETWORK_ERROR_LOSTCONNECTION :{WHITE}Networkspul ferbining kwyt -STR_NETWORK_ERROR_SAVEGAMEERROR :{WHITE}Koe opslein spul net laden -STR_NETWORK_ERROR_SERVER_START :{WHITE}Koe de tsjinner net starte +STR_NETWORK_ERROR_SAVEGAMEERROR :{WHITE}Koe spul net lade +STR_NETWORK_ERROR_SERVER_START :{WHITE}Koe de server net starte STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}In protokol flater is opmurken en de ferbining is sletten STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Ferkeard wachtwurd -STR_NETWORK_ERROR_SERVER_FULL :{WHITE}De tsjinner is vol +STR_NETWORK_ERROR_SERVER_FULL :{WHITE}De server is fol +STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}Do bist ferbanne fan disse server +STR_NETWORK_ERROR_KICK_MESSAGE :{WHITE}Reden: {STRING} STR_NETWORK_ERROR_CHEATER :Falsk spielje net tastien op disse server STR_NETWORK_ERROR_TOO_MANY_COMMANDS :{WHITE}Do stjoerst tevolle opdrachten ny de server +STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Disse namme is net jildich STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Mooglik ferbinning kwyt STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION :{WHITE}De lêste{NUM} seconde{P "" s} is gjin data oankom fan e server @@ -2145,14 +2170,20 @@ STR_NETWORK_ERROR_CLIENT_NOT_EXPECTED :ûnjildich of STR_NETWORK_ERROR_CLIENT_WRONG_REVISION :ferkearde revyzje STR_NETWORK_ERROR_CLIENT_NAME_IN_USE :namme is al beset STR_NETWORK_ERROR_CLIENT_WRONG_PASSWORD :ferkeard wachtwurd +STR_NETWORK_ERROR_CLIENT_KICKED :fuortstjoerd troch server +STR_NETWORK_ERROR_CLIENT_CHEATER :besocht falsk te spieljen STR_NETWORK_ERROR_CLIENT_TOO_MANY_COMMANDS :joech tevolle opdrachten +STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD :wachtwurd net op tiid ûntfongen +STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :tiidlimyt ferstrutsen STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP :kaart delheljen duorret te lang STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :kaart ferwurkje duorret te lang +STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :ûnjildige namme # Network related errors STR_NETWORK_SERVER_MESSAGE :*** {1:STRING} ###length 12 +STR_NETWORK_SERVER_MESSAGE_GAME_PAUSED :Spul yn rêst ({STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_1 :Spul stiet noch yn rêst ({STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_2 :Spul stiet noch yn rêst ({STRING}, {STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_4 :Spul stiet nog yn rêst ({STRING}, {STRING}, {STRING}, {STRING}) @@ -2162,8 +2193,9 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT :spulskript STR_NETWORK_MESSAGE_CLIENT_LEAVING :Ferlit STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} der is ien bykommen(Client #{2:NUM}) STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} is in neie taskôger +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} hat it spul ferlitten ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} hat syn/har namme oanpast nei {STRING} -STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Tsjinner hat de ferbining sluten +STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server hat de ferbyning slúten # Content downloading window @@ -2172,10 +2204,12 @@ STR_CONTENT_TYPE_CAPTION :{BLACK}Type STR_CONTENT_NAME_CAPTION :{BLACK}Namme STR_CONTENT_SELECT_ALL_CAPTION :{BLACK}Alles selektearje STR_CONTENT_UNSELECT_ALL_CAPTION :{BLACK}Alles deselektearje +STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}Do ferlitst OpenTTD! STR_CONTENT_OPEN_URL :{BLACK}Webside besykje STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Webside foar dizze ynhâld besykje STR_CONTENT_DOWNLOAD_CAPTION :{BLACK}Delhelje STR_CONTENT_DOWNLOAD_CAPTION_TOOLTIP :{BLACK}Begjinne mei delheljen fan selektearre ynhâld +STR_CONTENT_TOTAL_DOWNLOAD_SIZE :{SILVER}Totaal om te delheljen: {WHITE}{BYTES} STR_CONTENT_DETAIL_TITLE :{SILVER}KONTENT INFO ###length 5 @@ -2186,6 +2220,7 @@ STR_CONTENT_DETAIL_DESCRIPTION :{SILVER}Beskriu STR_CONTENT_DETAIL_URL :{SILVER}URL: {WHITE}{STRING} STR_CONTENT_DETAIL_TYPE :{SILVER}Type: {WHITE}{STRING} STR_CONTENT_DETAIL_FILESIZE :{SILVER}Bestângrutte: {WHITE}{BYTES} +STR_CONTENT_DETAIL_DEPENDENCIES :{SILVER}Ôfhinklikheden: {WHITE}{STRING} STR_CONTENT_NO_ZLIB_SUB :{WHITE}... delheljen fan dizze ynhâld is net mooglik # Order of these is important! @@ -2195,6 +2230,7 @@ STR_CONTENT_TYPE_AI_LIBRARY :AI biblioteek STR_CONTENT_TYPE_SCENARIO :Lânskip STR_CONTENT_TYPE_HEIGHTMAP :Hichtemap STR_CONTENT_TYPE_BASE_SOUNDS :Basislûden +STR_CONTENT_TYPE_BASE_MUSIC :Basisset for musyk STR_CONTENT_TYPE_GAME_SCRIPT :Spulskript STR_CONTENT_TYPE_GS_LIBRARY :GS biblioteek @@ -2206,15 +2242,16 @@ STR_CONTENT_DOWNLOAD_COMPLETE :{WHITE}Delhelje STR_CONTENT_DOWNLOAD_PROGRESS_SIZE :{WHITE}{BYTES} fan {BYTES} delhelle ({NUM} %) # Content downloading error messages -STR_CONTENT_ERROR_COULD_NOT_CONNECT :{WHITE}Koe gjin ferbyning mei ynhâldtsjinner meitsje... +STR_CONTENT_ERROR_COULD_NOT_CONNECT :{WHITE}Koe gjin ferbyning mei ynhâldserver meitsje... STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD :{WHITE}Delheljen net slagge... -STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE :{WHITE}... bestân koe net opslein wurde +STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE :{WHITE}... bestân koe net bewarre wurde STR_CONTENT_ERROR_COULD_NOT_EXTRACT :{WHITE}Kin it delhelle bestân net útpakke STR_MISSING_GRAPHICS_SET_CAPTION :{WHITE}Missende ôfbyldings STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}Ja, ôfbyldings delheljen STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}Nee, OpenTTD ôfslute +STR_MISSING_GRAPHICS_ERROR_QUIT :{BLACK}Slút OpenTTD ôf # Transparency settings window STR_TRANSPARENCY_CAPTION :{WHITE}Trochsichtigenopsjes @@ -2226,12 +2263,15 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Frachtst STR_LINKGRAPH_LEGEND_ALL :{BLACK}Alle STR_LINKGRAPH_LEGEND_NONE :{BLACK}Gjin STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Selektearje bedriuwen om sjen te litten +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}net brûkt STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}fersêde STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}oerbeladen +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Ut STR_STATION_BUILD_COVERAGE_ON :{BLACK}Oan @@ -2285,6 +2325,7 @@ STR_STATION_BUILD_NUMBER_OF_TRACKS :{BLACK}Oantal b STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP :{BLACK}Selektear oantal banen foar treinstasjon STR_STATION_BUILD_PLATFORM_LENGTH :{BLACK}Stasjon lengte STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP :{BLACK}Selektear lengte fan treinstasjon +STR_STATION_BUILD_DRAG_DROP :Sleepe en los litte STR_STATION_BUILD_STATION_TYPE_TOOLTIP :{BLACK}Selektearje type stasjon om te bouwe @@ -2299,8 +2340,6 @@ STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Bloksein STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Selektear Spoarbrêge STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Selektear brêge STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Brêge seleksje - klik op de brêge dyst boue wolst -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Hingbrêge, Stiel STR_BRIDGE_NAME_GIRDER_STEEL :Brêge mei balken, Stiel STR_BRIDGE_NAME_CANTILEVER_STEEL :Fakwurkbrêge, Stiel @@ -2325,6 +2364,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Bou in t STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Wikselje tusken bou en fuortheljen fan dyken STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Wikselje tusken bou en fuortheljen fan tramwei +STR_ROAD_NAME_ROAD :Wei # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Autodepot rjochting @@ -2363,7 +2403,7 @@ STR_TOOLBAR_AIRCRAFT_CAPTION :{WHITE}Fleanfji # Airport construction window STR_STATION_BUILD_AIRPORT_CAPTION :{WHITE}Fleanfjild Seleksje -STR_STATION_BUILD_AIRPORT_TOOLTIP :{BLACK}Kies grutte/type fleanfjild +STR_STATION_BUILD_AIRPORT_TOOLTIP :{BLACK}Selektearje grutte en type fan it fleanfjild STR_STATION_BUILD_AIRPORT_CLASS_LABEL :{BLACK}Fleanfjild klasse STR_STATION_BUILD_AIRPORT_LAYOUT_NAME :{BLACK}Patroan {NUM} @@ -2439,7 +2479,7 @@ STR_FOUND_TOWN_INITIAL_SIZE_SMALL_BUTTON :{BLACK}Lyts STR_FOUND_TOWN_INITIAL_SIZE_MEDIUM_BUTTON :{BLACK}Middel STR_FOUND_TOWN_INITIAL_SIZE_LARGE_BUTTON :{BLACK}Grut STR_FOUND_TOWN_SIZE_RANDOM :{BLACK}Samar in getal -STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Selektear de grutte fan 'e stêd +STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Selektearje de grutte fan 'e stêd STR_FOUND_TOWN_CITY :{BLACK}Stêd STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Stêden groeien flugger as doarpen{}Ôfhinklik fan ynstellings binne se grutter at se makke wurde @@ -2454,9 +2494,12 @@ STR_FOUND_TOWN_SELECT_LAYOUT_RANDOM :{BLACK}Samar # Fund new industry window STR_FUND_INDUSTRY_CAPTION :{WHITE}Betelje nije yndustry STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP :{BLACK}Pleats yndustry oer de map hinne +STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_CAPTION :{WHITE}Willekeurich neie yndustryen meitsje STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST :{BLACK}Kostet: {YELLOW}{CURRENCY_LONG} +STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY :{BLACK}Ûndersykje STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY :{BLACK}Bouwe STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY :{BLACK}Finansierje +STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_CAPTION :{WHITE}Alle yndustryen fuorthelje # Industry cargoes window STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION :{WHITE}Yndustrykeatlings foar {STRING} yndustry @@ -2492,6 +2535,8 @@ STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Fleanfji STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Akseptearre fracht: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) +STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Spoarsoart: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Tramsoart: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Faasjelimyt spoar: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Faasjelimyt dyk: {LTBLUE}{VELOCITY} @@ -2593,10 +2638,18 @@ STR_ABOUT_VERSION :{BLACK}OpenTTD- STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-{STRING} It OpenTTD team # Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Byldsnelheid +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Simulaasjesnelheid: {STRING} +STR_FRAMERATE_CURRENT :Aktueel +STR_FRAMERATE_AVERAGE :{WHITE}Gemiddeld +STR_FRAMERATE_MEMORYUSE :{WHITE}Geheugen +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ###length 15 ###length 15 +STR_FRAMETIME_CAPTION_AI :Kompjûterspiler {NUM} {STRING} # Save/load game/scenario @@ -2609,9 +2662,9 @@ STR_SAVELOAD_SAVE_HEIGHTMAP :{WHITE}Hichteka STR_SAVELOAD_HOME_BUTTON :{BLACK}Hjir klikke om nei standert opslach- en laadtriemtafel te gean STR_SAVELOAD_BYTES_FREE :{BLACK}{BYTES} frij STR_SAVELOAD_LIST_TOOLTIP :{BLACK}List fan skiven, mappen en bestânen -STR_SAVELOAD_EDITBOX_TOOLTIP :{BLACK}Op dit stuit selektearre namme foar opslein spul +STR_SAVELOAD_EDITBOX_TOOLTIP :{BLACK}Op dit stuit selektearre namme foar bewarre spul STR_SAVELOAD_DELETE_BUTTON :{BLACK}Fuortsmite -STR_SAVELOAD_DELETE_TOOLTIP :{BLACK}It no selektearre opsleine spul fuortsmite +STR_SAVELOAD_DELETE_TOOLTIP :{BLACK}It no selektearre bewarre spul fuortsmite STR_SAVELOAD_SAVE_BUTTON :{BLACK}Opslaan STR_SAVELOAD_SAVE_TOOLTIP :{BLACK}It hjoeddeisk spul opslaan ûnder de selektearre namme STR_SAVELOAD_LOAD_BUTTON :{BLACK}Laad @@ -2622,7 +2675,7 @@ STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Gjin ynf STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_OSKTITLE :{BLACK}Fier in namme yn foar it opsleine spul +STR_SAVELOAD_OSKTITLE :{BLACK}Fier in namme yn foar it bewarre spul # World generation STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}Wrâldgeneraasje @@ -2630,16 +2683,41 @@ STR_MAPGEN_MAPSIZE :{BLACK}Lângrut STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Selektearje de grutte fan de kaart yn tegels. It tal beskikbere tegels sil leger lizze. STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Oantal stêden: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Stêdnammen +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Selektearje nammestyl STR_MAPGEN_DATE :{BLACK}Datum: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Oantal yndustrien: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Lângenerator: +STR_MAPGEN_SNOW_COVERAGE :{BLACK}Snie-oerflak: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terreintype: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Seenivo: +STR_MAPGEN_SEA_LEVEL :{BLACK}Seenivo: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Rivieren: STR_MAPGEN_SMOOTHNESS :{BLACK}Sljochtens: STR_MAPGEN_VARIETY :{BLACK}Lânskipsfariaasje: STR_MAPGEN_GENERATE :{WHITE}Generearje +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Ingelsk (Orizjineel) +STR_MAPGEN_TOWN_NAME_FRENCH :Frânsk +STR_MAPGEN_TOWN_NAME_GERMAN :Dútsk +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Ingelsk (Ekstra) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latynsk-Amerikaansk +STR_MAPGEN_TOWN_NAME_SILLY :Ût mâlens +STR_MAPGEN_TOWN_NAME_SWEDISH :Sweedsk +STR_MAPGEN_TOWN_NAME_DUTCH :Nederlânsk +STR_MAPGEN_TOWN_NAME_FINNISH :Finsk +STR_MAPGEN_TOWN_NAME_POLISH :Poalsk +STR_MAPGEN_TOWN_NAME_SLOVAK :Slowaaks +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Noorsk +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hongaarsk +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Eastenryksk +STR_MAPGEN_TOWN_NAME_ROMANIAN :Roemeensk +STR_MAPGEN_TOWN_NAME_CZECH :Tsjechysk +STR_MAPGEN_TOWN_NAME_SWISS :Switsersk +STR_MAPGEN_TOWN_NAME_DANISH :Deensk +STR_MAPGEN_TOWN_NAME_TURKISH :Turksk +STR_MAPGEN_TOWN_NAME_ITALIAN :Italjaansk +STR_MAPGEN_TOWN_NAME_CATALAN :Katalaansk + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kaartrânen: STR_MAPGEN_NORTHWEST :{BLACK}Noardwest @@ -2657,6 +2735,7 @@ STR_MAPGEN_HEIGHTMAP_NAME :{BLACK}Namme hi STR_MAPGEN_HEIGHTMAP_SIZE_LABEL :{BLACK}Grutte: STR_MAPGEN_HEIGHTMAP_SIZE :{ORANGE}{NUM} x {NUM} +STR_MAPGEN_SNOW_COVERAGE_QUERY_CAPT :{WHITE}Snie-oerflak (yn %) STR_MAPGEN_START_DATE_QUERY_CAPT :{BLACK}Startjier oanpasse # SE Map generation @@ -2693,7 +2772,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}útgebre STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}NewGRF bestânen diet brûkt wurde STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}NewGRF bestânen diet net brûkt binne STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Selektearje ynstellings: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter namme: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Selektearre ynstellings lade STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Sla ynstellings op STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Sla dizze list op as foarynstelling @@ -2727,7 +2806,10 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}Ferzje: STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Leechte noch wurkjende ferzje: {SILVER}{NUM} STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Palet: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Oarspronklik (W) +STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Oarspronklik (W) / 32 bpp STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Parameters: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PARAMETER_NONE :Gjin STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}gjin ynformaasje beskikber STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}Keppelt bestând koe net fûn wurde @@ -2772,6 +2854,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Foarig f STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Gean tebek nei de foarige ôfbylding, sla pseudo/werkleure/lettertype ôfbyldings oer en begjin wer oernei at it begjin berikke is STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Represintaasje fan de no selektearre ôfbylding. Dizze wurdt net rjochte by it tekenjen STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Ferweech de ôfbylding, feroarje de X en Y útslach + +###length 2 + + STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X útslach: {NUM}, Y útslach: {NUM} (Absolút) STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}X útslach: {NUM}, Y útslach: {NUM} (Relatyf) STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Kies ôfbylding @@ -2784,7 +2870,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Warskôging: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Flater: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatale flater: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Der hat in fatale NewGRF-flater plakfûn:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} sil net wurkje kinne mei de TTDPatch-ferzje dy't troch OpenTTD meldt wurdt STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} is makke foar de {STRING}-ferzje fan TTD STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} makke om te brûken tegeare my{STRING} @@ -2891,6 +2976,7 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Stêdsnamme Fer # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} gemeente +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Sône STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Transportbedrieuwwurdearring: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Mooglike aksjes: @@ -3032,7 +3118,7 @@ STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}Sintrear STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}Feroarje stasjonsnamme -STR_STATION_VIEW_RENAME_STATION_CAPTION :Jow stasjon in nije namme +STR_STATION_VIEW_RENAME_STATION_CAPTION :Jou stasjon in nije namme STR_STATION_VIEW_CLOSE_AIRPORT :{BLACK}Fleanfjild slute @@ -3046,10 +3132,11 @@ STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}Namme fa STR_EDIT_WAYPOINT_NAME :{WHITE}Namme fan kontrôlepost oanpasse # Finances window -STR_FINANCES_CAPTION :{WHITE}{COMPANY} Finansieën {BLACK}{COMPANY_NUM} +STR_FINANCES_CAPTION :{WHITE}{COMPANY} Finânsjes {BLACK}{COMPANY_NUM} STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Kapitaalkosten ###length 13 @@ -3057,16 +3144,19 @@ STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Konstruks STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Nije faartúchen STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Trein Ûnderhâldskosten STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Lânfartugen ûnderhâldskosten -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Fleantúg Ûnderhâldskosten +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Fleantúch Ûnderhâldskosten STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Skip Ûnderhâldskosten -STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Rinte fan Liening +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Ynfrastruktuer +STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Rinte op liening STR_FINANCES_SECTION_OTHER :{GOLD}Oaren -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} -STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Jild +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Eigen fûnsen STR_FINANCES_LOAN_TITLE :{WHITE}Liening -STR_FINANCES_MAX_LOAN :{WHITE}Maksimale Liening: {BLACK}{CURRENCY_LONG} +STR_FINANCES_INTEREST_RATE :{WHITE}Rinte op liening: {BLACK}{NUM}% +STR_FINANCES_MAX_LOAN :{WHITE}Maksimale liening: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Lien {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Lien mear jild. Ctrl+Klik om it maksimale te lienen @@ -3090,6 +3180,7 @@ STR_COMPANY_VIEW_COMPANY_VALUE :{GOLD}Bedriuwsw STR_COMPANY_VIEW_SHARES_OWNED_BY :{WHITE}({COMMA}% besit fan {COMPANY}) STR_COMPANY_VIEW_INFRASTRUCTURE :{GOLD}Ynfrastruktuer: STR_COMPANY_VIEW_INFRASTRUCTURE_ROAD :{WHITE}{COMMA} stikje dyk{P "" s} +STR_COMPANY_VIEW_INFRASTRUCTURE_WATER :{WHITE}{COMMA} wetterfjild{P "" en} STR_COMPANY_VIEW_INFRASTRUCTURE_STATION :{WHITE}{COMMA} stasjontegel{P "" s} STR_COMPANY_VIEW_INFRASTRUCTURE_AIRPORT :{WHITE}{COMMA} fleanfjild{P "" en} STR_COMPANY_VIEW_INFRASTRUCTURE_NONE :{WHITE}Gjin @@ -3100,6 +3191,7 @@ STR_COMPANY_VIEW_VIEW_HQ_BUTTON :{BLACK}Sjoch ha STR_COMPANY_VIEW_VIEW_HQ_TOOLTIP :{BLACK}Haadkantoar besjen STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}Haadkantoar ferpleatse STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}Details +STR_COMPANY_VIEW_GIVE_MONEY_BUTTON :{BLACK}Jou jild STR_COMPANY_VIEW_NEW_FACE_BUTTON :{BLACK}Nei Gesicht STR_COMPANY_VIEW_NEW_FACE_TOOLTIP :{BLACK}Selektear nei gesicht foar de bedriuwslieder @@ -3124,6 +3216,7 @@ STR_BUY_COMPANY_MESSAGE :{WHITE}Wy sykje STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Ynfrastruktuer fan {COMPANY} STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Seinen STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Stikjes dyk: +STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanalen STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stasjons: STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS :{WHITE}Stasjontegels STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS :{WHITE}Fleanfjilden @@ -3133,6 +3226,8 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Yndustryen STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Gjin - STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_FILTER_NONE :Gjin # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} @@ -3142,29 +3237,33 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Sintrear STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Produksje nivo: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Yndustry kundicht drigend sluten oan! +STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Nedichheden: {YELLOW}{STRING}{STRING} +STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Nedichheden: -STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Feroaring produksje nivo (percentage, up to 800%) +STR_CONFIG_GAME_PRODUCTION :{WHITE}Feroarje produksjenivo (mearfâld fan 8, maksimaal 2040) +STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Feroarje produksjenivo (persintaazje, maksimaal 800%) # Vehicle lists ###length VEHICLE_TYPES STR_VEHICLE_LIST_TRAIN_CAPTION :{WHITE}{STRING} - {COMMA} Trein{P "" en} STR_VEHICLE_LIST_ROAD_VEHICLE_CAPTION :{WHITE}{STRING} - {COMMA} Wein{P "" en} -STR_VEHICLE_LIST_SHIP_CAPTION :{WHITE}{STRING} - {COMMA} {P Skip Skepen} +STR_VEHICLE_LIST_SHIP_CAPTION :{WHITE}{STRING} - {COMMA} Skip{P "" "pen"} STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING} - {COMMA} Fleantúch ###length VEHICLE_TYPES STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP :{BLACK}Treinen - klik op trein foar ynformaasje STR_VEHICLE_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Weinen - klik op wein foar ynformaasje -STR_VEHICLE_LIST_SHIP_TOOLTIP :{BLACK}Skepen - klik op skip foar ynformaasje -STR_VEHICLE_LIST_AIRCRAFT_TOOLTIP :{BLACK}Fleantúgen - klik op fleantúch foar ynformaasje +STR_VEHICLE_LIST_SHIP_TOOLTIP :{BLACK}Skippen - klik op skip foar ynformaasje +STR_VEHICLE_LIST_AIRCRAFT_TOOLTIP :{BLACK}Fleantugen - klik op fleantúch foar ynformaasje ###length VEHICLE_TYPES STR_VEHICLE_LIST_AVAILABLE_TRAINS :Beskikbere Treinen STR_VEHICLE_LIST_AVAILABLE_ROAD_VEHICLES :Beskikbere Weinen -STR_VEHICLE_LIST_AVAILABLE_SHIPS :Beskikbere Skepen -STR_VEHICLE_LIST_AVAILABLE_AIRCRAFT :Beskikbere Fleantúgen +STR_VEHICLE_LIST_AVAILABLE_SHIPS :Beskikbere Skippen +STR_VEHICLE_LIST_AVAILABLE_AIRCRAFT :Beskikbere Fleantugen +STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}List beheare STR_VEHICLE_LIST_REPLACE_VEHICLES :Fiertugen ferfange STR_VEHICLE_LIST_SEND_FOR_SERVICING :Stjoer foar ûnderhâldsbeurt STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Fertsjinste dit jier: {CURRENCY_LONG} (ferline jier: {CURRENCY_LONG}) @@ -3181,12 +3280,15 @@ STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP :{BLACK}Klik om ###length VEHICLE_TYPES STR_GROUP_ALL_TRAINS :Alle treinen STR_GROUP_ALL_ROAD_VEHICLES :Alle weinen -STR_GROUP_ALL_SHIPS :Alle skepen +STR_GROUP_ALL_SHIPS :Alle skippen STR_GROUP_ALL_AIRCRAFTS :Alle fleantugen ###length VEHICLE_TYPES -STR_GROUP_DEFAULT_SHIPS :Net groepearre skepen +STR_GROUP_DEFAULT_TRAINS :Net-groepearre treinen +STR_GROUP_DEFAULT_ROAD_VEHICLES :Net-groepearre weinen +STR_GROUP_DEFAULT_SHIPS :Net-groepearre skippen +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) STR_GROUP_CREATE_TOOLTIP :{BLACK}Klik om in groep oan te meitsje STR_GROUP_DELETE_TOOLTIP :{BLACK}Smit de selektearre groep fuort @@ -3197,6 +3299,7 @@ STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Ferwider STR_GROUP_REMOVE_ALL_VEHICLES :Alle fiertugen weihelje +STR_GROUP_PROFIT_THIS_YEAR :Winst dit jier: # Build vehicle window ###length 4 @@ -3205,12 +3308,14 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nije elektryske STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nije Maglev Treinen STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nije Weinen +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Nije trammen # Vehicle availability ###length VEHICLE_TYPES -STR_BUY_VEHICLE_SHIP_CAPTION :Nije Skepen +STR_BUY_VEHICLE_SHIP_CAPTION :Nije Skippen STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nije fleantugen +STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kosten: {GOLD}{CURRENCY_LONG}{BLACK} Gewicht: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Snelheid: {GOLD}{VELOCITY}{BLACK} Kracht: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Snelheid: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Faasje op see: {GOLD}{VELOCITY} @@ -3228,36 +3333,40 @@ STR_PURCHASE_INFO_ALL_TYPES :Alle frachttype STR_PURCHASE_INFO_ALL_BUT :Alles útsein {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Maks. Lûkkrêft: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Berik: {GOLD}{COMMA} flakken +STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Fleantúch type: {GOLD}{STRING} + +###length 3 ###length VEHICLE_TYPES ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Keapje auto +STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Keapje trein STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Keapje auto -STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Keapje boat -STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Keapje fleantúg +STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Keapje skip +STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Keapje fleantúch ###length VEHICLE_TYPES +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Auto keapje en ferbouwe ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Keapje ferljochte trein -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Keapje ferljochte auto -STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Keapje ferljochte boat -STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Keapje ferljochte fleantúg +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Keapje ferljochte auto. Shift+Klik toant ferwachte kosten sûnder te keapje +STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Keapje ferljochte skip. Shift+Klik toant ferwachte kosten sûnder te keapje +STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Keapje ferljochte fleantúch. Shift+Klik toant ferwachte kosten sûnder te keapje ###length VEHICLE_TYPES ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Jow in nije namme -STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Jow in nije namme -STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Jow in nije namme -STR_BUY_VEHICLE_AIRCRAFT_RENAME_BUTTON :{BLACK}Jow in nije namme +STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Jou in nije namme +STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Jou in nije namme +STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Jou in nije namme +STR_BUY_VEHICLE_AIRCRAFT_RENAME_BUTTON :{BLACK}Jou in nije namme ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_RENAME_TOOLTIP :{BLACK}Jow trein in nije namme -STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_TOOLTIP :{BLACK}Jow auto in nije namme -STR_BUY_VEHICLE_SHIP_RENAME_TOOLTIP :{BLACK}Jow boat type in nije namme -STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}Fleantúch type in nije nammer jaan +STR_BUY_VEHICLE_TRAIN_RENAME_TOOLTIP :{BLACK}Treintype neame +STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_TOOLTIP :{BLACK}Autotype neame +STR_BUY_VEHICLE_SHIP_RENAME_TOOLTIP :{BLACK}Skiptype neame +STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}Fleantúchtype neame ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_HIDE_TOGGLE_BUTTON :{BLACK}Ferbergje @@ -3278,8 +3387,9 @@ STR_BUY_VEHICLE_SHIP_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Wikselje STR_BUY_VEHICLE_AIRCRAFT_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Wikselje tusken it ferbergje/sjen litte fan it soart fleanmasine ###length VEHICLE_TYPES -STR_QUERY_RENAME_TRAIN_TYPE_CAPTION :{WHITE}Jou treinmodel in oare namme -STR_QUERY_RENAME_AIRCRAFT_TYPE_CAPTION :{WHITE}Fleantúch type in nije namme jaan +STR_QUERY_RENAME_TRAIN_TYPE_CAPTION :{WHITE}Treintype neame +STR_QUERY_RENAME_ROAD_VEHICLE_TYPE_CAPTION :{WHITE}Jou fiertug in nije namme +STR_QUERY_RENAME_AIRCRAFT_TYPE_CAPTION :{WHITE}Fleantúchtype neame # Depot window STR_DEPOT_CAPTION :{WHITE}{DEPOT} @@ -3293,27 +3403,28 @@ STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} ###length VEHICLE_TYPES STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Weinen - Brûk rjochter mûsklik op de wein foar ynformaasje -STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}Skepen - Brûk rjochter mûsklik op it skip foar ynformaasje +STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}Skippen - Brûk rjochter mûsklik op it skip foar ynformaasje ###length VEHICLE_TYPES -STR_DEPOT_TRAIN_SELL_TOOLTIP :{BLACK}tôgje trein hjirhinne om it te ferkeapjen. -STR_DEPOT_ROAD_VEHICLE_SELL_TOOLTIP :{BLACK}tôgje wein hjirhinne om it te ferkeapjen. +STR_DEPOT_TRAIN_SELL_TOOLTIP :{BLACK}Tôgje trein hjirhinne om it te ferkeapjen +STR_DEPOT_ROAD_VEHICLE_SELL_TOOLTIP :{BLACK}Tôgje wein hjirhinne om it te ferkeapjen STR_DEPOT_SHIP_SELL_TOOLTIP :{BLACK}Tôgje skip hjirhinne om it te ferkeapjen -STR_DEPOT_AIRCRAFT_SELL_TOOLTIP :{BLACK}tôgje fleantúg hjirhinne om it te ferkeapjen. +STR_DEPOT_AIRCRAFT_SELL_TOOLTIP :{BLACK}Tôgje fleantúch hjirhinne om it te ferkeapjen ###length VEHICLE_TYPES STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TOOLTIP :{BLACK}Ferkeapje alle treinen yn dit depot STR_DEPOT_SELL_ALL_BUTTON_ROAD_VEHICLE_TOOLTIP :Ferkeapje alle weinen yn disse garage +STR_DEPOT_SELL_ALL_BUTTON_SHIP_TOOLTIP :{BLACK}Ferkeapje alle skippen yn dit dok STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TOOLTIP :{BLACK}Ferkeapje alle fleantugen yn hangar ###length VEHICLE_TYPES -STR_DEPOT_AUTOREPLACE_SHIP_TOOLTIP :{BLACK}Ferfang automatysk skippen yn de skipmakkerij -STR_DEPOT_AUTOREPLACE_AIRCRAFT_TOOLTIP :{BLACK}Ferfang automatysk alle fleantúgen yn disse fleantúchhangaar +STR_DEPOT_AUTOREPLACE_SHIP_TOOLTIP :{BLACK}Ferfang automatysk skippen yn it dok +STR_DEPOT_AUTOREPLACE_AIRCRAFT_TOOLTIP :{BLACK}Ferfang automatysk alle fleantugen yn disse fleantúchhangaar ###length VEHICLE_TYPES STR_DEPOT_TRAIN_NEW_VEHICLES_BUTTON :{BLACK}Nije fiertugen STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_BUTTON :{BLACK}Nije Weinen -STR_DEPOT_SHIP_NEW_VEHICLES_BUTTON :{BLACK}Nije Skepen +STR_DEPOT_SHIP_NEW_VEHICLES_BUTTON :{BLACK}Nije Skippen STR_DEPOT_AIRCRAFT_NEW_VEHICLES_BUTTON :{BLACK}Nije Fleantugen ###length VEHICLE_TYPES @@ -3322,6 +3433,7 @@ STR_DEPOT_SHIP_NEW_VEHICLES_TOOLTIP :{BLACK}Nij skip STR_DEPOT_AIRCRAFT_NEW_VEHICLES_TOOLTIP :{BLACK}Nij fleantúch keapje ###length VEHICLE_TYPES +STR_DEPOT_CLONE_TRAIN :{BLACK}Trein klone ###length VEHICLE_TYPES @@ -3332,10 +3444,10 @@ STR_DEPOT_AIRCRAFT_NEW_VEHICLES_TOOLTIP :{BLACK}Nij flea ###length VEHICLE_TYPES STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP :{BLACK}Klik om alle treinen yn dit depot te stopjen STR_DEPOT_MASS_STOP_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Klik om alle weinen yn dizze garaazje te stopjen -STR_DEPOT_MASS_STOP_HANGAR_TOOLTIP :{BLACK}Klik om alle fleantugen yn dizze hangar te stopje +STR_DEPOT_MASS_STOP_HANGAR_TOOLTIP :{BLACK}Klik om alle fleantugen yn dizze hangaar te stopje ###length VEHICLE_TYPES -STR_DEPOT_MASS_START_DEPOT_SHIP_TOOLTIP :{BLACK}Klik om alle skepen te starte +STR_DEPOT_MASS_START_DEPOT_SHIP_TOOLTIP :{BLACK}Klik om alle skippen in it dok te starte # Engine preview window @@ -3347,6 +3459,7 @@ STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monorail lokomo STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglevlokomotyf STR_ENGINE_PREVIEW_ROAD_VEHICLE :wein +STR_ENGINE_PREVIEW_TRAM_VEHICLE :tram STR_ENGINE_PREVIEW_AIRCRAFT :fleantúch STR_ENGINE_PREVIEW_SHIP :skip @@ -3371,6 +3484,7 @@ STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Selektea STR_REPLACE_VEHICLES_NOW :No alle fiertugen ferfange STR_REPLACE_VEHICLES_WHEN_OLD :Ferfang allinech âlde weinen +STR_REPLACE_ENGINES :Motoaren ###length 2 ###next-name-looks-similar @@ -3378,6 +3492,7 @@ STR_REPLACE_VEHICLES_WHEN_OLD :Ferfang allinec STR_REPLACE_MONORAIL_VEHICLES :Monorail weinen STR_REPLACE_MAGLEV_VEHICLES :Maglev treinen +STR_REPLACE_TRAM_VEHICLES :Trams # Vehicle view @@ -3386,14 +3501,15 @@ STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE ###length VEHICLE_TYPES ###length VEHICLE_TYPES -STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}Stjoer trein nei depot. Brûk Ctrl+Klik om allinich ûnderhâld te jaan -STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Stjoer wein nei garaazje. Brûk Ctrl+Klik om allinich ûnderhâld te jaan -STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Stjoer skip nij skipmakkerij. Brûk Ctrl+klik om skip ûnderhâld te jaan -STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Stjoer fleantúch nei hanger. Brûk Ctrl+klik om allinich ûnderhald te jaan +STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}Stjoer trein nei depot. Ctrl+Klik om allinich ûnderhâld te jaan +STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Stjoer wein nei garaazje. Ctrl+Klik om allinich ûnderhâld te jaan +STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Stjoer skip nij skipmakkerij. Ctrl+klik om skip ûnderhâld te jaan +STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Stjoer fleantúch nei hangaer. Ctrl+klik om allinich ûnderhald te jaan ###length VEHICLE_TYPES STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}Rydrjochting fan trein omkeare +STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :Lit fiertug omkeare ###length VEHICLE_TYPES STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Trein ombouwe om in oar soart fracht mei te nimmen @@ -3413,6 +3529,7 @@ STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Fleantú # Messages in the start stop button in the vehicle view STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}Laden / Losse STR_VEHICLE_STATUS_LEAVING :{LTBLUE}fuortsette +STR_VEHICLE_STATUS_CRASHED :{RED}Ferûngelokke! STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}Stikken STR_VEHICLE_STATUS_STOPPED :{RED}Stoppe STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL :{RED}Stoppet, {VELOCITY} @@ -3425,6 +3542,7 @@ STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Ûnderw STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL :{ORANGE}Ûnderweis nei{DEPOT}, {VELOCITY} STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL :{LTBLUE}ûnderhâld yn {DEPOT}, {VELOCITY} +STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_SERVICE_VEL :{LTBLUE}Kin {DEPOT}, {VELOCITY} net berikke # Vehicle stopped/started animations ###length 2 @@ -3442,12 +3560,14 @@ STR_VEHICLE_DETAILS_CAPTION :{WHITE}{VEHICLE STR_VEHICLE_DETAILS_TRAIN_RENAME :{BLACK}Jou trein in namme STR_VEHICLE_DETAILS_ROAD_VEHICLE_RENAME :{BLACK}Namme fan de wein STR_VEHICLE_DETAILS_SHIP_RENAME :{BLACK}Skip in namme jaan +STR_VEHICLE_DETAILS_AIRCRAFT_RENAME :{BLACK}Fleantúch neame STR_VEHICLE_INFO_AGE :{COMMA} jier{P "" ren} ({COMMA}) STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} jier{P "" ren} ({COMMA}) STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Maks. snelheid: {LTBLUE}{VELOCITY} -STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Gewicht: {LTBLUE}{WEIGHT_SHORT} {BLACK}Krêft: {LTBLUE}{POWER}{BLACK} Maks. faasje: {LTBLUE}{VELOCITY} +STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Gewicht: {LTBLUE}{WEIGHT_SHORT} {BLACK}Krêft: {LTBLUE}{POWER}{BLACK} Maks. snelheid: {LTBLUE}{VELOCITY} +STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Gewicht: {LTBLUE}{WEIGHT_SHORT} {BLACK}Krêft: {LTBLUE}{POWER}{BLACK} Maks. snelheid: {LTBLUE}{VELOCITY} {BLACK}Maks. lûkkrêft: {LTBLUE}{FORCE} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}betrouberens: {LTBLUE}{COMMA}% {BLACK}Stikken west sûnt lêste ûnderhâld: {LTBLUE}{COMMA} @@ -3495,13 +3615,15 @@ STR_VEHICLE_DETAIL_TAB_TOTAL_CARGO :{BLACK}Totale F STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}Kapasiteit: {LTBLUE} # Vehicle refit +STR_REFIT_CAPTION :{WHITE}{VEHICLE} (Ombouwe) STR_REFIT_TITLE :{GOLD}Selektearje it soart fracht om mei te nimmen: STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nije kapasiteit: {GOLD}{CARGO_LONG}{}{BLACK}Kosten fan ombou: {RED}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Nije kapasiteit: {GOLD}{CARGO_LONG}{}{BLACK}Ynkomsten fan ombouw: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Nije kapasiteit: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}kosten fan werfolje: {RED}{CURRENCY_LONG} STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Selektearje in ferfiermiddel foar reparaasje. sleep mei de mûs om meardere ferfiermiddels te selekttearjen. Ctrl+klick sil in ferfiermiddel selektearje en de neikommende rige ###length VEHICLE_TYPES -STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}selektearje soart fracht foar de trein om mei te nimmen +STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Selektearje soart fracht foar de trein om mei te nimmen STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Selektearje it soart fracht foar wein om mei te nimmen STR_REFIT_SHIP_LIST_TOOLTIP :{BLACK}Selektearje it soart fracht foar it skip om mei te nimmen STR_REFIT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Selektearje it soart fracht foar it fleantúch om mei te nimmen @@ -3519,6 +3641,7 @@ STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}Skip omb STR_REFIT_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Fleantúch ombouwe nei selektearre fracht # Order view +STR_ORDERS_CAPTION :{WHITE}{VEHICLE} (Oarders) STR_ORDERS_TIMETABLE_VIEW :{BLACK}Tjinstregeling STR_ORDER_INDEX :{COMMA}:{NBSP} @@ -3535,10 +3658,12 @@ STR_ORDER_TOOLTIP_NON_STOP :{BLACK}Feroarje STR_ORDER_TOGGLE_FULL_LOAD :{BLACK}Alle fracht folslein lade STR_ORDER_DROP_LOAD_IF_POSSIBLE :Lade as beskikber +STR_ORDER_DROP_FULL_LOAD_ALL :Alle fracht folslein lade STR_ORDER_DROP_FULL_LOAD_ANY :Samar in fracht folslein lade STR_ORDER_DROP_NO_LOADING :Net laden STR_ORDER_TOGGLE_UNLOAD :{BLACK}Alles losse +STR_ORDER_DROP_UNLOAD_IF_ACCEPTED :Losse as it oannaam wurd STR_ORDER_DROP_UNLOAD :Alles losse STR_ORDER_DROP_TRANSFER :Oerlade STR_ORDER_DROP_NO_UNLOADING :Net losse @@ -3556,14 +3681,26 @@ STR_ORDER_SERVICE_TOOLTIP :{BLACK}Sla dizz # Conditional order variables, must follow order of OrderConditionVariable enum ###length 8 +STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE :Laadpersintaazje STR_ORDER_CONDITIONAL_RELIABILITY :Betrouberens STR_ORDER_CONDITIONAL_MAX_SPEED :Maksimale snelheid STR_ORDER_CONDITIONAL_AGE :âlderdom (yn jierren) +STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :Ûnderhâld nedich STR_ORDER_CONDITIONAL_UNCONDITIONALLY :Altyd +STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :Restearjende libbensdoer (jieren) +STR_ORDER_CONDITIONAL_MAX_RELIABILITY :Maksimale betrouberheid ###next-name-looks-similar +STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :is gelyk oan +STR_ORDER_CONDITIONAL_COMPARATOR_NOT_EQUALS :is net gelyk oan +STR_ORDER_CONDITIONAL_COMPARATOR_LESS_THAN :is minder as +STR_ORDER_CONDITIONAL_COMPARATOR_LESS_EQUALS :is minder of gelyk oan +STR_ORDER_CONDITIONAL_COMPARATOR_MORE_THAN :is mear as +STR_ORDER_CONDITIONAL_COMPARATOR_MORE_EQUALS :is minder as +STR_ORDER_CONDITIONAL_COMPARATOR_IS_TRUE :is wier STR_ORDER_CONDITIONAL_COMPARATOR_IS_FALSE :is net wier +STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Wearde om mei te ferlykjen STR_ORDERS_SKIP_BUTTON :{BLACK}Oerslaan @@ -3574,6 +3711,7 @@ STR_ORDERS_STOP_SHARING_BUTTON :{BLACK}Stop die STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}Stopje mei dielde bestimmingen STR_ORDERS_GO_TO_BUTTON :{BLACK}Gean Nei +STR_ORDER_CONDITIONAL :Kondisjoneel nei oarder ljeppe STR_ORDER_SHARE :Dielde Bestimmingen @@ -3595,6 +3733,7 @@ STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT :{STRING} {STRIN STR_ORDER_GO_TO_DEPOT_FORMAT :{STRING} {DEPOT} STR_ORDER_REFIT_ORDER :(Ombouwe nij {STRING}) +STR_ORDER_REFIT_STOP_ORDER :(Ombouwe nei {STRING} en stopje) STR_ORDER_STOP_ORDER :(Stop) STR_ORDER_GO_TO_STATION :{STRING} {STATION} {STRING} @@ -3604,8 +3743,8 @@ STR_ORDER_IMPLICIT :(Ymplisyt) STR_ORDER_FULL_LOAD :(Folle fracht) STR_ORDER_FULL_LOAD_ANY :(Samar in fracht folslein lade) STR_ORDER_NO_LOAD :(Gjin lading) -STR_ORDER_UNLOAD :(Afladen en nim lading -STR_ORDER_UNLOAD_FULL_LOAD :(Afladen en wacht foar folle fracht) +STR_ORDER_UNLOAD :(Losse en fracht meinimme) +STR_ORDER_UNLOAD_FULL_LOAD :(Losse en wacht foar folle fracht) STR_ORDER_UNLOAD_FULL_LOAD_ANY :(Losse en wachtsje foar ien folle fracht) STR_ORDER_UNLOAD_NO_LOAD :(Oflade en lit leech) STR_ORDER_TRANSFER :(Oerladen en fracht meinimme) @@ -3634,9 +3773,9 @@ STR_ORDER_STOP_LOCATION_FAR_END :[ein] STR_ORDER_OUT_OF_RANGE :{RED} (Folgjende bestimming is bûten berik) -STR_ORDER_CONDITIONAL_UNCONDITIONAL :Ljep nei opdracht {COMMA} -STR_ORDER_CONDITIONAL_NUM :Ljep nei opdracht {COMMA} at {STRING} {STRING} {COMMA} -STR_ORDER_CONDITIONAL_TRUE_FALSE :Ljep nei opdracht {COMMA} at {STRING} {STRING} +STR_ORDER_CONDITIONAL_UNCONDITIONAL :Ljep nei oarder {COMMA} +STR_ORDER_CONDITIONAL_NUM :Ljep nei oarder {COMMA} as {STRING} {STRING} {COMMA} +STR_ORDER_CONDITIONAL_TRUE_FALSE :Ljep nei oarder {COMMA} as {STRING} {STRING} STR_INVALID_ORDER :{RED} (Unjildige opdracht) @@ -3644,6 +3783,7 @@ STR_INVALID_ORDER :{RED} (Unjildig STR_TIMETABLE_ORDER_VIEW :{BLACK}Opdrachten +STR_TIMETABLE_NO_TRAVEL :Net reizgje STR_TIMETABLE_NOT_TIMETABLEABLE :Reizgje (automatic; timetabled by next manual order) STR_TIMETABLE_TRAVEL_FOR_SPEED :Reis {STRING} mei maksimum {VELOCITY} STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Reizgje (foar {STRING}, sûnder tsjinstregeling) @@ -3655,7 +3795,8 @@ STR_TIMETABLE_DAYS :{COMMA}{NBSP}{P STR_TIMETABLE_TICKS :{COMMA}{NBSP}tik{P "" ken} -STR_TIMETABLE_STATUS_ON_TIME :{BLACK}Dit fiertûg is op tiid +STR_TIMETABLE_STATUS_ON_TIME :{BLACK}Dit fiertûch is op tiid +STR_TIMETABLE_STATUS_EARLY :{BLACK}Dit fiertûch is {STRING} te betiid STR_TIMETABLE_STARTING_DATE :{BLACK}Begjin datum @@ -3699,16 +3840,16 @@ STR_AI_DEBUG_CONTINUE :{BLACK}Trjochge STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}Lit debug output fan dizze AI sjen STR_AI_GAME_SCRIPT :{BLACK}Spulskript -STR_ERROR_AI_NO_AI_FOUND :Gjin geskikte compjûterspiler fûn.{}Disse compjûterspiler is in dummy en docht neat.{}Jo kinne compjûterspilers delhelje fan 'Online Inhâld' ôf. -STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/Spulskript debugskerm is allinich beskikber foar de tsjinner +STR_ERROR_AI_NO_AI_FOUND :Gjin geskikte kompjûterspiler fûn.{}Disse kompjûterspiler is in dummy en docht neat.{}Jo kinne kompjûterspilers delhelje fan 'Online Inhâld' ôf. +STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/Spulskript debugskerm is allinich beskikber foar de server # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI/Spulskript konfiguraasje STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}It spulskript dat yn it folgjende spul laden sil wurde STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AIs dy't yn it folgjende spul laden sille wurde STR_AI_CONFIG_HUMAN_PLAYER :Minslike spiler STR_AI_CONFIG_RANDOM_AI :Samar in AI STR_AI_CONFIG_NONE :(gjin) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maksimum oantal tsjinstanners: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Pleats heger STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Set selektearre AI boppenoan de list @@ -3717,8 +3858,6 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Pleats l STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spulskript STR_AI_CONFIG_AI :{SILVER}AIs -STR_AI_CONFIG_CHANGE :{BLACK}Selektear {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :AI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Spulskript STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}in oar script lade @@ -3741,10 +3880,8 @@ STR_AI_LIST_CANCEL :{BLACK}Annulear STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Skript net feroare -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spulskript STR_AI_SETTINGS_CLOSE :{BLACK}Slúte STR_AI_SETTINGS_RESET :{BLACK}Weromsette STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -3752,6 +3889,7 @@ STR_AI_SETTINGS_SETTING :{STRING}: {ORAN # Textfile window STR_TEXTFILE_WRAP_TEXT :{WHITE}Omwikkelje tekst +STR_TEXTFILE_VIEW_README :{BLACK}Besjoch readme STR_TEXTFILE_VIEW_CHANGELOG :{BLACK}Feroarings STR_TEXTFILE_VIEW_LICENCE :{BLACK}Lisinsje ###length 3 @@ -3782,6 +3920,7 @@ STR_MESSAGE_ESTIMATED_COST :{WHITE}Dit gjit STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Dit gjit {CURRENCY_LONG} opbringen. # Saveload messages +STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Spul noch an it bewarjen,{}graach nog efkes geduld! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Automatysk opslaan net slagge STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Koe net fan 'e skiif lêze STR_ERROR_GAME_SAVE_FAILED :{WHITE}Opslaan Mislearre{}{STRING} @@ -3789,6 +3928,7 @@ STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kin best STR_ERROR_GAME_LOAD_FAILED :{WHITE}Laden Mislearre{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interne flater: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Stikkene savegame - {STRING} +STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spul is makke mei in neiere fersje STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE :Koe bestân net lêze STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE :Koe net nei bestân skriuwe STR_GAME_SAVELOAD_NOT_AVAILABLE : @@ -3806,7 +3946,7 @@ STR_ERROR_HEIGHTMAP_TOO_LARGE :{WHITE}... ôfb # Screenshot related messages STR_WARNING_SCREENSHOT_SIZE_CAPTION :{WHITE}Grutte skermôfbylding -STR_MESSAGE_SCREENSHOT_SUCCESSFULLY :{WHITE}Skermfoto opslein as '{STRING}' +STR_MESSAGE_SCREENSHOT_SUCCESSFULLY :{WHITE}Skermfoto bewarre as '{STRING}' STR_ERROR_SCREENSHOT_FAILED :{WHITE}Koe gjin skermfoto meitsje! # Error message titles @@ -4070,61 +4210,62 @@ STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Kin diel STR_ERROR_TRAIN_IN_THE_WAY :{WHITE}Trein yn it paad STR_ERROR_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Auto yn it paad STR_ERROR_SHIP_IN_THE_WAY :{WHITE}Skip yn it paad -STR_ERROR_AIRCRAFT_IN_THE_WAY :{WHITE}Fleantúg yn it paad +STR_ERROR_AIRCRAFT_IN_THE_WAY :{WHITE}Fleantúch yn it paad ###length VEHICLE_TYPES STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE :{WHITE}Trein is net beskikber STR_ERROR_ROAD_VEHICLE_NOT_AVAILABLE :{WHITE}Wein is net beskikber STR_ERROR_SHIP_NOT_AVAILABLE :{WHITE}Skip is net beskikber -STR_ERROR_AIRCRAFT_NOT_AVAILABLE :{WHITE}Fleantúg is net beskikber +STR_ERROR_AIRCRAFT_NOT_AVAILABLE :{WHITE}Fleantúch is net beskikber ###length VEHICLE_TYPES STR_ERROR_CAN_T_REFIT_TRAIN :{WHITE}Kin trein net werútrisse STR_ERROR_CAN_T_REFIT_ROAD_VEHICLE :{WHITE}Kin auto net ombouwe STR_ERROR_CAN_T_REFIT_SHIP :{WHITE}Kin skip net oanpasse -STR_ERROR_CAN_T_REFIT_AIRCRAFT :{WHITE}kin fleantúg net veroarje +STR_ERROR_CAN_T_REFIT_AIRCRAFT :{WHITE}Kin fleantúch net ombouwe ###length VEHICLE_TYPES STR_ERROR_CAN_T_RENAME_TRAIN :{WHITE}Kin trein net neamje... STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Kin auto net neamje... STR_ERROR_CAN_T_RENAME_SHIP :{WHITE}Kin skip net neamje... -STR_ERROR_CAN_T_RENAME_AIRCRAFT :{WHITE}Kin fleantúg net neamje... +STR_ERROR_CAN_T_RENAME_AIRCRAFT :{WHITE}Kin fleantúch net neame... ###length VEHICLE_TYPES STR_ERROR_CAN_T_STOP_START_TRAIN :{WHITE}Kin trein net stoppe/starte... STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Kin wein net stoppe/starte... STR_ERROR_CAN_T_STOP_START_SHIP :{WHITE}Kin skip net stoppe/starte... -STR_ERROR_CAN_T_STOP_START_AIRCRAFT :{WHITE}Kin fleantúg net stoppe/starte... +STR_ERROR_CAN_T_STOP_START_AIRCRAFT :{WHITE}Kin fleantúch net stoppe/starte... ###length VEHICLE_TYPES STR_ERROR_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Kin trein net nei depot stjoere... STR_ERROR_CAN_T_SEND_ROAD_VEHICLE_TO_DEPOT :{WHITE}Kin wein net nei depot stjoere... STR_ERROR_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Kin skip net nei depot stjoere... -STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR :{WHITE}Kin fleantúg net nei hangar stjoere... +STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR :{WHITE}Kin fleantúch net nei hangaar stjoere... ###length VEHICLE_TYPES STR_ERROR_CAN_T_BUY_TRAIN :{WHITE}Kin gjin trein keapje... STR_ERROR_CAN_T_BUY_ROAD_VEHICLE :{WHITE}Kin gjin auto keapje... -STR_ERROR_CAN_T_BUY_SHIP :{WHITE}Kin gjin boat keapje... -STR_ERROR_CAN_T_BUY_AIRCRAFT :{WHITE}Kin gjin fleantúg keapje... +STR_ERROR_CAN_T_BUY_SHIP :{WHITE}Kin skip net keapje... +STR_ERROR_CAN_T_BUY_AIRCRAFT :{WHITE}Kin gjin fleantúch keapje... ###length VEHICLE_TYPES STR_ERROR_CAN_T_RENAME_TRAIN_TYPE :{WHITE}Kin trein type gjin nije namme joan... STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Kin wein type gjin nije namme jaan... STR_ERROR_CAN_T_RENAME_SHIP_TYPE :{WHITE}Kin skiptype gjin nije namme jaan... -STR_ERROR_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Kin fleantúgtype gjin nije namme jaan... +STR_ERROR_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Kin fleantúchtype net neame... ###length VEHICLE_TYPES STR_ERROR_CAN_T_SELL_TRAIN :{WHITE}Kin trein net ferkeapje... STR_ERROR_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Kin wein net ferkeapje... STR_ERROR_CAN_T_SELL_SHIP :{WHITE}Kin skip net ferkeapje... -STR_ERROR_CAN_T_SELL_AIRCRAFT :{WHITE}Kin fleantúg net ferkeapje... +STR_ERROR_CAN_T_SELL_AIRCRAFT :{WHITE}Kin fleantúch net ferkeapje... STR_ERROR_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Te folle fartugen yn it spul STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Kin tiid tusken ûnderhâldsbeurten net feroarje... STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... wein verneatige + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Hielendal gjin fiertugen talitten STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Feroarje jo NewGRF-konfiguraasje STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Der binne noch gjin fiertugen beskikber @@ -4137,7 +4278,7 @@ STR_ERROR_TRAIN_START_NO_POWER :Trein hat gjin STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN :{WHITE}Wein kin net omkeare -STR_ERROR_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Fleantúg is oan it fleanen +STR_ERROR_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Fleantúch is oan it fleanen # Order related errors STR_ERROR_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Gjin romte mear foar opdrachten @@ -4158,6 +4299,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Kin best STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... te fier fan lêste bestimming STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... fleantúch hat in te lege aksjeradius +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kin gjin tsjinst meitsje STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Auto's kinne allinech op stations wachtsje @@ -4266,10 +4409,10 @@ STR_INDUSTRY_NAME_SUGAR_MINE :Sûkermyn ##id 0x6000 STR_SV_EMPTY : STR_SV_UNNAMED :Net neamt -STR_SV_TRAIN_NAME :Trein {COMMA} -STR_SV_ROAD_VEHICLE_NAME :Lânfartúg {COMMA} -STR_SV_SHIP_NAME :Skip {COMMA} -STR_SV_AIRCRAFT_NAME :Fleantúg {COMMA} +STR_SV_TRAIN_NAME :Trein #{COMMA} +STR_SV_ROAD_VEHICLE_NAME :Lânfartúg #{COMMA} +STR_SV_SHIP_NAME :Skip #{COMMA} +STR_SV_AIRCRAFT_NAME :Fleantúch {COMMA} ###length 27 STR_SV_STNAME :{STRING} @@ -4523,8 +4666,8 @@ STR_VEHICLE_NAME_SHIP_CHUGGER_CHUG_PASSENGER :Chugger-Chug Pa STR_VEHICLE_NAME_SHIP_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Passazjier Fearboat STR_VEHICLE_NAME_SHIP_YATE_CARGO_SHIP :Yate Frachtskip STR_VEHICLE_NAME_SHIP_BAKEWELL_CARGO_SHIP :Bakewell Frachtskip -STR_VEHICLE_NAME_SHIP_MIGHTYMOVER_CARGO_SHIP :MightyMover Guod boat -STR_VEHICLE_NAME_SHIP_POWERNAUT_CARGO_SHIP :Powernaut Guodskip +STR_VEHICLE_NAME_SHIP_MIGHTYMOVER_CARGO_SHIP :MightyMover Frachtskip +STR_VEHICLE_NAME_SHIP_POWERNAUT_CARGO_SHIP :Powernaut Frachtskip ###length 41 STR_VEHICLE_NAME_AIRCRAFT_SAMPSON_U52 :Sampson U52 diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index 9aa134f5b8c74..ff92ba0ff6be1 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -385,6 +385,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -562,10 +563,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Fàg an-seo # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Roghainnean a' gheama STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Roghainnean -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Roghainnean IF/sgriobt geama STR_SETTINGS_MENU_NEWGRF_SETTINGS :Roghainnean NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Roghainnean trìd-shoilleireachd STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Ainmean nam bailtean gan sealltainn @@ -1129,36 +1129,6 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :Gnàthaichte... STR_GAME_OPTIONS_CURRENCY_GEL :Lari Cairtbheileach (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iorànach (IRR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Draibheadh air an taobh chlì -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Draibheadh air an taobh deas - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Ainmean bhailtean -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Tagh stoidhle aig ainmean nam bailtean - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Beurla (Tùsail) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Frangach -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Gearmailteach -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Beurla (a bharrachd) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Aimeireaga Laidinneach -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Gòrach -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Suaineach -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Duitseach -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Fionnlannach -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Pòlannach -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slòbhacach -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Nirribheach -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungaireach -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Ostaireach -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romàineach -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Seiceach -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Eilbheiseach -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danmhairgeach -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turcach -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Eadailteach -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalanach - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Fèin-shàbhaladh STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Tagh dè cho tric ’s a thèid an geama fèin-shàbhaladh @@ -1183,12 +1153,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :Gnàthaichte -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Meud na h-eadar-aghaidh -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Tagh am meud airson rud san eadar-aghaidh - -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Àbhaisteach -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dà uiread a mheud -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Ceithir uiread a mheud @@ -1237,8 +1201,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Ro-shea STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 not (£) san airgeadra agad STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Atharraich paramadair an airgeadra ghnàthaichte -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Àireamh as motha dhe cho-fharpaisich: {ORANGE}{COMMA} - STR_NONE :Chan eil gin STR_FUNDING_ONLY :Le maoineachadh a-mhàin STR_MINIMAL :As lugha @@ -1288,6 +1250,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Cruth-tìre measarra +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Cruth-tìre fo-artach +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Cruth-tìre fo-thropaigeach +STR_CLIMATE_TOYLAND_LANDSCAPE :Cruth-tìre nan dèideag + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Glè rèidh STR_TERRAIN_TYPE_FLAT :Rèidh @@ -1361,6 +1329,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Ris an taobh de STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Iasad tòiseachaidh as motha: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :An t-airgead as motha as urrainn dha chompanaidh fhaighinn mar iasad (a' fàgail an atmhorachd dhan darna taobh) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Luach-rèidh: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Luach-rèidh iasaid; stiùiridh seo an atmhorachd cuideachd ma tha e an comas @@ -1623,6 +1592,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Leasaichte STR_CONFIG_SETTING_ROAD_SIDE :Carbadan-rathaid: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Tagh an taobh air an draibhear +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Draibheadh air an taobh chlì +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Draibheadh air an taobh deas + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Cuairteachadh a' mhapa-àirde: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Tuathal @@ -2100,7 +2073,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Taobh contrarra STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Faodaidh trèanaichean tilleadh aig comharra nuair a bhios iad air feitheamh ann ùine fada ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(molta) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(molta) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Atharraich luach na roghainn @@ -2141,7 +2114,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Clàr na STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Roghainnean STR_INTRO_NEWGRF_SETTINGS :{BLACK}Roghainnean NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Susbaint air loidhne -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Roghainnean sgriobt IF/Geama STR_INTRO_QUIT :{BLACK}Fàg an-seo STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Tòisich geama ùr. Ctrl+Briogadh gus leum thairis air rèiteachadh a mhapa @@ -2161,7 +2133,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Seall cl STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Roghainnean an t-seallaidh STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Seall na roghainnean NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Thoir sùil airson susbainte ùire no air a h-ùrachadh ri luchdadh a-nuas -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Seall roghainnean sgriobt IF/geama STR_INTRO_TOOLTIP_QUIT :{BLACK}Fàg “OpenTTD" STR_INTRO_BASESET :{BLACK}Tha {NUM} {P sprìd sprìd sprìdean sprìd} a dhìth air an t-seata grafaigeachd bhunasach a thagh thu. Thoir sùil airson ùrachaidhean an t-seata bhunasaich. @@ -2191,12 +2162,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Atharra STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Atharraich am bliadhna an-dràsta STR_CHEAT_SETUP_PROD :{LTBLUE}Cuir an comas atharrachadh air luachan saothrachaidh: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Cruth-tìre measarra -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Cruth-tìre fo-artach -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Cruth-tìre fo-thropaigeach -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Cruth-tìre nan dèideag - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Sgeama nan dath @@ -2595,6 +2560,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}sàsaichte STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}cus dheth +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Seall raon-còmhdachaidh STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Air @@ -2695,8 +2662,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Meudaich STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Tagh drochaid rèile STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Tagh drochaid rathaid STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Tagh drochaid - briog air an drochaid a thogras tu gus a togail -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Crochaidh, Stàilinn STR_BRIDGE_NAME_GIRDER_STEEL :Teannadair, Stàilinn STR_BRIDGE_NAME_CANTILEVER_STEEL :Starr-chrann, Stàillinn @@ -3098,16 +3063,40 @@ STR_MAPGEN_MAPSIZE :{BLACK}Meud a' STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Tagh co mheud leacan a bhios sa mhapa. Bidh an àireamh dhe leacan ri làimh beagan nas lugha STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Bailtean: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Ainmean bhailtean +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Tagh stoidhle aig ainmean nam bailtean STR_MAPGEN_DATE :{BLACK}Ceann-latha: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Gnìomhachasan: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Gineadair crutha-thìre: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Seòrsa a' chrutha-thìre: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Àirde na mara: +STR_MAPGEN_SEA_LEVEL :{BLACK}Àirde na mara: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Aibhnichean: STR_MAPGEN_SMOOTHNESS :{BLACK}Dè cho rèidh: STR_MAPGEN_VARIETY :{BLACK}Sgaoileadh caochlaidh: STR_MAPGEN_GENERATE :{WHITE}Gin am mapa +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Beurla (Tùsail) +STR_MAPGEN_TOWN_NAME_FRENCH :Frangach +STR_MAPGEN_TOWN_NAME_GERMAN :Gearmailteach +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Beurla (a bharrachd) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Aimeireaga Laidinneach +STR_MAPGEN_TOWN_NAME_SILLY :Gòrach +STR_MAPGEN_TOWN_NAME_SWEDISH :Suaineach +STR_MAPGEN_TOWN_NAME_DUTCH :Duitseach +STR_MAPGEN_TOWN_NAME_FINNISH :Fionnlannach +STR_MAPGEN_TOWN_NAME_POLISH :Pòlannach +STR_MAPGEN_TOWN_NAME_SLOVAK :Slòbhacach +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Nirribheach +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungaireach +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Ostaireach +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romàineach +STR_MAPGEN_TOWN_NAME_CZECH :Seiceach +STR_MAPGEN_TOWN_NAME_SWISS :Eilbheiseach +STR_MAPGEN_TOWN_NAME_DANISH :Danmhairgeach +STR_MAPGEN_TOWN_NAME_TURKISH :Turcach +STR_MAPGEN_TOWN_NAME_ITALIAN :Eadailteach +STR_MAPGEN_TOWN_NAME_CATALAN :Catalanach + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Oirean a' mhapa: STR_MAPGEN_NORTHWEST :{BLACK}Iar-thuath @@ -3247,6 +3236,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}An sprit STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Lean air adhart dhan sprite àbhaisteach roimhe, a' gearradh leum thairis air sprites mas fhìor/ath-dhathaidh/crutha-chlò is a' pasgadh aig an toiseach gun sprite mu dheireadh STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Riochdachadh air an sprite a thagh thu an-dràsta. Thèid an co-thaobhadh a chur dhan dàrna taobh nuair a thèid an sprite a tharraing STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Gluais an sprite mu thimcheall, ag atharrachadh nam frith-àireamhan aig X is Y + +###length 2 + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Ath-shuidhich na frith-àireamhean dàimheach STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Ath-shuidhich na frith-àireamhean dàimheach làithreach STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}frith-àireamh X: {NUM}, frith-àireamh Y: {NUM} (absaloideach) @@ -3261,7 +3254,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Rabhadh: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Mearachd: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Marbhtach: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Thachair mearachd NewGRF marbhtach:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :Chan obraich {1:STRING} leis an tionndadh aig TTDPatch a chaidh aithris le OpenTTD STR_NEWGRF_ERROR_DOS_OR_WINDOWS :Tha {1:STRING} airson tionndadh {STRING} aig TTD STR_NEWGRF_ERROR_UNSET_SWITCH :Chaidh {1:STRING} a dhealbhachadh gus cleachdadh le {STRING} @@ -3766,6 +3758,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Spàirn STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Astar: {GOLD}{COMMA} {P leac leac leacan leac} STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Seòrsa a' charbaid-adhair: {GOLD}{STRING} +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Liosta airson carbadan-rèile a thaghadh. Briog air carbad airson fiosrachaidh. Ctrl+briog gus toglachadh an tèid seòrsa a’ charbaid fhalach gus nach tèid STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Liosta airson carbadan-rathaid a thaghadh. Briog air carbad airson fiosrachaidh. Ctrl+briog gus toglachadh an tèid seòrsa a’ charbaid fhalach gus nach tèid @@ -4395,12 +4389,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Thuislic STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Chan eil an uinneag dì-bhugaidh aig an IF/sgriobt geama ri làimh ach airson an fhrithealaiche # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Rèiteachadh an IF/sgriobt geama STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}An sgriobt geama a thèid a luchdadh leis an ath-gheama STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Na IF a thèid a luchdadh leis an ath-gheama STR_AI_CONFIG_HUMAN_PLAYER :Cluicheadair daonna STR_AI_CONFIG_RANDOM_AI :IF air thuaiream STR_AI_CONFIG_NONE :(gun IF) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Àireamh as motha dhe cho-fharpaisich: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Gluais suas STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Gluais an IF a thagh thu suas air an liosta @@ -4410,8 +4404,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Gluais a STR_AI_CONFIG_GAMESCRIPT :{SILVER}Sgriobt geama STR_AI_CONFIG_AI :{SILVER}IFan -STR_AI_CONFIG_CHANGE :{BLACK}Tagh {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :IF STR_AI_CONFIG_CHANGE_GAMESCRIPT :Sgriobt geama STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Luchdaich sgriobt eile @@ -4434,10 +4426,8 @@ STR_AI_LIST_CANCEL :{BLACK}Sguir dh STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Na atharraich an sgriobt -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}Paramadairean aig {STRING} +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :IF -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Sgriobt geama STR_AI_SETTINGS_CLOSE :{BLACK}Dùin STR_AI_SETTINGS_RESET :{BLACK}Ath-shuidhich STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4843,6 +4833,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Cha ghab STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... chaidh an carbad a mhilleadh + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Cha bhi carbad sam bith ri làimh STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Atharraich an rèiteachadh NewGRF agad STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Chan eil carbad ri fhaighinn fhathast @@ -4876,6 +4867,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Cha ghab STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... ro fhad air falbh on cheann-uidhe roimhe STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... chan eil rainse gu leòr aig a' charbad-adhair +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Cha ghabh clàr-ama toirt dhan charbad... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Chan urrainn dha charbad feitheamh ach aig stèisean diff --git a/src/lang/galician.txt b/src/lang/galician.txt index 7381805b9ac1d..c485a3327cd94 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}cv STR_UNITS_POWER_METRIC :{COMMA}cv STR_UNITS_POWER_SI :{COMMA}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -226,9 +236,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA} m STR_UNITS_HEIGHT_SI :{COMMA} m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filtrar texto: -STR_LIST_FILTER_OSKTITLE :{BLACK}Introducir cadea de texto a filtrar -STR_LIST_FILTER_TOOLTIP :{BLACK}Introduce unha palabra clave pola que filtra-la lista +STR_LIST_FILTER_TITLE :{BLACK}Filtrar: +STR_LIST_FILTER_OSKTITLE :{BLACK}Introducir unha ou máis palabras clave pola que filtrar a lista +STR_LIST_FILTER_TOOLTIP :{BLACK}Introduce unha ou máis palabras clave pola que filtra-la lista STR_TOOLTIP_GROUP_ORDER :{BLACK}Selecciona a orde de agrupamento STR_TOOLTIP_SORT_ORDER :{BLACK}Selecciona a ordenación (descendente/ascendente) @@ -377,9 +387,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Xeració STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Xeración de industrias STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Construción de estradas STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Construción de tranvía -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantar árbores. Shift alterna entre construir/amosar custo estimado +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantar árbores. Ctrl selecciona a area diagonalmente. Shift alterna entre construir/amosar custo estimado STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Colocar rótulo -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar obxecto. Shift alterna entre construir/amosar custo estimado +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar obxecto. Ctrl selecciona a area diagonalmente. Shift alterna entre construir/amosar custo estimado # Scenario editor file menu ###length 7 @@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Saír # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Opcións do xogo STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Opcións -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Configuración da IA/scripts +STR_SETTINGS_MENU_AI_SETTINGS :Axustes da IA +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Axustes dos scripts do xogo STR_SETTINGS_MENU_NEWGRF_SETTINGS :Configuración NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opcións de transparencia STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Amosar nomes de cidades @@ -966,36 +977,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rupia India (IN STR_GAME_OPTIONS_CURRENCY_IDR :Rupia Indonesia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit malaio(MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Conducir pola esquerda -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Conducir pola dereita - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nomes das localidades: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Selecciona o estilo dos nomes das cidades - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Inglés (Orixinal) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francés -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Alemán -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Inglés (Adicional) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latino-Americano -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Parvo -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Sueco -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Neerlandés -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finés -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polaco -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Eslovaco -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Noruegués -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Húngaro -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austríaco -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumano -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Checo -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Suízo -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danés -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turco -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiano -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalán - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Autogravado STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selecciona o intervalo entre autogravados @@ -1026,22 +1007,21 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}O cambio STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Marca esta caixa para activar o V-sync da pantalla. O cambio só se aplicará tras reiniciar o xogo. Só funciona coa aceleración de hardware habilitada +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Controlador actual: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Tamaño da interface -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Seleciona o tamaño de elementos da interface a usar +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Tamaño da interface +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Arrastra o deslizante para establecer o tamaño da interface. Mantén Ctrl para axuste continuo +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Auto-detectar tamaño +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marca esta caixa para detectar o tamaño da interface automáticamente -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(auto-detectar) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dobre tamaño -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Tamaño do cadro +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Escalar biseles +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marca esta caixa para escalar os biseles segundo o tamaño da interface -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Tamaño da letra -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Escoller o tamaño de fonte da interfaz - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(auto-detectar) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Tamaño doble -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Tamaño do cadro +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Gráficos @@ -1093,8 +1073,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Vista p STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Libras esterlinas (£) na túa moeda STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Cambiar o parámetro de moeda personalizada -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Nº máximo de opoñentes: {ORANGE}{COMMA} - STR_NONE :Ningún STR_FUNDING_ONLY :Só fundadas STR_MINIMAL :Mínimo @@ -1144,6 +1122,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Paisaxe temperada +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Paisaxe subártica +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Paisaxe subtropical +STR_CLIMATE_TOYLAND_LANDSCAPE :Paisaxe xoguetelandia + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Moi chan STR_TERRAIN_TYPE_FLAT :Chan @@ -1163,7 +1147,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}Non hai # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Opcións -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrar texto: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrar: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Expandir todos STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Minimizar todos STR_CONFIG_SETTING_RESET_ALL :{BLACK}Restablecer todos os valores @@ -1223,6 +1207,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Dereita STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Crédito máximo inicial: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Cantidade máxima de cartos que unha compañía pode pedir (sen ter en conta a inflación) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Non hai empréstitos. {RED}Require dun script do xogo para ter fondos iniciais STR_CONFIG_SETTING_INTEREST_RATE :Taxa de interés: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :A taxa de interés do préstamo; controla tamén a inflación, se está activada @@ -1449,6 +1436,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Ancho de liña STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Amosar o nome do NewGRF na fiestra de comprar vehículos: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Engade unha liña a fiestra de compra de vehículos, amosando de que NewGRF ven o vehículo. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Amosa as cargas que os vehículos poden levar nas fiestras de listas {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Cando se activa, a carga transportable polo vehículo aparece enriba súa na lista de vehículos STR_CONFIG_SETTING_LANDSCAPE :Paisaxe: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :As paisaxes definen escenarios de xogo con diferentes requerimentos de mercadorías e de crecemento da poboación. Os scripts de xogo e os NewGRF permiten un maior control @@ -1503,6 +1492,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Mellorado STR_CONFIG_SETTING_ROAD_SIDE :Vehículos rodados: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Escolle o senso de circulación +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Conducir pola esquerda +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Conducir pola dereita + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotación do mapa de alturas: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Antihorario @@ -1936,13 +1929,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Leva {STRING}{N STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tempo empregado para cada recálculo dunha compoñente do gráfico de ligazóns. Cando comeza un recálculo, creáse un fío que funciona por este número de días. Canto máis pequeno sexa este, é máis probable que o fío non remate cando se supón. Nese intre o xogo para para compensar este retardo. Canto máis longo sexa, máis tempo leva actualizar a distribución cando cambian as rutas. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modo de distribución para pasaxeiros: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"simétrico" singinfica que máis ou menos o mesmo número de pasaxeiros irán dende a estación A cada a estación B e tamén da B cara a A. "asimétrico" significa que calquera número de pasaxeiros pode ir en calquera dirección. "manual" significa que non haberá distribución automática para os pasaxeiros. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simétrico" significa que máis ou menos o mesmo número de pasaxeiros irán dende a estación A cada a estación B e tamén da B cara a A. "Asimétrico" significa que calquera número de pasaxeiros pode ir en calquera dirección. "manual" significa que non haberá distribución automática para os pasaxeiros. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Modo de distribución para correo: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"simétrico" significa que máis ou menos a mesma cantidade de correo vai ser enviada da estación A cara a estación B como da estación B cara a A. "asimétrico" signigica que calquera cantidade de correo pode ser enviado en calquera dirección. "manual" significa que non hai distribución automática para o correo. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Simétrico" significa que máis ou menos a mesma cantidade de correo vai ser enviada da estación A cara a estación B como da estación B cara a A. "Asimétrico" signigica que calquera cantidade de correo pode ser enviado en calquera dirección. "Manual" significa que non hai distribución automática para o correo. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Modo de disitribución para o tipo de mercadoría BLINDADO: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :A calse de mercadoría BLINDADA contén obxectos de valor nos clima morno, diamantes no subtropical ou ouro no clima subártico. Os NewGRFs poden cambiar isto. "simétrico" significa que máis ou menos a mesma cantidade de esta mercadoría será enviadas dende a estación A cara a estación B así como da estación B para a A. "asimétrico" significa que calquera cantidade de esta mercadoría pode ser enviada en calquera dirección. "manual" significa que non haberá distribución automática para esta mercadoría. Recoméndase elixir asimétrico ou manual cando se xoguen mapas subárticos, xa que os bancos non van enviar ouro de volta ás minas. Para climas mornos e subtropicais podes escoller tamén simétrico xa que os bancos retornan valores aos bancos de orixe dalgunha carga de valores. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :A clase de mercadoría BLINDADA contén obxectos de valor nos clima morno, diamantes no subtropical ou ouro no clima subártico. Os NewGRFs poden cambiar isto. "Simétrico" significa que máis ou menos a mesma cantidade de esta mercadoría será enviadas dende a estación A cara a estación B así como da estación B para a A. "Asimétrico" significa que calquera cantidade de esta mercadoría pode ser enviada en calquera dirección. "manual" significa que non haberá distribución automática para esta mercadoría. Recoméndase elixir asimétrico ou manual cando se xoguen mapas subárticos ou subtropicais, xa que os bancos só reciben carga nestos climas. Para os climas mornos podes escoller simétrico xa que os bancos enviarán carga de volta o banco orixinal. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Xeito de distribución para outros tipos de mercadoría: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asimétrico" significa que calquera cantidade de mercadorías pode ser enviada en calquera dirección. "manual" significa que non haberá distribución automática para estas mercadorías. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimétrico" significa que calquera cantidade de mercadorías pode ser enviada en calquera dirección. "Manual" significa que non haberá distribución automática para estas mercadorías. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimétrica @@ -2037,7 +2030,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Cambio de senti STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Permite aos trens cambiar de sentido nun sinal, se agardaron durante moito tempo ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomendado) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recomendado) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Cambia-lo valor @@ -2080,7 +2073,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Táboa d STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Opcións STR_INTRO_NEWGRF_SETTINGS :{BLACK}Configuración NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Comprobar contido online -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Configuración dos scripts de IA +STR_INTRO_AI_SETTINGS :{BLACK}Axustes da IA +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Axustes dos scripts do xogo STR_INTRO_QUIT :{BLACK}Saír STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Comezar unha nova partida. Ctrl+Click para saltarse a configuración do mapa @@ -2100,7 +2094,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Mostrar STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Opcións de visualización STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Mostra-la configuración de NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Buscar contidos novos e actualizados para descargar -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Motra-la configuración dos scripts de IA +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Amosar axustes da IA +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Amosar os axustes dos scripts do xogo STR_INTRO_TOOLTIP_QUIT :{BLACK}Saír de 'OpenTTD' STR_INTRO_BASESET :{BLACK}A base gráfica seleccionada actualmente está perdendo {NUM} sprite{P "" s}. Por favor comproba se hai actualizacións para o conxunto base. @@ -2132,12 +2127,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Cambiar STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Cambiar o ano actual STR_CHEAT_SETUP_PROD :{LTBLUE}Permitir a modificación dos valores de producción: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Paisaxe temperada -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Paisaxe subártica -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Paisaxe subtropical -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Paisaxe xoguetelandia - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Novo esquema de cor @@ -2370,7 +2359,6 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nova compañí STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Crear unha nova compañía e unirte a ela STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Este es ti STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Este é o anfitrión da partida -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s} / {NUM} compañía{P "" "s"} # Matches ConnectionType ###length 5 @@ -2497,13 +2485,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :agargando pola STR_NETWORK_MESSAGE_CLIENT_LEAVING :saíndo STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} uniuse á partida -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} uniuse á partida (Cliente #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} uniuse á compañía #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} uniuse á partida (Cliente #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} uniuse á compañía #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} uniuse aos espectadores -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} comezou unha nova compañía (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} saiu da partida ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} comezou unha nova compañía (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} saiu da partida ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} cambiou o seu nome a {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} deu {2:CURRENCY_LONG} a {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} deu {2:CURRENCY_LONG} a {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}O servidor pechou a sesión STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}O servidor estase a reiniciar...{}Agarda por favor... STR_NETWORK_MESSAGE_KICKED :*** {STRING} foi expulsado. Motivo: ({STRING}) @@ -2617,6 +2605,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}saturado STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}exceso de carga +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} serán transportados por mes dende {STATION} a {STATION} ({COMMA}% da capacidade){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} serán transportados de volta ({COMMA}% da capacidade) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Tempo medio de viaxe: {NUM}{NBSP}día{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Resaltar área de cobertura STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Off @@ -2625,6 +2618,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Non resa STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Resalta-la área de cobertura do sitio proposto STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Acepta: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Abastecementos: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Coste de mantemento: {GOLD}{CURRENCY_SHORT}/ano # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Unir estación @@ -2706,9 +2700,11 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Aumentar # Bridge selection window STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Selecciona ponte ferroviaria STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Selecciona ponte de estrada -STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Selección de pontes - picha na ponte seleccionada para construíla -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Selección de pontes - pincha na ponte seleccionada para construíla +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Colgante, aceiro STR_BRIDGE_NAME_GIRDER_STEEL :Vigas, aceiro STR_BRIDGE_NAME_CANTILEVER_STEEL :Voladizo, aceiro @@ -2812,11 +2808,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Movement STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Baixar unha esquina de terreo. Ao arrastrar báixase a primeira esquina seleccionada e nivela a área seleccionada á nova cota da esquina. Ctrl selecciona a área diagonalmente. Shift alterna entre construír e amosa-lo custo estimado STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Elevar unha esquina de terreo. Ao arrastrar elévase a primeira esquina seleccionada e nivela a área seleccionada á nova cota da esquina. Ctrl selecciona a área diagonalmente. Shift alterna entre construír e amosa-lo custo estimado STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}{BLACK}Nivela unha área de terreo á cota da primeira esquina de terreo seleccionada. Ctrl selecciona a área diagonalmente. Shift alterna entre construír e amosa-lo custo estimado -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreo para usar no futuro. Shift alterna entre construír e amosa-lo custo estimado +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreo para usar no futuro. Ctrl selecciona a area diagonalmente. Shift alterna entre construír e amosa-lo custo estimado # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Selección de obxectos -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selecciona o obxecto a construír. Shift alterna entre construír e amosa-lo custo estimado +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selecciona o obxecto a construír. Ctrl selecciona a area diagonalmente. Shift alterna entre construír e amosa-lo custo estimado STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Selecciona a clase de obxecto a construír STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Previsualización do obxecto STR_OBJECT_BUILD_SIZE :{BLACK}Tamaño: {GOLD}{NUM} x {NUM} cadros @@ -2828,7 +2824,7 @@ STR_OBJECT_CLASS_TRNS :Transmisores STR_PLANT_TREE_CAPTION :{WHITE}Árbores STR_PLANT_TREE_TOOLTIP :{BLACK}Selecciona-lo tipo de árbore a plantar. Se xa hai unha árbore no cadro, isto engadirá máis árbores de varios tipos independentemente do tipo seleccionado STR_TREES_RANDOM_TYPE :{BLACK}Árbores de tipo aleatorio -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Colocar árbores de tipo aleatorio. Shift alterna entre construír e amosa-lo custo estimado +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Colocar árbores de tipo aleatorio. Ctrl selecciona a area diagonalmente. Shift alterna entre construír e amosa-lo custo estimado STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Árbores aleatorias STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plantar árbores aleatoriamente sobre a paisaxe STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2860,6 +2856,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Cidade a STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Fundar cidade nun emprazamento aleatorio STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Moitas cidades aleatorias STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cubri-lo mapa con cidades colocadas aleatoriamente +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Expandir todas as vilas +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Facer que todas as vilas medren lixeiramente STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nome da poboación: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Escribe o nome da poboación @@ -3124,7 +3122,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalles STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Non hai información dispoñíbel STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}String de filtrado: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtro: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Sobrescribir arquivo STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Estás seguro de que queres rescribir este arquivo? STR_SAVELOAD_DIRECTORY :{STRING} (Directorio) @@ -3138,6 +3136,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Tamaño STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK} Selecciona o tamaño do mapa en cadros. O número de cadros dispoñíbeis será sensiblemente menor STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Nº de cidades: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nomes das localidades: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Selecciona o estilo dos nomes das cidades STR_MAPGEN_DATE :{BLACK}Data: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Nº de industrias: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Maior pico: @@ -3151,13 +3151,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Cobertur STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Aumenta a cobertura do deserto un dez por cento STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Disminuír a cobertura do deserto un dez por cento. STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Xerador de terreo: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tipo de terreo: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Nivel do mar: +STR_MAPGEN_SEA_LEVEL :{BLACK}Nivel do mar: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Ríos: STR_MAPGEN_SMOOTHNESS :{BLACK}Suavidade: STR_MAPGEN_VARIETY :{BLACK}Variedade: STR_MAPGEN_GENERATE :{WHITE}Xerar +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Configuración NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Amosar os axustes de NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Axustes da IA +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Amosar axustes da IA +STR_MAPGEN_GS_SETTINGS :{BLACK}Axustes dos scripts do xogo +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Amosar axustes dos scripts do xogo + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Inglés (Orixinal) +STR_MAPGEN_TOWN_NAME_FRENCH :Francés +STR_MAPGEN_TOWN_NAME_GERMAN :Alemán +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Inglés (Adicional) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latino-Americano +STR_MAPGEN_TOWN_NAME_SILLY :Parvo +STR_MAPGEN_TOWN_NAME_SWEDISH :Sueco +STR_MAPGEN_TOWN_NAME_DUTCH :Neerlandés +STR_MAPGEN_TOWN_NAME_FINNISH :Finés +STR_MAPGEN_TOWN_NAME_POLISH :Polaco +STR_MAPGEN_TOWN_NAME_SLOVAK :Eslovaco +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Noruegués +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Húngaro +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austríaco +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumano +STR_MAPGEN_TOWN_NAME_CZECH :Checo +STR_MAPGEN_TOWN_NAME_SWISS :Suízo +STR_MAPGEN_TOWN_NAME_DANISH :Danés +STR_MAPGEN_TOWN_NAME_TURKISH :Turco +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiano +STR_MAPGEN_TOWN_NAME_CATALAN :Catalán # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Bordes do mapa: @@ -3216,7 +3244,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Informac STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Arquivos NewGRF activos STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Arquivos NewGRF inactivos STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Seleccionar perfil -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtrar cadea de caracteres +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtrar: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Carga-lo perfil seleccionado STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Gravar perfil STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Grava-la lista actual coma un perfil @@ -3303,6 +3331,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Sprite a STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Ir ao sprite anterior, ignorando pseudosprites, sprites recoloreados e sprites de fonte, e volvendo a empezar ao chegar ao inicio STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representación do sprite seleccionado. A aliñación ignórase ao debuxar este sprite STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Move-lo sprite, cambiando os valores de X e Y. Ctrl+Click para movelo sprite oito unidades de golpe. + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Desfase centrado +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centrado + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Punto de mira + STR_SPRITE_ALIGNER_RESET_BUTTON :Reinicio relativo STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Restablecer a compensación actual STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Compensación eixo X: {NUM}, Compensación eixo Y: {NUM} (Absoluta) @@ -3317,18 +3352,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Coidado: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Erro: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Erro fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Ocorreu un erro fatal de NewGRF:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Ocurriu un erro cun NewGRF:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}O NewGRF "{STRING}" devolveu un erro crítico:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}O NewGRF "{STRING}" devolveu un erro:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} non funcionará coa versión de TTDPatch reportada por OpenTTD. -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} é para a versión {STRING} de TTD. -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} está deseñado para ser usado con {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Parámetro incorrecto para {1:STRING}: parámetro {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} debe cargarse antes de {STRING}. -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} debe cargarse despois de {STRING}. -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} require a versión de OpenTTD {STRING} ou posterior +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} é para a versión {2:STRING} de TTD. +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} está deseñado para ser usado con {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Parámetro incorrecto para {1:STRING}: parámetro {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} debe cargarse antes de {2:STRING}. +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} debe cargarse despois de {2:STRING}. +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} require a versión de OpenTTD {2:STRING} ou posterior STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :o arquivo GRF que foi deseñado para traducir STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Cargáronse demasiados NewGRFs. -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Cargar {1:STRING} como NewGRF estático con {STRING} pode causar desincronizacións +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Cargar {1:STRING} como NewGRF estático con {2:STRING} pode causar desincronizacións STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Sprite inesperado (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Propiedade de acción 0 descoñecida {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Intento de usar un ID inválido (sprite {3:NUM}) @@ -3454,20 +3489,20 @@ STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN :Pequena campañ STR_LOCAL_AUTHORITY_ACTION_MEDIUM_ADVERTISING_CAMPAIGN :Campaña publicitaria mediana STR_LOCAL_AUTHORITY_ACTION_LARGE_ADVERTISING_CAMPAIGN :Gran campaña publicitaria STR_LOCAL_AUTHORITY_ACTION_ROAD_RECONSTRUCTION :Financia-la reparación das fochancas nas rúas da cidade -STR_LOCAL_AUTHORITY_ACTION_STATUE_OF_COMPANY :Construír unha estatua ao propietario da compañía +STR_LOCAL_AUTHORITY_ACTION_STATUE_OF_COMPANY :Construír unha estatua do propietario da compañía STR_LOCAL_AUTHORITY_ACTION_NEW_BUILDINGS :Financiar novos edificios STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Compra-los dereitos exclusivos de transporte STR_LOCAL_AUTHORITY_ACTION_BRIBE :Suborna-la autoridade local ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Iniciar unha campaña de publicidade pequena, para atraer máis pasaxeiros e mercadorías aos teus servizos de transporte.{}Concede un aumento temporal da puntuación da estación nun pequeno radio arredor do centro da localide.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Iniciar unha campaña de publicidade mediana, para atraer máis pasaxeiros e mercadorías aos teus servizos de transporte.{}Concede un aumento temporal da puntuación da estación nun radio medio arredor do centro da localide.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Iniciar unha gran campaña de publicidade, para atraer máis pasaxeiros e mercadorías aos teus servizos de transporte.{}Concede un aumento temporal da puntiación das túas estacións nun gran radio arredor do centro da localidade.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Financiar a reconstrución das rúas da localidade.{}Provoca unhas considerables interrupcións no tráfico durante seis meses.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Construír unha estatua en honor a túa compañía.{}Condede un aumento permanente da puntuación das túas estacións nesta localide.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW} Financiar a construción de novos edificios comerciais na cidade.{}Concede un aumento temporal do crecemento desta localide.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Comprar os dereitos exclusivos de transporte na cidade durante 1 ano.{}A autoridade só permitirá que os pasaxeiros e as mercadorías usen as estacións da túa compañía.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Suborna-la autoridade local para mellora-la túa puntuación, co risco dunha gran penalización se o descobren.{}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniciar unha campaña de publicidade pequena, para atraer máis pasaxeiros e mercadorías aos teus servizos de transporte.{}Concede un aumento temporal da puntuación da estación nun pequeno radio arredor do centro da localide.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniciar unha campaña de publicidade mediana, para atraer máis pasaxeiros e mercadorías aos teus servizos de transporte.{}Concede un aumento temporal da puntuación da estación nun radio medio arredor do centro da localide.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniciar unha gran campaña de publicidade, para atraer máis pasaxeiros e mercadorías aos teus servizos de transporte.{}Concede un aumento temporal da puntiación das túas estacións nun gran radio arredor do centro da localidade.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Financiar a reconstrución das rúas da localidade.{}Provoca unhas considerables interrupcións no tráfico durante seis meses.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Construír unha estatua en honor a túa compañía.{}Condede un aumento permanente da puntuación das túas estacións nesta localide.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW} Financiar a construción de novos edificios comerciais na cidade.{}Concede un aumento temporal do crecemento desta localide.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Comprar os dereitos exclusivos de transporte na cidade durante 1 ano.{}A autoridade só permitirá que os pasaxeiros e as mercadorías usen as estacións da túa compañía.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Suborna-la autoridade local para mellora-la túa puntuación, co risco dunha gran penalización se o descobren.{}{POP_COLOUR}Custo: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Obxectivos @@ -3640,15 +3675,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Barcos STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Interese do préstamo STR_FINANCES_SECTION_OTHER :{GOLD}Outros +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Beneficio neto +STR_FINANCES_PROFIT :{WHITE}Beneficio STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Balance bancario STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Fondos propios STR_FINANCES_LOAN_TITLE :{WHITE}Préstamo STR_FINANCES_INTEREST_RATE :{WHITE}Interese do préstamo: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Préstamo máximo: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Pedir {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Incrementar o préstamo. CTRL+Click solicita o máximo posíbel STR_FINANCES_REPAY_BUTTON :{BLACK}Devolver {CURRENCY_LONG} @@ -3749,7 +3787,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produce: STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Require: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} agardando{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Cambiar produción (múltiplo de 8, ata 2040) @@ -3779,6 +3817,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Envia-la STR_VEHICLE_LIST_REPLACE_VEHICLES :Reemprazar vehículos STR_VEHICLE_LIST_SEND_FOR_SERVICING :Enviar para servizo STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Beneficio este ano: {CURRENCY_LONG} (ano pasado: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Enviar ao depósito STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Enviar ao depósito @@ -3870,6 +3910,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Esforzo STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Autonomía: {GOLD}{COMMA} cadros STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipo de aeronave: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Todos os tipos de carga +STR_CARGO_TYPE_FILTER_FREIGHT :Carga +STR_CARGO_TYPE_FILTER_NONE :Ningunha + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Lista de selección de vehículos ferroviarios - pincha nun vehículo para obter información STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Lista de selección de vehículos de estrada - pincha nun vehículo para obter información @@ -4038,7 +4083,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :avión STR_ENGINE_PREVIEW_SHIP :barco STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Custo: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocidade: {VELOCITY} Potencia: {POWER}{}Custo operativo: {CURRENCY_LONG}/ano{}Capacidade: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Custo: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocidade: {VELOCITY} Potencia: {POWER} Esforzo tractor máximo: {6:FORCE}{}Custo operativo: {4:CURRENCY_LONG}/ano{}Capacidade: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Custo: {0:CURRENCY_LONG} Peso: {1:WEIGHT_SHORT}{}Velocidade: {2:VELOCITY} Potencia: {3:POWER} Esforzo tractor máximo: {6:FORCE}{}Custo operativo: {4:CURRENCY_LONG}/ano{}Capacidade: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Velocidade máxima: {VELOCITY}{}Capacidade: {CARGO_LONG}{}Custo operativo: {CURRENCY_LONG}/ano STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Vel. Máxima: {VELOCITY}{}Tipo aeronave: {STRING}{}Capacidade: {CARGO_LONG}, {CARGO_LONG}{}Custo operativo: {CURRENCY_LONG}/ano STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Vel. Máxima: {VELOCITY}{}Tipo aeronave: {STRING}{}Capacidade: {CARGO_LONG}{}Custo operativo: {CURRENCY_LONG}/ano @@ -4197,12 +4242,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {L STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potencia: {LTBLUE}{POWER}{BLACK} Velocidade máxima: {LTBLUE}{VELOCITY} {BLACK}T.E. máx.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Beneficio este ano: {LTBLUE}{CURRENCY_LONG} (ano pasado: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Beneficios este ano: {LTBLUE}{CURRENCY_LONG} (último ano: {CURRENCY_LONG}) {BLACK}Rendemento Mín.: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidade: {LTBLUE}{COMMA}% {BLACK}Avarías dende o último servizo: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacidade: {LTBLUE}Ningunha{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidade: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacidade: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Créditos de transferencia: {LTBLUE}{CURRENCY_LONG} @@ -4228,8 +4274,8 @@ STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Valor: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Capacidade total de carga deste tren: -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Baleiro STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} dende {STATION} @@ -4468,25 +4514,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Este hor STR_TIMETABLE_STATUS_START_AT :{BLACK}Este horario comezará o {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Data comezo -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Selecciona unha data coma punto de inicio para este horario. Ctrl + click determina o punto de partida deste horario e distribúe uniformemente tódolos vehículos que compartan esta orde baséandose na súa orde relativa. se a orde está completamente tabulada nos horarios +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Selecciona unha data coma punto de inicio para este horario. Ctrl + click distribúe uniformemente tódolos vehículos que compartan esta orde baséandose na súa orde relativa. se a orde está completamente tabulada nos horarios STR_TIMETABLE_CHANGE_TIME :{BLACK}Cambiar Tempo -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Cambiar o tempo que debería levar a orde seleccionada +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Cambiar o tempo que debería levar a orde seleccionada. Ctrl+Click cambia o tempo para todas as ordes STR_TIMETABLE_CLEAR_TIME :{BLACK}Borrar tempo -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Borrar o tempo para a orde seleccionada +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Borrar o tempo para a orde seleccionada. Ctrl+Click borra o tempo para todas as ordes STR_TIMETABLE_CHANGE_SPEED :{BLACK}Cambiar o límite de velocidade -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Cambiar a velocidade máxima da orde seleccionada +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Cambiar a velocidade máxima da orde seleccionada. Ctrl+Click fixa a velocidade para todas as ordes. STR_TIMETABLE_CLEAR_SPEED :{BLACK}Borrar o límite de velocidade -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Borrar a velocidade máxima da orde seleccionada +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Borrar a velocidade máxima da orde seleccionada. Ctrl+Click borra a velocidade para todas as ordes. STR_TIMETABLE_RESET_LATENESS :{BLACK}Reiniciar atraso -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reiniciar o contador de atraso, para que o vehículo vaia en hora +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reiniciar o contador de atraso, para que o vehículo vaia en hora. Ctrl+Click reiniciará o grupo enteiro de tal xeito que o último vehículo vaia en hora e os demáis máis cedo. STR_TIMETABLE_AUTOFILL :{BLACK}Encher automaticamente -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Encher o horario automaticamente cos valores da seguinte viaxe (CTRL+Pinchar para intentar manter os tempos de espera) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Encher o horario automaticamente cos valores da seguinte viaxe. Ctrl+Clic para intentar manter os tempos de espera STR_TIMETABLE_EXPECTED :{BLACK}Esperado STR_TIMETABLE_SCHEDULED :{BLACK}Programado @@ -4530,12 +4576,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Fallou u STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}A fiestra de Depuración de IA só está dispoñíbel para o servidor # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Configuración IA / scripts do xogo +STR_AI_CONFIG_CAPTION_AI :{WHITE}Configuración da IA +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Configuración dos scripts do xogo STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}O script de xogo que se cargará na próxima partida STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}As IAs que serán cargadas na próxima partida STR_AI_CONFIG_HUMAN_PLAYER :Xogador humano STR_AI_CONFIG_RANDOM_AI :IA aleatoria STR_AI_CONFIG_NONE :(ningunha) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Nº máximo de opoñentes: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Subir STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Mover a IA seleccionada cara arriba na lista @@ -4543,12 +4591,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Baixar STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Mover a IA seleccionada hacia abaixo na lista STR_AI_CONFIG_GAMESCRIPT :{SILVER} Script do xogo +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parámetros STR_AI_CONFIG_AI :{SILVER}IAs -STR_AI_CONFIG_CHANGE :{BLACK}Seleccionar{STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :IA -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script do xogo +STR_AI_CONFIG_CHANGE_AI :{BLACK}Seleccionar IA +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Seleccionar script do xogo STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Cargar outro script STR_AI_CONFIG_CONFIGURE :{BLACK}Configurar STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configurar os parámetros do script @@ -4576,9 +4623,9 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Captura STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Captura de pantalla do mapa de alturas STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Captura de pantalla do minimapa -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parámetros -STR_AI_SETTINGS_CAPTION_AI :IA +STR_AI_SETTINGS_CAPTION_AI :AI STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script do xogo STR_AI_SETTINGS_CLOSE :{BLACK}Pechar STR_AI_SETTINGS_RESET :{BLACK}Restablecer @@ -4743,6 +4790,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... dema STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Non se poden xera-las industrias... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Non se pode construír {STRING} aquí... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Non se pode construír este tipo de industria aí... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Non se pode facer unha prospección desta industria... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... demasiado preto doutra industria STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... debes fundar unha vila primeiro STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... só se permite un por cidade @@ -4757,6 +4805,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... o bo STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... só se pode construír sobre a cota de neve STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... só se pode construír baixo a cota de neve +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}A fundación non conseguiu facer unha boa prospección por mala sorte; proba de novo +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Non había lugares axeitados para prospeccións desta industria STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Non habían lugares axeitados para industrias '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Cambia os parámetros de xeración de mapas para obter un mapa mellor @@ -4924,6 +4974,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Hai un o STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... sede dunha compañía no camiño STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Non se pode comprar esta área de terreo... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... xa é da túa propiedade! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... limite de construción de obxectos alcanzado # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Non se pode crear o grupo... @@ -4996,6 +5047,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Non se p STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... o vehículo está destruído +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... non todos os vehículos son idénticos + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Non haberá vehículos dispoñibles STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Cambia a túa configuración NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Aínda non hai vehículos dispoñíbeis @@ -5022,6 +5075,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Non se p STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... o vehículo non pode ir a tódalas estacións STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... o vehículo non pode ir a esa estación STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... un vehículo que comparte esta orde non pode ir a esa estación +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... non todos os vehículos teñen as mesmas ordes +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... non todos os vehículos están compartindo ordes STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Non se pode comparti-la lista de ordes... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Non se pode parar de compartir a lista de ordes... @@ -5029,6 +5084,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Non se p STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... demasiado lonxe do destino anterior STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... o avión non ten autonomía suficiente +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Non se pode axusta-lo horario do vehículo... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Os vehículos só poden parar nas estacións @@ -5115,7 +5172,7 @@ STR_INDUSTRY_NAME_BANK_TROPIC_ARCTIC :Banco STR_INDUSTRY_NAME_DIAMOND_MINE :Mina de diamante STR_INDUSTRY_NAME_IRON_ORE_MINE :Mina de ferro STR_INDUSTRY_NAME_FRUIT_PLANTATION :Plantación de froita -STR_INDUSTRY_NAME_RUBBER_PLANTATION :Plantación de sobreiras +STR_INDUSTRY_NAME_RUBBER_PLANTATION :Plantación de caucho STR_INDUSTRY_NAME_WATER_SUPPLY :Abastecemento de auga STR_INDUSTRY_NAME_WATER_TOWER :Torre de auga STR_INDUSTRY_NAME_FACTORY_2 :Fábrica diff --git a/src/lang/german.txt b/src/lang/german.txt index d6cee6ae0be3f..074ee9afdc74d 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}PS STR_UNITS_POWER_METRIC :{COMMA}{NBSP}PS STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -226,9 +236,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Auswahl-Text: -STR_LIST_FILTER_OSKTITLE :{BLACK}Filter eingeben -STR_LIST_FILTER_TOOLTIP :{BLACK}Stichwort eingeben, mit dem die Liste gefiltert werden soll +STR_LIST_FILTER_TITLE :{BLACK}Filter: +STR_LIST_FILTER_OSKTITLE :{BLACK}Einen oder mehrere Schlüsselwörter für den Listenfilter eingeben +STR_LIST_FILTER_TOOLTIP :{BLACK}Ein oder mehrere Stichwörter eingeben, mit dem die Liste gefiltert werden soll STR_TOOLTIP_GROUP_ORDER :{BLACK}Gruppierung wählen STR_TOOLTIP_SORT_ORDER :{BLACK}Sortierreihenfolge auswählen (absteigend/aufsteigend) @@ -377,7 +387,7 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Städte STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industrie errichten STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Straße bauen STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Straßenbahngleise bauen -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Bäume pflanzen. Umschalt schaltet zwischen Bauen und Kostenvoranschlag um +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Bäume pflanzen. Strg wählt das Gebiet diagonal aus. Umschalt schaltet zwischen Bauen und Kostenvoranschlag um STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Schild aufstellen STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Objekt platzieren. Umschalt schaltet zwischen Bauen und Kostenvoranschlag um @@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Beenden # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Spieleinstellungen STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Einstellungen -STR_SETTINGS_MENU_SCRIPT_SETTINGS :KI- / Skripteinstellungen +STR_SETTINGS_MENU_AI_SETTINGS :KI-Einstellungen +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Spielskripteinstellungen STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF-Einstellungen STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Transparenzeinstellungen STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Städtenamen anzeigen @@ -966,36 +977,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indische Rupie STR_GAME_OPTIONS_CURRENCY_IDR :Indonesische Rupiah (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaysische Ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Linksverkehr -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Rechtsverkehr - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Städtenamen: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Wähle die Sprache für die Städtenamen aus - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Englisch -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Französisch -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Deutsch -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Englisch (Zusätzlich) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Lateinamerikanisch -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Verrückt -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Schwedisch -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Niederländisch -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finnisch -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polnisch -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slowakisch -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norwegisch -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungarisch -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Österreichisch -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumänisch -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tschechisch -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Schweizerisch -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dänisch -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Türkisch -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italienisch -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalanisch - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Autosicherung STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Abstand zwischen den automatischen Spielesicherungen wählen @@ -1028,21 +1009,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Dieses K STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Aktueller Treiber: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Größe der Bedienelemente -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Wähle die Größe der Bedienelemente +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Oberflächengröße +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Schieberegler ziehen, um die Größe der Benutzeroberfläche zu wählen. Strg gedrückt halten für eine stetige Anpassung +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Größe automatisch erkennen +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Dieses Kästchen ankreuzen, um die Größe der Benutzeroberfläche automatisch zu erkennen -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(automatisch erkennen) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Doppelt -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Vierfach +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Schrägen skalieren +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Dieses Kästchen ankreuzen, um Schrägen nach der Oberflächengröße zu skalieren -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Schriftgröße -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Die Schriftgröße der Spieloberfläche auswählen - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(automatisch erkennen) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Doppelt -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Vierfach +STR_GAME_OPTIONS_GUI_SCALE_1X :1× +STR_GAME_OPTIONS_GUI_SCALE_2X :2× +STR_GAME_OPTIONS_GUI_SCALE_3X :3× +STR_GAME_OPTIONS_GUI_SCALE_4X :4× +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafik @@ -1094,8 +1073,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Vorscha STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pfund (£) in der eigenen Währung STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Parameter für eigene Währung ändern -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Max. Mitbewerber-Zahl: {ORANGE}{COMMA} - STR_NONE :Keine STR_FUNDING_ONLY :Nur durch Spieler STR_MINIMAL :Minimal @@ -1145,6 +1122,12 @@ STR_SUBSIDY_X2 :×2 STR_SUBSIDY_X3 :×3 STR_SUBSIDY_X4 :×4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Gemäßigt +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subarktisch +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Subtropisch +STR_CLIMATE_TOYLAND_LANDSCAPE :Spielzeugland + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Sehr flach STR_TERRAIN_TYPE_FLAT :Flach @@ -1164,7 +1147,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}Keine KI # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Einstellungen -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Suchtext: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Alles ausklappen STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Alles einklappen STR_CONFIG_SETTING_RESET_ALL :{BLACK}Alle Werte zurücksetzen @@ -1224,6 +1207,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Rechts STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Kreditlimit bei Spielbeginn: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximaler Kredit für eine Firma (ohne Berücksichtigung der Inflation) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Kein Darlehen {RED}Benötigt Spielskript, um Startgeld zur Verfügung zu stellen STR_CONFIG_SETTING_INTEREST_RATE :Zinssatz: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Zinssatz für Kredite; beeinflusst auch die Inflation, falls aktiv @@ -1450,6 +1436,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Strichdicke der STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :NewGRF-Namen im Fahrzeugbaumenü zeigen: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Eine Textzeile mit dem Namen des NewGRF, von dem ein Fahrzeug stammt, hinzufügen. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Die Frachten, die das Fahrzzeug tragen kann, in den Listenfenstern anzeigen {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Falls erlaubt, wird die transportierbare Ladung des Fahrzeugs über ihm in den Fahrzeuglisten erscheinen STR_CONFIG_SETTING_LANDSCAPE :Landschaftstyp: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landschaftstypen definieren grundlegende Spielszenarien mit verschiedenen Frachtarten und Bedingungen für das Wachstum von Städten. Mit NewGRFs und Spielskripten können diese allerdings genauer angepasst werden @@ -1504,6 +1492,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Verbessert STR_CONFIG_SETTING_ROAD_SIDE :Straßenfahrzeuge: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Die Seite des Straßenverkehrs auswählen +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Linksverkehr +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Rechtsverkehr + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Drehung der Reliefkarte: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Nach links @@ -1941,9 +1933,9 @@ STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :„Symmetrisch STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Verteilungsschema für Post: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :„Symmetrisch“ heißt, dass etwa die selbe Menge Post von einer Station A zu einer anderen Station B geschickt wird, wie von B nach A. „Asymmetrisch“ heißt, dass Post in beliebigen Mengen hin- und her geschickt werden kann. „Manuell“ heißt, dass keine automatische Verteilung der Post stattfindet. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Verteilungsschema für Wertsachen: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Werttransporte umfassen Wertsachen im gemäßigten, Diamanten im subtropischen und Gold im subarktischen Klima. NewGRFs könnten dies ändern. „Symmetrisch“ bedeutet, dass etwa dieselbe Anzahl von Station A nach Station B transportiert wird wie umgekehrt von B nach A. „Asymmetrisch“ bedeutet, dass eine unterschiedliche Menge in die jeweiligen Richtungen gesendet wird. „Manuell“ bedeutet, dass keine automatische Verteilung stattfindet. Es wird die Einstellung „asymmetrisch“ oder „manuell“ im subarktischen Gebiet empfohlen, da Banken kein Gold bzw. Diamanten zu den Minen senden. Für das gemäßigte und subtropische Klima kann die Einstellung „symmetrisch“ genommen werden, da Banken Wertsachen untereinander versenden. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Werttransporte (Frachtklasse „ARMOURED“) umfassen Wertsachen im gemäßigten, Diamanten im subtropischen und Gold im subarktischen Klima. NewGRFs könnten dies ändern. „Symmetrisch“ bedeutet, dass etwa dieselbe Anzahl von Station A nach Station B transportiert wird wie umgekehrt von B nach A. „Asymmetrisch“ bedeutet, dass eine unterschiedliche Menge in die jeweiligen Richtungen gesendet wird. „Manuell“ bedeutet, dass keine automatische Verteilung stattfindet. Es wird die Einstellung „asymmetrisch“ oder „manuell“ im subarktischen Gebiet empfohlen, da Banken kein Gold bzw. Diamanten zu den Minen senden. Für das gemäßigte und subtropische Klima kann die Einstellung „symmetrisch“ genommen werden, da Banken Wertsachen untereinander versenden. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Verteilungsschema für sonstige Frachtarten: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :„Symmetrisch“ heißt, dass etwa die selbe Menge Waren von einer Station A zu einer anderen Station B geschickt wird, wie von B nach A. „Asymmetrisch“ heißt, dass Waren in beliebigen Mengen hin- und her geschickt werden können. „Manuell“ heißt, dass keine automatische Verteilung der Waren stattfindet. Hier sollte fast immer „asymmetrisch“ oder „manuell“ gewählt werden. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :„Asymmetrisch“ heißt, dass Waren in beliebigen Mengen hin- und her geschickt werden können. „Manuell“ heißt, dass keine automatische Verteilung der Waren stattfindet. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuell STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asymmetrisch @@ -2038,7 +2030,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatisches U STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Erlaube Zügen, an Signalen umzudrehen, wenn sie dort zu lange gewartet haben ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(empfohlen) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(empfohlen) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Wert der Einstellung ändern @@ -2081,7 +2073,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Bestenli STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Einstellungen STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF-Einstellungen STR_INTRO_ONLINE_CONTENT :{BLACK}Erweiterungen herunterladen -STR_INTRO_SCRIPT_SETTINGS :{BLACK}KI- / Skripteinstellungen +STR_INTRO_AI_SETTINGS :{BLACK}KI-Einstellungen +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Spielskripteinstellungen STR_INTRO_QUIT :{BLACK}Beenden STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Ein neues Spiel beginnen. Strg+Klick überspringt Karteneinstellungen @@ -2101,7 +2094,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Zeige di STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Einstellungen anzeigen STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF-Einstellungen anzeigen und/oder ändern STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Prüfe, ob neue oder aktualisierte Erweiterungen zum Herunterladen bereitstehen -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Zeige KI- und Skripteinstellungen +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}KI-Einstellungen anzeigen +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Spielskripteinstellungen anzeigen STR_INTRO_TOOLTIP_QUIT :{BLACK}OpenTTD beenden STR_INTRO_BASESET :{BLACK}Den momentan ausgewählten Basisgrafiken fehl{P 0 "t" "en"} {NUM} Sprite{P 0 "" "s"}. Bitte überprüfen, ob es Updates für die Basisgrafiken gibt. @@ -2133,12 +2127,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Ändere STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Ändert das Spieljahr STR_CHEAT_SETUP_PROD :{LTBLUE}Erlaube manuelles Ändern der Produktionsleistungen: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Gemäßigt -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subarktisch -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Subtropisch -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Spielzeugland - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} – Farbschema @@ -2371,7 +2359,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Neue Firma) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Eine neue Firma gründen und beitreten STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Das sind Sie STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Dies ist der Host des Spiels -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} Client{P "" s} / {NUM} Firm{P a en} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} Client{P "" s} – {NUM}/{NUM} Firm{P a en} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Die Anzahl der derzeit verbundenen Clients, die Anzahl der Firmen und die vom Serveradministrator zugelassene maximale Anzahl von Firmen # Matches ConnectionType ###length 5 @@ -2498,13 +2487,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :Warten auf Neub STR_NETWORK_MESSAGE_CLIENT_LEAVING :geht STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} ist dem Spiel beigetreten -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} ist dem Spiel beigetreten (Teilnehmer #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} ist der Firma #{2:NUM} beigetreten +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} ist dem Spiel beigetreten (Teilnehmer #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} ist der Firma #{2:NUM} beigetreten STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} ist den Zuschauern beigetreten -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} hat eine neue Firma gegründet (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} hat das Spiel verlassen ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} hat eine neue Firma gegründet (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} hat das Spiel verlassen ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} hat den eigenen Namen zu {STRING} geändert -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} gab {2:CURRENCY_LONG} an {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} gab {2:CURRENCY_LONG} an {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Der Server hat das Spiel beendet STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Der Server startet neu...{}Bitte warten... STR_NETWORK_MESSAGE_KICKED :*** {STRING} wurde vom Server hinausgeworfen. Grund: ({STRING}) @@ -2618,6 +2607,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}ausgeglichen STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}überlastet +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} Zum Transport pro Monat votgesehen von {STATION} zu {STATION}({COMMA}% der Kapazitäten){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} ZUM Rücktransport vorgesehen ({COMMA}% der Kapazitäten) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Durchschnittliche Reisezeit: {NUM}{NBSP}Tag{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Einzugsgebiet anzeigen STR_STATION_BUILD_COVERAGE_OFF :{BLACK}aus @@ -2626,6 +2620,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Einzugsg STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Einzugsgebiet anzeigen STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Nimmt an: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Liefert: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Wartungskosten: {GOLD}{CURRENCY_SHORT}/yr # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Verbinde mit Station @@ -2708,8 +2703,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Signalab STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Eisenbahnbrücke auswählen STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Straßenbrücke wählen STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Brückenauswahl – Auf die gewünschte Brücke klicken, um sie zu bauen -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Stahlhängebrücke STR_BRIDGE_NAME_GIRDER_STEEL :Stahlträgerbrücke STR_BRIDGE_NAME_CANTILEVER_STEEL :Auslegerbrücke (Stahl) @@ -2829,7 +2826,7 @@ STR_OBJECT_CLASS_TRNS :Sendemasten STR_PLANT_TREE_CAPTION :{WHITE}Bäume STR_PLANT_TREE_TOOLTIP :{BLACK}Die zu pflanzende Baumart wählen. Wenn auf dem Feld schon ein Baum steht, wird eine zufällige Baumart gepflanzt STR_TREES_RANDOM_TYPE :{BLACK}Zufällige Baumart -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Zufällige Baumart pflanzen. Umschalt schaltet zwischen Bauen und Kostenvoranschlag um +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Zufällige Baumart pflanzen. Strg wählt das Gebiet diagonal aus. Umschalt schaltet zwischen Bauen und Kostenvoranschlag um STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Zufällige Bäume STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Bäume zufällig über die Landschaft verteilen STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2861,6 +2858,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Zufälli STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Stadt an zufälligem Ort gründen STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Viele zufällige Städte STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Das Spielfeld mit zufällig platzierten Städten füllen +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Alle Städte ausbreiten +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Lässt alle Städte sich leicht ausbreiten STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Stadtname STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Stadtnamen eingeben @@ -3125,7 +3124,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Spielsta STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Keine Informationen verfügbar STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Suchtext: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Datei überschreiben STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Existierende Datei wirklich überschreiben? STR_SAVELOAD_DIRECTORY :{STRING} (Verzeichnis) @@ -3139,6 +3138,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Spielfel STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Die Größe des Spielfelds auswählen. Die tatsächlich verfügbare Anzahl Felder wird geringfügig kleiner sein STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Städteanzahl: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Städtenamen: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Wähle die Sprache für die Städtenamen aus STR_MAPGEN_DATE :{BLACK}Datum: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Industriedichte: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Höchster Gipfel: @@ -3152,13 +3153,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Wüstenb STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Wüstenabdeckung um zehn Prozent erhöhen STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Wüstenbedeckung um zehn Prozent verringern STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Landgenerator: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Landschaftstyp: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Gewässermenge: +STR_MAPGEN_SEA_LEVEL :{BLACK}Gewässermenge: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Flüsse: STR_MAPGEN_SMOOTHNESS :{BLACK}Gleichmäßigkeit: STR_MAPGEN_VARIETY :{BLACK}Größe der Geländeformen: STR_MAPGEN_GENERATE :{WHITE}Erzeugen +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF-Einstellungen +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}NewGRF-Einstellungen anzeigen +STR_MAPGEN_AI_SETTINGS :{BLACK}KI Einstellungen +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}KI-Einstellungen anzeigen +STR_MAPGEN_GS_SETTINGS :{BLACK}Spielskripteinstellungen +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Spielskripteinstellungen anzeigen + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Englisch +STR_MAPGEN_TOWN_NAME_FRENCH :Französisch +STR_MAPGEN_TOWN_NAME_GERMAN :Deutsch +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Englisch (Zusätzlich) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Lateinamerikanisch +STR_MAPGEN_TOWN_NAME_SILLY :Verrückt +STR_MAPGEN_TOWN_NAME_SWEDISH :Schwedisch +STR_MAPGEN_TOWN_NAME_DUTCH :Niederländisch +STR_MAPGEN_TOWN_NAME_FINNISH :Finnisch +STR_MAPGEN_TOWN_NAME_POLISH :Polnisch +STR_MAPGEN_TOWN_NAME_SLOVAK :Slowakisch +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norwegisch +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungarisch +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Österreichisch +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumänisch +STR_MAPGEN_TOWN_NAME_CZECH :Tschechisch +STR_MAPGEN_TOWN_NAME_SWISS :Schweizerisch +STR_MAPGEN_TOWN_NAME_DANISH :Dänisch +STR_MAPGEN_TOWN_NAME_TURKISH :Türkisch +STR_MAPGEN_TOWN_NAME_ITALIAN :Italienisch +STR_MAPGEN_TOWN_NAME_CATALAN :Katalanisch # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Spielfeldränder: @@ -3304,6 +3333,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Vorherig STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Gehe zum vorherigen normalen Sprite und überspringe alle Pseudo-, Recolour- und Schriftsprites (springt ggf. vom letzten bis zum ersten Sprite) STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Darstellung des aktuellen Sprites. Die Ausrichtung wird beim Zeichnen des Sprites ignoriert STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Bewege die Sprites und ändere dadurch die X- und Y-Offsets. Strg+Klick um die Sprites 8 Blöcke weit zu bewegen. + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Versatz zentriert +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite zentriert + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Fadenkreuz + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Setze zurück STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Setze die aktuellen relativen Versätze zurück STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X-Versatz: {NUM}, Y-Versatz: {NUM} (Absolut) @@ -3318,18 +3354,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Warnung: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Fehler: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Schwerer Fehler: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Ein schwerer NewGRF-Fehler ist aufgetreten:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Ein NewGRF-Fehler ist aufgetreten:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Das NewGRF „{STRING}“ hat einen kritischen Fehler zurückgegeben:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}Das NewGRF „{STRING}“ hat einen Fehler ist zurückgegeben:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} funktioniert nicht im Zusammenhang mit der von OpenTTD ermittelten TTDPatch-Version -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} ist für die {STRING}-Version von TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} ist für die Nutzung mit {STRING} vorgesehen -STR_NEWGRF_ERROR_INVALID_PARAMETER :Falscher Parameter für {1:STRING}: Parameter {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} muss vor {STRING} geladen werden -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} muss nach {STRING} geladen werden -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} Benötigt OpenTTD-Version {STRING} oder höher +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} ist für die {2:STRING}-Version von TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} ist für die Nutzung mit {2:STRING} vorgesehen +STR_NEWGRF_ERROR_INVALID_PARAMETER :Ungültiger Parameter für {1:STRING}: Parameter {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} muss vor {2:STRING} geladen werden +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} muss nach {2:STRING} geladen werden +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} benötigt OpenTTD-Version {2:STRING} oder höher STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :der NewGRF-Datei, die es übersetzen soll, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Zu viele NewGRFs geladen -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Das Laden von {1:STRING} als statisches NewGRF mit {STRING} könnte Synchronisationsfehler hervorrufen +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Das Laden von {1:STRING} als statisches NewGRF mit {2:STRING} könnte Synchronisationsfehler hervorrufen STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Unerwartetes Sprite (Sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Unbekannte Action-0-Eigenschaft {4:HEX} (Sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Zugriff auf eine ungültige ID (Sprite {3:NUM}) @@ -3461,14 +3497,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Exklusive Trans STR_LOCAL_AUTHORITY_ACTION_BRIBE :Die Stadtverwaltung bestechen ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Im Ort eine kleine Werbekampagne starten, um mehr Passagier- und Frachtaufträge für die eigene Firma zu gewinnen.{}Bewirkt eine temporäre Steigerung der Stationsbewertung in einem kleinen Radius um das Ortszentrum.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Im Ort eine mittlere Werbekampagne starten, um mehr Passagier- und Frachtaufträge für die eigene Firma zu gewinnen.{}Bewirkt eine temporäre Steigerung der Stationsbewertung in einem mittleren Radius um das Ortszentrum.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Im Ort eine große Werbekampagne starten, um mehr Passagier- und Frachtaufträge für die eigene Firma zu gewinnen.{}Bewirkt eine temporäre Steigerung der Stationsbewertung in einem großen Radius um das Ortszentrum.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Die örtlichen Straßenreparaturen finanzieren.{}Der Straßenverkehr wird bis zu 6 Monate beeinträchtigt.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Eine Statue zu Ehren der eigenen Firma errichten.{}Bewirkt eine permanente Steigerung der Stationsbewertung in diesem Ort.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Bau von neuen Gebäuden im Ort finanzieren.{}Bewirkt eine temporäre Steigerung des Ortswachstums in diesem Ort.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Für ein Jahr die exklusiven Transportrechte in der Stadt kaufen.{}Die Stadtverwaltung erlaubt dann nur Passagier- und Frachttransporte der eigenen Firma.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Die Stadtverwaltung bestechen, um die eigene Bewertung zu verbessern. Dabei riskiert man allerdings eine harte Strafe, falls man ertappt wird.{}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Im Ort eine kleine Werbekampagne starten, um mehr Passagier- und Frachtaufträge für die eigene Firma zu gewinnen.{}Bewirkt eine temporäre Steigerung der Stationsbewertung in einem kleinen Radius um das Ortszentrum.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Im Ort eine mittlere Werbekampagne starten, um mehr Passagier- und Frachtaufträge für die eigene Firma zu gewinnen.{}Bewirkt eine temporäre Steigerung der Stationsbewertung in einem mittleren Radius um das Ortszentrum.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Im Ort eine große Werbekampagne starten, um mehr Passagier- und Frachtaufträge für die eigene Firma zu gewinnen.{}Bewirkt eine temporäre Steigerung der Stationsbewertung in einem großen Radius um das Ortszentrum.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Die örtlichen Straßenreparaturen finanzieren.{}Der Straßenverkehr wird bis zu 6 Monate beeinträchtigt.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Eine Statue zu Ehren der eigenen Firma errichten.{}Bewirkt eine permanente Steigerung der Stationsbewertung in diesem Ort.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Bau von neuen Gebäuden im Ort finanzieren.{}Bewirkt eine temporäre Steigerung des Ortswachstums in diesem Ort.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Für ein Jahr die exklusiven Transportrechte in der Stadt kaufen.{}Die Stadtverwaltung erlaubt dann nur Passagier- und Frachttransporte der eigenen Firma.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Die Stadtverwaltung bestechen, um die eigene Bewertung zu verbessern. Dabei riskiert man allerdings eine harte Strafe, falls man ertappt wird.{}{POP_COLOUR}Kosten: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Ziele @@ -3641,15 +3677,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Schiffe STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Kreditzinsen STR_FINANCES_SECTION_OTHER :{GOLD}Sonstiges +STR_FINANCES_TOTAL_CAPTION :{WHITE}Gesamt STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Reingewinn +STR_FINANCES_PROFIT :{WHITE}Gewinn STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Kontostand STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Eigenes Kapital STR_FINANCES_LOAN_TITLE :{WHITE}Kredit STR_FINANCES_INTEREST_RATE :{WHITE}Kreditzinssatz: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maximaler Kredit: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}{CURRENCY_LONG} leihen STR_FINANCES_BORROW_TOOLTIP :{BLACK}Kredit aufnehmen. Strg+Klick, um maximalen Kredit aufzunehmen STR_FINANCES_REPAY_BUTTON :{BLACK}{CURRENCY_LONG} zurückzahlen @@ -3750,7 +3789,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produzie STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Benötigt: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} wartend{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Produktion ändern (Vielfache von 8, maximal 2040) @@ -3780,6 +3819,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Aufträg STR_VEHICLE_LIST_REPLACE_VEHICLES :Fahrzeuge ersetzen STR_VEHICLE_LIST_SEND_FOR_SERVICING :Zur Wartung schicken STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Gewinn im laufenden Jahr: {CURRENCY_LONG} (vergangenes Jahr: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Ins Depot schicken STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Ins Depot schicken @@ -3871,6 +3912,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Zug STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Reichweite: {GOLD}{COMMA} Felder STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Flugzeugtyp: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Alle Frachttypen +STR_CARGO_TYPE_FILTER_FREIGHT :Fracht +STR_CARGO_TYPE_FILTER_NONE :Keine + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Schienenfahrzeugsliste. Einzelheiten durch Anklicken des Fahrzeuges. Strg+Klick schaltet um zwischen Verstecken und Zeigen des Fahrzeugtyps STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Straßenfahrzeugsliste. Für Einzelheiten auf ein Fahrzeug klicken. Strg+Klick schaltet um zwischen Verstecken und Zeigen des Fahrzeugtyps @@ -4039,7 +4085,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :{G=n}Flugzeug STR_ENGINE_PREVIEW_SHIP :{G=n}Schiff STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Kosten: {CURRENCY_LONG} Gewicht: {WEIGHT_SHORT}{}Geschwindigk.: {VELOCITY} Leistung: {POWER}{}Betriebskosten: {CURRENCY_LONG} pro Jahr{}Kapazität: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Preis: {CURRENCY_LONG} Gewicht: {WEIGHT_SHORT}{}Max. Geschwindigkeit: {VELOCITY} Leistung: {POWER} Max. Zugkraft: {6:FORCE}{}Betriebskosten: {4:CURRENCY_LONG}/Jahr{}Kapazität: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Preis: {0:CURRENCY_LONG} Gewicht: {1:WEIGHT_SHORT}{}Max. Geschwindigkeit: {2:VELOCITY} Leistung: {3:POWER} Max. Zugkraft: {6:FORCE}{}Betriebskosten: {4:CURRENCY_LONG}/Jahr{}Kapazität: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Preis: {CURRENCY_LONG} Höchstgeschw.: {VELOCITY}{}Kapazität: {CARGO_LONG}{}Betriebskosten: {CURRENCY_LONG}/Jahr STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Kosten: {CURRENCY_LONG} Max. Geschw.: {VELOCITY}{}Flugzeugtyp: {STRING}{}Kapazität: {CARGO_LONG}, {CARGO_LONG}{}Betriebskosten: {CURRENCY_LONG}/Jahr STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Kosten: {CURRENCY_LONG} Max. Geschw.: {VELOCITY}{}Flugzeugtyp: {STRING}{}Kapazität: {CARGO_LONG}{}Betriebskosten: {CURRENCY_LONG}/Jahr @@ -4198,12 +4244,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Gewicht: STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Gewicht: {LTBLUE}{WEIGHT_SHORT} {BLACK}Leistung: {LTBLUE}{POWER}{BLACK} Max. Geschw.: {LTBLUE}{VELOCITY} {BLACK}Max. Zugkraft: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Gewinn dieses Jahr: {LTBLUE}{CURRENCY_LONG} (letztes Jahr: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Gewinn im laufenden Jahr: {LTBLUE}{CURRENCY_LONG} (vergangenes Jahr: {CURRENCY_LONG}) {BLACK}Min. Leistung: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Zuverlässigkeit: {LTBLUE}{COMMA}% {BLACK}Pannen seit der letzten Wartung: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Gebaut: {LTBLUE}{NUM}{BLACK} Wert: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Kapazität: {LTBLUE}Keine{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapazität: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapazität: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapazität: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapazität: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Kapazität: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transfer-Einnahmen: {LTBLUE}{CURRENCY_LONG} @@ -4472,22 +4519,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Anfangsd STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Wähle ein Anfangsdatum für diesen Fahrplan aus. Mit Strg+Klick wird bei allen Fahrzeugen, die nach demselben Fahrplan unterwegs sind, ein zeitlich versetztes Anfangsdatum gesetzt, so dass die Abstände zwischen den einzelnen Fahrzeugen immer gleich sind. Dazu muss der Fahrplan erst komplett erfasst worden sein. STR_TIMETABLE_CHANGE_TIME :{BLACK}Zeit ändern -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Zeitrahmen für den markierten Auftrag ändern +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Zeitrahmen für den markierten Auftrag ändern. Strg+Klick legt die Zeit für alle Aufträge fest STR_TIMETABLE_CLEAR_TIME :{BLACK}Zeit löschen -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Zeitrahmen für den markierten Auftrag löschen +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Zeitrahmen für den markierten Auftrag löschen. Strg+Klick löscht die Zeit für alle Aufträge STR_TIMETABLE_CHANGE_SPEED :{BLACK}Tempolimit ändern -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Tempolimit beim Ausführen des ausgewählten Auftrags ändern +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Tempolimit beim Ausführen des ausgewählten Auftrags ändern. Strg+Klick legt das Tempo für alle Aufträge fest STR_TIMETABLE_CLEAR_SPEED :{BLACK}Tempolimit löschen -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Tempolimit für das Ausführen des ausgewählten Auftrags löschen +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Tempolimit für das Ausführen des ausgewählten Auftrags löschen. Strg+Klick löscht das Tempo für alle Aufträge STR_TIMETABLE_RESET_LATENESS :{BLACK}Verspätung löschen -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Verspätungsmelder zurücksetzen (das Fahrzeug gilt dann als pünktlich). +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Verspätungsmelder zurücksetzen, damit das Fahrzeug als pünktlich gilt. Strg+Klick wird die gesamte Gruppe zurücksetzen, so dass das späteste Fahrzeug im Zeitplan ist und alle anderen verfrüht sind STR_TIMETABLE_AUTOFILL :{BLACK}Erfassen -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Zeiten automatisch bei der nächsten Fahrt eintragen (Mit Strg+Klick wird versucht, die aktuellen Wartezeiten beizubehalten) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Zeiten automatisch bei der nächsten Fahrt eintragen. Mit Strg+Klick wird versucht, die aktuellen Wartezeiten beizubehalten STR_TIMETABLE_EXPECTED :{BLACK}Voraussichtlich STR_TIMETABLE_SCHEDULED :{BLACK}Fahrplanmäßig @@ -4531,12 +4578,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Eine der STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Debugfenster für KI oder Skripte ist nur auf dem Server verfügbar # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}KI / Skripte einstellen +STR_AI_CONFIG_CAPTION_AI :{WHITE}KI Konfiguration +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Spielskriptkonfiguration STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Das Skript, das im nächsten Spiel geladen wird STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Die KIs, die im nächsten Spiel geladen werden STR_AI_CONFIG_HUMAN_PLAYER :Menschlicher Spieler STR_AI_CONFIG_RANDOM_AI :Zufällige KI STR_AI_CONFIG_NONE :- +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Max. Mitbewerber-Zahl: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Nach oben verschieben STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Die ausgewählte KI in der Liste nach oben verschieben @@ -4544,12 +4593,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Nach unt STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Die ausgewählte KI in der Liste nach unten verschieben STR_AI_CONFIG_GAMESCRIPT :{SILVER}Skript +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parameter STR_AI_CONFIG_AI :{SILVER}KIs -STR_AI_CONFIG_CHANGE :{BLACK}Wähle {STRING} aus -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :KI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Skript +STR_AI_CONFIG_CHANGE_AI :{BLACK}KI auswählen +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Spielskript auswählen STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Lade ein anderes Skript STR_AI_CONFIG_CONFIGURE :{BLACK}Einstellungen STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Einstellungen des Skripts anzeigen oder ändern @@ -4577,10 +4625,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Screensh STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Reliefkartenscreenshot STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Übersichtskartenscreenshot -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameter STR_AI_SETTINGS_CAPTION_AI :KI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Skript +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spielskript STR_AI_SETTINGS_CLOSE :{BLACK}Schließen STR_AI_SETTINGS_RESET :{BLACK}Zurücksetzen STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4744,6 +4792,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... zu v STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Industrie kann nicht erzeugt werden ... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}{STRING} kann hier nicht gebaut werden ... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Industrie kann hier nicht gebaut werden ... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Industrie kann nicht prospektiert werden ... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... zu nah an einer anderen Industrie STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... erst muss eine Stadt gegründet werden STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... pro Stadt nur einmal erlaubt @@ -4758,6 +4807,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... Wald STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... kann nur oberhalb der Schneegrenze errichtet werden STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... kann nur unterhalb der Schneegrenze errichtet werden +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Aufgrund eines Unglücks ist die Prospektierung gescheitert; versuchen Sie es erneut +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Es gab keine geeigneten Orte, wo für diese Industrie prospektiert werden könnte STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Es konnten für die Industrie „{STRING}“ keine geeigneten Standorte gefunden werden STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Karteneinstellungen ändern, um eine bessere Karte zu erzeugen @@ -4925,6 +4976,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objekt i STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... Firmensitz ist im Weg STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Das Land kann nicht erworben werden ... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... ist bereits im Besitz der eigenen Firma! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... Baulimit erreicht # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Gruppe kann nicht erstellt werden ... @@ -4997,6 +5049,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Das Wart STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... Fahrzeug ist zerstört +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... es sind nicht alle Fahrzeuge identisch + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Es sind keine Fahrzeuge verfügbar! STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Bitte die NewGRF-Einstellungen ändern, damit Fahrzeuge früher verfügbar sind STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Noch keine Fahrzeuge verfügbar @@ -5023,6 +5077,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Springen STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... Fahrzeug kann nicht alle Stationen erreichen STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... Fahrzeug kann diese Station nicht erreichen STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... ein Fahrzeug, welches diesen gemeinsamen Fahrplan nutzt, kann die Station nicht erreichen +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... es haben nicht alle Fahrzeuge die gleichen Aufträge +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... es teilen sich nicht alle Fahrzeuge die Aufträge STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Fehler beim Erstellen eines gemeinsam genutzten Fahrplans ... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Gemeinsame Aufträge können nicht aufgehoben werden... @@ -5030,6 +5086,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Fahrplan STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... zu weit vom vorherigen Bestimmungsort entfernt STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... Luftfahrzeug hat zu geringe Reichweite +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Es gibt keinen Bahnhof +STR_ERROR_NO_BUS_STATION :{WHITE}Es gibt keine Bushaltestelle +STR_ERROR_NO_TRUCK_STATION :{WHITE}Es gibt keinen Lkw-Ladeplatz +STR_ERROR_NO_DOCK :{WHITE}Es gibt keine Anlegestelle +STR_ERROR_NO_AIRPORT :{WHITE}Es gibt keinen Flughafen/Hubschrauberlandeplatz +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Es gibt keine Haltestellen mit einem kompatiblen Straßentyp +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Es gibt keine Haltestellen mit einen kompatiblen Straßenbahntyp +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Es gibt keine Haltestellen, welche für Gelenkstraßenfahrzeuge geeignet sind.{}Gelenkstraßenfahrzeuge benötigen eine Durchfahrtshaltestelle, keine Haltebucht +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Dieses Flugzeug kann nicht auf diesen Hubschrauberlandeplatz landen +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Dieser Helikopter kann auf diesen Flughafen nicht landen +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Es gibt keinen Gleiswegpunkt +STR_ERROR_NO_BUOY :{WHITE}Es gibt keine Boje + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Fahrplan kann nicht erstellt werden ... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Fahrzeuge halten nur an Stationen diff --git a/src/lang/greek.txt b/src/lang/greek.txt index 4dcbad8d952e3..3d80085a839a5 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -261,6 +261,15 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}τ. STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}τ. STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -439,7 +448,7 @@ 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 εναλλάσσει κτίσιμο/εμφάνιση εκτίμησης κόστους +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Τοποθέτηση αντικειμένου. Ctrl για διαγώνια επιλογή περιοχής. Το Shift εναλλάσσει κτίσιμο/εμφάνιση εκτίμησης κόστους # Scenario editor file menu ###length 7 @@ -452,10 +461,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Έξοδος # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Επιλογές παιχνιδιού STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Ρυθμίσεις -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Ρυθμίσεις ΑΙ και Δέσμης Ενεργειών +STR_SETTINGS_MENU_AI_SETTINGS :Ρυθμίσεις AI +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Ρυθμίσεις σενάριου παιχνιδιού STR_SETTINGS_MENU_NEWGRF_SETTINGS :Ρυθμίσεις NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Επιλογές διαφάνειας STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Εμφάνιση ονομάτων πόλεων @@ -1072,36 +1082,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Ρουπία Ι STR_GAME_OPTIONS_CURRENCY_IDR :Ινδονησιακή Ρουπία (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ρινγκίτ Μαλαισίας (MYR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}Επιλογή στυλ ονομάτων πόλεων - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Αγγλικά (Αυθεντικά) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Γαλλικά -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Γερμανικά -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Αγγλικά (Πρόσθετα) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Λατινοαμερικάνικα -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Αστεία -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Σουηδικά -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Ολλανδικά -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Φινλανδικά -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Πολωνικά -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Σλοβάκικα -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Νορβηγικά -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ουγγρικά -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Αυστριακά -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Ρουμάνικα -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Τσέχικα -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Ελβετικά -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Δανέζικα -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Τούρκικα -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Ιταλικά -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Καταλανικά - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Αυτόματη αποθήκευση STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Επιλογή διάκενου ανάμεσα στις αυτόματες αποθηκεύσεις @@ -1132,22 +1112,21 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Η ρύ STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Τσεκάρετε αυτό το κουτί για να ενεργοποιήσετε το v-sync στην οθόνη. Η αλλαγή αυτή θα εφαρμοστεί μετά από επανεκκίνηση του παιχνιδιού. Λειτουργεί μόνο με ενεργοποιημένη την επιτάχυνση υλικού +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Τρέχον οδηγός: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Μέγεθος διεπαφής -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Επιλέξτε το μέγεθος στοιχείου διεπαφής +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Μέγεθος διεπαφής +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Σύρετε το κουμπί για να θέσετε μέγεθος διεπαφής. Κρατήστε πατημένο το Ctrl για συνεχής αλλαγή +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Αυτόματη εντόπιση μεγέθους +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Τσεκάρετε αυτό το κουτάκι για να ανιχνεύεται το μέγεθος της διεπαφής αυτόματα -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(αυτόματη ανίχνευση) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Κανονικό -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Διπλό μέγεθος -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Τετραπλό μέγεθος +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Κλίση κλίμακας +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Τσεκάρετε αυτό το κουτί για να αλλάζει μέγεθος το περίγραμμα με βάση το μέγεθος της διεπαφής -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Μέγεθος γραμματοσειράς -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Επιλέξτε το μέγεθος της γραμματοσειράς διεπαφής - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(αυτόματη ανίχνευση) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Κανονικό -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Διπλό μέγεθος -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Τετραπλό μέγεθος +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Γραφικά @@ -1199,8 +1178,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Προ STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 λίρες (£) στο νόμισμά σας STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Αλλαγή παραμέτρων προσαρμοσμένου νομίσματος -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Μέγιστος αρ. ανταγωνιστών: {ORANGE}{COMMA} - STR_NONE :Κανένα STR_FUNDING_ONLY :Χρηματοδότηση μονο STR_MINIMAL :Ελάχιστο @@ -1250,6 +1227,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Εύκρατο τοπίο +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Πολικό τοπίο +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Υποτροπικό τοπίο +STR_CLIMATE_TOYLAND_LANDSCAPE :Τοπίο παιχνιδότοπου + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Πολύ Επίπεδο STR_TERRAIN_TYPE_FLAT :Επίπεδο @@ -1260,6 +1243,7 @@ STR_TERRAIN_TYPE_CUSTOM :Προσαρμ STR_TERRAIN_TYPE_CUSTOM_VALUE :Προσαρμοσμένο ύψος ({NUM}) ###length 4 +STR_CITY_APPROVAL_LENIENT :Ήπειο STR_CITY_APPROVAL_TOLERANT :Υπομονετική STR_CITY_APPROVAL_HOSTILE :Εχθρική STR_CITY_APPROVAL_PERMISSIVE :Ανεκτική @@ -1328,6 +1312,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Δεξιά STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Μέγιστο αρχικό δάνειο: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Μέγιστο ποσό που μπορεί να δανειστεί μία εταιρία (χωρίς να λαμβάνεται υπόψη ο πληθωρισμός) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Επιτόκιο: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Επιτόκιο δανείων· επίσης ελέγχεται ο πληθωρισμός αν είναι ενεργοποιημένος @@ -1554,6 +1539,8 @@ 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_SHOW_CARGO_IN_LISTS :Εμφάνιση όλων των αποδεκτών φορτίων οχημάτων στις λίστες εικονίδιων {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Όταν είναι ενεργοποιημένο, το μεταφέρσημο φορτίο του οχήματος θα εμφανίζεται από πάνω του στις λίστες οχημάτων STR_CONFIG_SETTING_LANDSCAPE :Τοπίο: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Τα τοπία ορίζουν βασικά σενάρια παιχνιδιού με διαφορετικά φορτία και προϋποθέσεις επέκτασης πόλεων. Παρ' όλα αυτά, τα NewGRF και οι Δέσμες Ενεργειών Παιχνιδιού επιτρέπουν πιο λεπτό χειρισμό @@ -1608,6 +1595,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Βελτιωμ STR_CONFIG_SETTING_ROAD_SIDE :Οχήματα δρόμου: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Επιλέξτε την πλευρά οδήγησης +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Οδηγούν από αριστερά +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Οδηγούν από δεξιά + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Περιστροφή χάρτη υψομετρίας: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Αριστερόστροφη @@ -1634,7 +1625,13 @@ 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_LINKGRAPH_COLOURS :Χρώμα επίστρωσης ροής φορτίου: {STRING} +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_HELPTEXT :Θέσημο της παλέτας χρωμάτων που θα χρησιμοποιηθούν για την επίστρωση ροής φορτίου ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :Πράσινο σε κόκκινο (Αρχικό) +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Πράσινο σε μπλέ +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Γκρι σε μπλε +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :Ασπρόμαυρο STR_CONFIG_SETTING_SCROLLMODE :Συμπεριφορά κύλισης του παραθύρου εμφάνισης: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Συμπεριφορά κατά την κύλιση του χάρτη @@ -2136,7 +2133,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Αυτόματ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Επιτρέπεται στα τρένα να αντιστραφούν σε σήμα, εάν περιμένουν εκεί για πολύ ώρα ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Συνίσταται) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Συνίσταται) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Αλλαγή τιμής ρύθμισης @@ -2179,7 +2176,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Πίνα STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Ρυθμίσεις STR_INTRO_NEWGRF_SETTINGS :{BLACK}Ρυθμίσεις NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Διαδικτυακό Περιεχόμενο -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Ρυθμίσεις AI και Δέσμης Ενεργειών +STR_INTRO_AI_SETTINGS :{BLACK}Ρυθμίσεις AI +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Ρυθμίσεις σενάριου παιχνιδιού STR_INTRO_QUIT :{BLACK}Έξοδος STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Έναρξη νέου παιχνιδιού. Με Ctrl+Κλικ παρακάμπτεται η ρύθμιση του χάρτη @@ -2199,7 +2197,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Εμφά STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Ρυθμίσεις οθόνης STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Εμφάνιση ρυθμίσεων NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Έλεγχος για νέο και ανανεωμένο περιεχόμενο για λήψη -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Εμφάνιση ρυθμίσεων για AI και της δέσμης ενεργειών του παιχνιδιού +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Εμφάνιση ρυθμίσεων ΑΙ +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Εμφάνιση ρυθμίσεων σενάριου παιχνιδιού STR_INTRO_TOOLTIP_QUIT :{BLACK}Έξοδος από το «OpenTTD» STR_INTRO_BASESET :{BLACK}Λείπουν {NUM} sprite{P "" s} από το επιλεγμένο βασικό σετ γραφικών. Παρακαλούμε ελέγξτε για ενημερώσεις του βασικού σετ. @@ -2231,12 +2230,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Αλλ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Αλλαγή τρέχοντος έτους STR_CHEAT_SETUP_PROD :{LTBLUE}Ενεργοποίηση δυνατότητας αλλαγής τιμών παραγωγής: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Εύκρατο τοπίο -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Πολικό τοπίο -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Υποτροπικό τοπίο -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Τοπίο παιχνιδότοπου - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Νέος Χρωματισμός @@ -2469,7 +2462,6 @@ 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_CLIENT_COMPANY_COUNT :{BLACK}{NUM} πελάτης/ες / {NUM} εταιρία/ες # Matches ConnectionType ###length 5 @@ -2716,6 +2708,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}κορεσμένο STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}υπερφορτωμένο +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} προς μεταφορά κάθε μήνα από {STATION} στο {STATION} ({COMMA}% χωρητικότητας){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} προς μεταφορά πίσω ({COMMA}% της χωρητικότητας) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Μέσος χρόνος ταξιδιού: {NUM}{NBSP}{P "ημέρα" "ημέρες"} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Κάλυψη περιοχής STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Ανενεργό @@ -2724,6 +2721,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Μη ε STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Εμφάνιση κάλυψης του προτεινόμενου τόπου STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Δέχεται: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Προμηθεύει : {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Κόστος συντήρησης: {GOLD}{CURRENCY_SHORT}/έτος # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Συνένωση σταθμού @@ -2806,8 +2804,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Αύξη STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Επιλογή Γέφυρας STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Επιλογή Γέφυρας Δρόμου STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Επιλογή γέφυρας - πατήστε στην γέφυρα της προτίμησής σας για κατασκευή -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Ατσάλινη, με Αναρτήσεις STR_BRIDGE_NAME_GIRDER_STEEL :Ατσάλινη, με Δοκούς STR_BRIDGE_NAME_CANTILEVER_STEEL :Ατσάλινη, Κρεμαστή @@ -2959,6 +2955,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Τυχα STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Ίδρυση πόλης σε τυχαία τοποθεσία STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Πολλές τυχαίες πόλεις STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Κάλυψη του χάρτη με τυχαία τοποθετημένες πόλεις +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Επέκταση όλων των πόλεων +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Κάνε όλες τις πόλεις να επεκτείνονται λιγάκι STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Όνομα πόλης: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Εισάγετε το όνομα της πόλης @@ -3237,6 +3235,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Διάσ STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Επιλέξτε το μέγεθος του χάρτη σε τετραγωνίδια. Ο αριθμός των τετραγωνίδιων διαθέσιμα για κτίσιμο θα είναι λίγο χαμηλότερος STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Αριθμός πόλεων: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Ονόματα πόλεων: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Επιλογή στυλ ονομάτων πόλεων STR_MAPGEN_DATE :{BLACK}Ημερομηνία: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Αριθμός βιομηχανιών: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Υψηλότερη κορυφή: @@ -3250,13 +3250,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Κάλυ STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Αύξηση κάλυψης ερήμου κατά δέκα τοις εκατό STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Μείωση κάλυψης ερήμου κατά δέκα τοις εκατό STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Δημιουργός εδάφους: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Τύπος εδάφους: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Επίπεδο θάλασσας: +STR_MAPGEN_SEA_LEVEL :{BLACK}Επίπεδο θάλασσας: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Ποτάμια: STR_MAPGEN_SMOOTHNESS :{BLACK}Ομαλότητα: STR_MAPGEN_VARIETY :{BLACK}Διανομή ποικιλομορφίας: STR_MAPGEN_GENERATE :{WHITE}Δημιουργία +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Ρυθμίσεις NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Εμφάνιση ρυθμίσεων NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Ρυθμίσεις AI +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Εμφάνιση ρυθμίσεων AI +STR_MAPGEN_GS_SETTINGS :{BLACK}Ρυθμίσεις σενάριου παιχνιδιού +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Εμφάνιση ρυθμίσεων σενάριου παιχνιδιού + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Αγγλικά (Αυθεντικά) +STR_MAPGEN_TOWN_NAME_FRENCH :Γαλλικά +STR_MAPGEN_TOWN_NAME_GERMAN :Γερμανικά +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Αγγλικά (Πρόσθετα) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Λατινοαμερικάνικα +STR_MAPGEN_TOWN_NAME_SILLY :Αστεία +STR_MAPGEN_TOWN_NAME_SWEDISH :Σουηδικά +STR_MAPGEN_TOWN_NAME_DUTCH :Ολλανδικά +STR_MAPGEN_TOWN_NAME_FINNISH :Φινλανδικά +STR_MAPGEN_TOWN_NAME_POLISH :Πολωνικά +STR_MAPGEN_TOWN_NAME_SLOVAK :Σλοβάκικα +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Νορβηγικά +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ουγγρικά +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Αυστριακά +STR_MAPGEN_TOWN_NAME_ROMANIAN :Ρουμάνικα +STR_MAPGEN_TOWN_NAME_CZECH :Τσέχικα +STR_MAPGEN_TOWN_NAME_SWISS :Ελβετικά +STR_MAPGEN_TOWN_NAME_DANISH :Δανέζικα +STR_MAPGEN_TOWN_NAME_TURKISH :Τούρκικα +STR_MAPGEN_TOWN_NAME_ITALIAN :Ιταλικά +STR_MAPGEN_TOWN_NAME_CATALAN :Καταλανικά # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Άκρες χάρτη: @@ -3402,6 +3430,12 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Προη STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Προχώρησε στο προηγούμενο κανονικό sprite, προσπερνώντας οποιαδήποτε ψευδό/επαναχρωματιζόμενα/γραμματοσειράς sprites και ξαναεκτέλεσε τη διαδικασία από το πρώτο sprite ως το τελεταίο STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Επανεμφάνιση του επιλεγμένου sprite. Η ευθυγράμμιση αγνοείται όταν γίνεται η σχεδίαση του sprite STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Μετακίνηση του sprite τριγύρω, αλλάζοντας τα στίγματα Χ και Υ. Ctrl+Κλικ για να μετακινήσετε το sprite μονάδες τη φορά. + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Μετατόπιση κέντρου +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Ευθυγραμμισμένα sprite + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Επαναφορά σχετικού STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Επαναφορά των τρεχούμενων σχετικών στιγμάτων STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Στίγμα X: {NUM}, Στίγμα Y: {NUM} (Απόλυτο) @@ -3416,15 +3450,13 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Προειδοποίηση: {SILVER}{STRING} 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} δεν θα δουλέψει με την έκδοση του TTDPatch όπως αναφέρεται από το OpenTTD STR_NEWGRF_ERROR_DOS_OR_WINDOWS :Το {1:STRING} είναι για την έκδοση {STRING} του TTD STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} είναι σχεδιασμένο να δουλέψει με το {STRING} STR_NEWGRF_ERROR_INVALID_PARAMETER :Λάθος παράμετρος για το {1:STRING}: παράμετρος {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :Το {1:STRING} πρέπει να φορτωθεί πριν από το {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :Το {1:STRING} πρέπει να φορτωθεί μετά από το {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :Το {1:STRING} απαιτεί έκδοση OpenTTD {STRING} ή καλύτερη +STR_NEWGRF_ERROR_LOAD_BEFORE :Το {1:STRING} πρέπει να φορτωθεί πριν από το {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :Το {1:STRING} πρέπει να φορτωθεί μετά από το {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :Το {1:STRING} απαιτεί έκδοση OpenTTD {2:STRING} ή υψηλότερη STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :το αρχείο GRF είναι σχεδιασμένο για να μεταφράζει STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Έχουν φορτωθεί πολλά NewGRF STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Η φόρτωση του {1:STRING} ως στατικό NewGRF με {STRING} μπορεί να προκαλέσει αποσυγχρονισμούς @@ -3561,9 +3593,9 @@ STR_LOCAL_AUTHORITY_ACTION_BRIBE :Δωροδοκ ###length 8 STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Έναρξη μικρής τοπικής διαφημιστικής καμπάνιας, για να προσελκύσετε περισσότερους επιβάτες και εμπορεύματα στις μεταφορικές σας υπηρεσίες.{}Παρέχει μία προσωρινή ώθηση στην βαθμολογία σταθμών σε μία μικρή ακτίνα γύρω από το κέντρο της πόλης.{} Κόστος: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Έναρξη μεσαίας τοπικής διαφημιστικής καμπάνιας, για να προσελκύσετε περισσότερους επιβάτες και εμπορεύματα στις μεταφορικές σας υπηρεσίες.{}Παρέχει μία προσωρινή ώθηση στην βαθμολογία σταθμών σε μία μεσαία ακτίνα γύρω από το κέντρο της πόλης.{} Κόστος: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Έναρξη μεγάλης τοπικής διαφημιστικής καμπάνιας, για να προσελκύσετε περισσότερους επιβάτες και εμπορεύματα στις μεταφορικές σας υπηρεσίες.{}Παρέχει μία προσωρινή ώθηση στην βαθμολογία σταθμού σε μία μεγάλη ακτίνα γύρω από το κέντρο της πόλης.{} Κόστος: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Έναρξη μεγάλης τοπικής διαφημιστικής καμπάνιας, για να προσελκύσετε περισσότερους επιβάτες και εμπορεύματα στις μεταφορικές σας υπηρεσίες.{}Παρέχει μία προσωρινή ώθηση στην βαθμολογία σταθμού σε μία μεγάλη ακτίνα γύρω από το κέντρο της πόλης.{}{POP_COLOUR} Κόστος: {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_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Χτίστε ένα άγαλμα προς τιμήν της εταιρίας σας.{}Παρέχει μία μόνιμη ώθηση στην βαθμολογία σταθμών σε αυτή την πόλη.{}{POP_COLOUR}Κόστος: {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} @@ -3719,6 +3751,9 @@ STR_FINANCES_CAPTION :{WHITE}{COMPANY STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}Έσοδα +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Έξοδα λειτουργίας +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Έξοδα κεφαλαίου ###length 13 @@ -3726,17 +3761,29 @@ STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Κατα STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Νέα Οχήματα STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Λειτουργικά Έξοδα Τρένων STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Λειτουργικά Έξοδα Οχημάτων -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Λειτουργικά Έξοδα Αεροσκαφών +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Αεροσκάφη STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Λειτουργικά Έξοδα Πλοίων +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Υποδομές +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Τρένα +STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}Οχήματα δρόμου +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Αεροσκάφη +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Πλοία +STR_FINANCES_SECTION_SHIP_REVENUE.geniki :{GOLD}Πλοίων STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Τόκοι Δανείου STR_FINANCES_SECTION_OTHER :{GOLD}Άλλα -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} +STR_FINANCES_TOTAL_CAPTION :{WHITE}Σύνολο +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Κέρδος STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Υπόλοιπο Τραπέζης +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Τα χρήματα σου STR_FINANCES_LOAN_TITLE :{WHITE}Δάνειο +STR_FINANCES_INTEREST_RATE :{WHITE}Επιτόκιο δάνειου: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Μέγιστο Δάνειο: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Δανεισμός {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Αύξηση του ποσού του δανείου. Πατήστε Ctrl+Κλικ για να δανειστείτε όσο περισσότερο γίνεται STR_FINANCES_REPAY_BUTTON :{BLACK}Αποπληρωμή {CURRENCY_LONG} @@ -3867,6 +3914,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Στεί STR_VEHICLE_LIST_REPLACE_VEHICLES :Αντικατάσταση οχημάτων STR_VEHICLE_LIST_SEND_FOR_SERVICING :Στείλτε για Επισκευή STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Κέρδος αυτό το έτος: {CURRENCY_LONG} (προηγούμενο έτος: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Στείλτε στο Υπόστεγο STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Στείλτε στο Αμαξοστάσιο @@ -3958,6 +4007,12 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Μέγ. STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Εύρος: {GOLD}{COMMA} τετραγωνίδια STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Τύπος αεροσκάφους: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Όλα τα είδη φορτίων +STR_CARGO_TYPE_FILTER_FREIGHT :Φορτίο +STR_CARGO_TYPE_FILTER_FREIGHT.geniki :Φορτίου +STR_CARGO_TYPE_FILTER_NONE :Κανένα + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Λίστα επιλογής βαγονιού τρένου. Πατήστε σε ένα βαγόνι για πληροφορίες. Ctrl+Click για εμφάνιση/απόκρυψη του τύπου βαγονιού STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Λίστα επιλογής οχήματος δρόμου. Πατήστε σε ένα όχημα για πληροφορίες. Ctrl+Click για εμφάνιση/απόκρυψη του τύπου οχήματος @@ -4291,6 +4346,7 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Βάρο STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Βάρος: {LTBLUE}{WEIGHT_SHORT} {BLACK}Δύναμη Κινητήρα: {LTBLUE}{POWER}{BLACK} Μέγ. Ταχύτητα: {LTBLUE}{VELOCITY} {BLACK}Μέγ. Ε.Δ: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Κέρδη αυτό το έτος: {LTBLUE}{CURRENCY_LONG} (προηγούμενου έτους: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Φετινό κέρδος: {LTBLUE}{CURRENCY_LONG} (Περσινό: {CURRENCY_LONG}) {BLACK}Ελάχιστη απόδοση: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Αξιοπιστία: {LTBLUE}{COMMA}% {BLACK}Καταρρεύσεις μετά από την τελευταία επισκευή: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Κατασκευή: {LTBLUE}{NUM}{BLACK} Αξία: {LTBLUE}{CURRENCY_LONG} @@ -4322,7 +4378,7 @@ STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Αξία: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Συνολική χωρητικότητα φορτίου του τρένου: -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Άδειο @@ -4568,7 +4624,7 @@ STR_TIMETABLE_CHANGE_TIME :{BLACK}Αλλα STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Αλλάζει ο χρόνος που παίρνει η επιλεγμένη επιλογή για να εκτελεστεί STR_TIMETABLE_CLEAR_TIME :{BLACK}Εκκαθάριση Χρόνων -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Εκκαθαρίζει το χρόνο για την επιλεγμένη εντολή +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Εκκαθαρίζει το χρόνο για την επιλεγμένη εντολή. Ctrl+Κλικ σβήνει τον χρόνο για όλες τις εντολές STR_TIMETABLE_CHANGE_SPEED :{BLACK}Αλλαγή Ορίου Ταχύτητας STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Αλλαγή της μέγιστης ταχύτητας ταξιδιού της επιλεγμένης εντολής @@ -4580,7 +4636,7 @@ STR_TIMETABLE_RESET_LATENESS :{BLACK}Επαν STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Επαναφορά του μετρητή καθυστέρησης, ώστε το όχημα να είναι στην ώρα του STR_TIMETABLE_AUTOFILL :{BLACK}Αυτόματη Γέμιση -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Συμπληρώστε το δρομολόγιο αυτόματα με τις τιμές από το επόμενο ταξίδι (Ctrl+Κλικ για να προσπαθήσει να κρατήσει τους χρόνους αναμονής) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Συμπληρώστε το δρομολόγιο αυτόματα με τις τιμές από το επόμενο ταξίδι. (Ctrl+Κλικ για να προσπαθήσει να κρατήσει τους χρόνους αναμονής) STR_TIMETABLE_EXPECTED :{BLACK}Αναμενόμενη STR_TIMETABLE_SCHEDULED :{BLACK}Προγραμματισμένη @@ -4624,12 +4680,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Μια STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Το παράθυρο αποσφαλμάτωσης ΑΙ και δέσμης ενεργειών είναι διαθέσιμο μόνο για τον διακομιστή # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Ρύθμιση ΑΙ και Δέσμης Ενεργειών +STR_AI_CONFIG_CAPTION_AI :{WHITE}Ρύθμιση ΤΝ +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Ρύθμηση δέσμης ενεργειών παιχνιδιού STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Η Δέσμη Ενεργειών παιχνιδιού που θα φορτωθεί στο επόμενο παιχνίδι STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Οι AIs που θα φορτωθούν στο επόμενο παιχνίδι STR_AI_CONFIG_HUMAN_PLAYER :Ανθρώπινος παίκτης STR_AI_CONFIG_RANDOM_AI :Τυχαία AI STR_AI_CONFIG_NONE :{G=f}(καμία) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Μέγιστος αρ. ανταγωνιστών: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Μετακίνηση Πάνω STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Μετακίνηση της επιλεγμένης AI πάνω στη λίστα @@ -4637,12 +4695,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Μετα STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Μετακίνηση της επιλεγμένης AI κάτω στη λίστα STR_AI_CONFIG_GAMESCRIPT :{SILVER}Δέσμη Ενεργειών +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Παράμετροι STR_AI_CONFIG_AI :{SILVER}AI -STR_AI_CONFIG_CHANGE :{BLACK}Επιλογή {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :ΑΙ -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Δέσμη Ενεργειών +STR_AI_CONFIG_CHANGE_AI :{BLACK}Διάλεξε ΤΝ +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Δέσμη Ενεργειών STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Φόρτωση άλλης δέσμης ενεργειών STR_AI_CONFIG_CONFIGURE :{BLACK}Ρυθμίσεις STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Ρύθμιση των παραμέτρων της Δέσμης Ενεργειών @@ -4670,10 +4727,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Στιγ STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Στιγμιότυπο χάρτη υψομετρίας STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Στιγμιότυπο μίνι χάρτη -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Παράμετροι +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Δέσμη Ενεργειών STR_AI_SETTINGS_CLOSE :{BLACK}Κλείσιμο STR_AI_SETTINGS_RESET :{BLACK}Επαναφορά STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4837,6 +4892,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... πά STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Δε γίνεται να δημιουργηθούν βιομηχανίες... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Δεν μπορεί να κτιστεί {G ο η το} {STRING} εδώ... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Δεν είναι δυνατό να κτιστεί αυτός ο τύπος βιομηχανίας εδώ... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Δεν βρέθηκαν ευκαιρίες για τη βιομηχανία... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... πολύ κοντά σε άλλη βιομηχανία STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... πρέπει να κτιστεί πόλη πρώτα STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... επιτρέπεται μόνο μία ανά πόλη @@ -4851,6 +4907,7 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... δά STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... μπορεί να κτιστεί μόνο πάνω από τη γραμμή του χιονιού STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... μπορεί να κτιστεί μόνο κάτω από τη γραμμή του χιονιού +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Η χρηματοδότηση απέτυχε να προσκομήσει αποτελέσματα λόγω κακής τύχης· δοκιμάστε ξάνα STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Δεν υπήρχαν διαθέσιμες τοποθεσίες για βιομηχανίες τύπου '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Αλλαγή παραμέτρων δημιουργίας χάρτη για καλύτερα αποτελέσματα @@ -5018,6 +5075,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Αντι STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... κεντρικά γραφεία εταιρίας στη μέση STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Αδύνατο να αγοραστεί το έδαφος... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... είστε ήδη ιδιοκτήτης! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... έχετε φτάσει το όριο οικοδομήσεων # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Δεν μπορεί να δημιουργηθεί ομάδα... @@ -5090,6 +5148,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Δεν STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... το όχημα καταστράφηκε +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... όλα τα οχήματα δεν είναι ίδια + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Δεν θα είναι κανένα όχημα διαθέσιμο STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Αλλάξτε τις ρύθμισεις NewGRF σας STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Κανένα όχημα δεν είναι διαθέσιμο ακόμη @@ -5116,6 +5176,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Δεν STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... το όχημα δεν μπορεί να πάει σε όλους τους σταθμούς STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... το όχημα δεν μπορεί να πάει σε αυτόν τον σταθμό STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... ένα όχημα που μοιράζεται αυτή την εντολή δεν μπορεί να πάει σε εκείνο τον σταθμό +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... όλα τα οχήματα δεν έχουν τις ίδιες εντολές +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... δε μοιράζουν διαταγές όλα τα οχήματα STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Αδύνατο να μοιραστεί η λίστα εντολών... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Δεν μπορεί να σταματήσει να μοιράζεται η λίστα εντολών... @@ -5123,6 +5185,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Αδύν STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... πολύ μακριά από τον προηγούμενο προορισμό STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... δεν επαρκεί η εμβέλεια του αεροσκάφους +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Δεν μπορεί να δρομολογηθεί το όχημα... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Τα οχήματα μπορούν να περιμένουν μόνο στους σταθμούς diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index 50fd813149af5..7ec05cd2f0008 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -211,6 +211,8 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}כ"ס STR_UNITS_POWER_METRIC :{COMMA}כ"ס STR_UNITS_POWER_SI :{COMMA}קילו וואט +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}ט' STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}ט' STR_UNITS_WEIGHT_SHORT_SI :{COMMA}ק"ג @@ -323,6 +325,7 @@ STR_SORT_BY_CARGO_CAPACITY :קיבולת ס STR_SORT_BY_RANGE :טווח STR_SORT_BY_POPULATION :אכלוסיה STR_SORT_BY_RATING :דרוג +STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR :סה"כ רווח שנה שעברה # Group by options for vehicle list @@ -388,10 +391,10 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :יציאה # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :אפשרויות המשחק STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :הגדרות -STR_SETTINGS_MENU_SCRIPT_SETTINGS :הגדרות סקריפטים של משחק/שחקני מחשב +STR_SETTINGS_MENU_AI_SETTINGS :הגדרות בינה מלאכותית STR_SETTINGS_MENU_NEWGRF_SETTINGS :הגדרות GRF חדש STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :אפשרויות שקיפות STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :שמות ערים @@ -942,36 +945,7 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :אחר... STR_GAME_OPTIONS_CURRENCY_GEL :לארי גאורגי (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :ריאל איראני (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :רובל רוסי (RUB) - -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}בחר סגנון של שמות הערים - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :אנגלית -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :צרפתית -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :גרמנית -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :אנגלית -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :אמריקאי-לטיני -STR_GAME_OPTIONS_TOWN_NAME_SILLY :מצחיק -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :שוודית -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :הולנדית -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :פינית -STR_GAME_OPTIONS_TOWN_NAME_POLISH :פולנית -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :סלובקית -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :נורבגית -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :הונגרית -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :אוסטרית -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :רומנית -STR_GAME_OPTIONS_TOWN_NAME_CZECH :צ'כית -STR_GAME_OPTIONS_TOWN_NAME_SWISS :שווצרית -STR_GAME_OPTIONS_TOWN_NAME_DANISH :דנית -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :טורקית -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :איטלקית -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :רומאית +STR_GAME_OPTIONS_CURRENCY_INR :רופי הודי (INR) STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}שמירה אוטומטית STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}בחר פרק זמן בין שמירות אוטומטיות @@ -986,6 +960,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 על כל המסך @@ -993,20 +968,21 @@ STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}סמן STR_GAME_OPTIONS_RESOLUTION :{BLACK}רזלוציית המסך STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}בחר את רזולוציית המסך STR_GAME_OPTIONS_RESOLUTION_OTHER :אחר +STR_GAME_OPTIONS_RESOLUTION_ITEM :{NUM}x{NUM} +STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}גודל ממשק -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}בחר את ממשק גודל העצם לשימוש - -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :רגיל -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :גודל כפול -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :גודל מרובע +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GRAPHICS :{BLACK}גרפיקה +STR_GAME_OPTIONS_REFRESH_RATE_WARNING :{WHITE}עדכוני סמך מעל 60Hz עלולים להשפיע על ביצועים. STR_GAME_OPTIONS_BASE_GRF :{BLACK}ערכת גרפיקה בסיסית STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}בחר בערכת גרפיקה בסיסית לשימוש @@ -1051,8 +1027,6 @@ STR_CURRENCY_PREVIEW :{ORANGE}{CURREN STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 ליש"ט (£) במטבע שלך STR_CURRENCY_CHANGE_PARAMETER :{BLACK}שנה פרמטר עבור מטבע מותאם אישית -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{ORANGE}{COMMA}{LTBLUE} : מספר מתחרים מירבי - STR_NONE :ללא STR_FUNDING_ONLY :מימון בלבד STR_MINIMAL :מזערי @@ -1102,6 +1076,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :אקלים ממוזג +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :אקלים קר +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :אקלים טרופי +STR_CLIMATE_TOYLAND_LANDSCAPE :ארץ הצעצועים + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :שטוח ביותר STR_TERRAIN_TYPE_FLAT :שטוח @@ -1110,6 +1090,7 @@ STR_TERRAIN_TYPE_MOUNTAINOUS :הררי STR_TERRAIN_TYPE_ALPINIST :מטפס הרים ###length 4 +STR_CITY_APPROVAL_LENIENT :רחמני STR_CITY_APPROVAL_TOLERANT :סביר STR_CITY_APPROVAL_HOSTILE :עויין STR_CITY_APPROVAL_PERMISSIVE :מתירני @@ -1121,6 +1102,7 @@ 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_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} @@ -1129,6 +1111,7 @@ 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_RESTRICT_CATEGORY :{BLACK}קטגוריה: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}סוג: @@ -1175,6 +1158,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :ימין STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :סכום הלוואה ראשוני: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :סכום מירבי שחברה יכולה ללוות (מבלי לקחת בחשבון אינפלציה) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :ריבית: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :ריבית עבור הלוואות; שולטת גם באינפלציה אם זו מאופשרות @@ -1191,8 +1175,10 @@ STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT :שלוט באי STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER :מכפיל עבור סובסידיה: {STRING} STR_CONFIG_SETTING_SUBSIDY_MULTIPLIER_HELPTEXT :קבע כמה משולם עבור חיבורים מסובסדים +STR_CONFIG_SETTING_SUBSIDY_DURATION :זמן סובסידיה: {STRING} ###setting-zero-is-special +STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED :אין סובידיות STR_CONFIG_SETTING_CONSTRUCTION_COSTS :עלויות בנייה: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :קבע את רמת העלויות של בנייה ורכישה @@ -1218,6 +1204,8 @@ 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 :הקל על הסרת מבנים ותשתיות בבעלות עיירות @@ -1339,6 +1327,7 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}שינו STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :תחזוקת תשתיות: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :כאשר מאופשר, תשתיות גורמות לעלויות תחזוקה. העלות גדלה באופן שהוא מעבר ליחסי לעומת גודל הרשת, וכך משפיע יותר על חברות גדולות מאשר על חברות קטנות +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :בחר צבע התחלתי לחברה STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :בטל התיישנות נמלי תעופה: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :אפשור הגדרה זו גורם לכל סוג נמל תעופה להישאר זמין לעד אחרי השקתו @@ -1409,7 +1398,9 @@ STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :מזקקות נ STR_CONFIG_SETTING_SNOWLINE_HEIGHT :גובה קו השלג: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :בחר מהו הגובה בו מתחיל השלג באקלים קר. שלג משפיע גם על הדרישות ביצירת תעשייה וגידול ערים +STR_CONFIG_SETTING_SNOW_COVERAGE :כיסוי שלג: {STRING} +STR_CONFIG_SETTING_DESERT_COVERAGE :כיסוי מדבר: {STRING} STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :רמת חספוס השטח: {STRING} STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT :(בורא הקרקע בלבד) בחר את תדירות הגבעות: למשטחים חלקים פחות גבעות שמפוזרות במרחב. למשטחים מחוספסים יש הרבה גבעות, שעלולות להיראות מחזוריות @@ -1435,6 +1426,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :משופר STR_CONFIG_SETTING_ROAD_SIDE :כלי רכב: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :בחר את צד הנסיעה +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :סע בצד שמאל +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :סע בצד ימין + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :סיבוב מפת גבהים: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :נגד כיוון השעון @@ -1462,6 +1457,7 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :ירוק כהה STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :סגול ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :ירוק לאדום (מקורי) STR_CONFIG_SETTING_SCROLLMODE :התנהגות גלילת תצוגה: {STRING} ###length 4 @@ -1564,6 +1560,7 @@ STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION_HELPTEXT :תן צבע ש STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS :{STRING}: שמור על כלי הבנייה פעילים לאחר השימוש STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :השאר את כלי הבנייה עבור גשרים, מנהרות וכו' פתוחים אחרי השימוש +STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :הסר רמזורים אוטומטית במהלך בניית פסי רכבת: {STRING} ###setting-zero-is-special @@ -1607,7 +1604,7 @@ STR_CONFIG_SETTING_AI_BUILDS_TRAINS :מנע הפעל STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :אפשור הגדרה זו הופך בניית רכבות לבלתי אפשרית עבור שחקן מחשב STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :{STRING} :מנע הפעלת אוטובוסים/משאיות ע”י שחקני המחשב -STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :אפשור הגדרה זו הופך בניית רכבי כביש לבלתי אפשרית עבור שחקן מחשב +STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :אפשור הגדרה זו הופך בניית כלי רכב לבלתי אפשרית עבור שחקן מחשב STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :{STRING} :מנע הפעלת כלי טייס ע”י שחקני המחשב STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :אפשור הגדרה זו הופך בניית מטוסים לבלתי אפשרית עבור שחקן מחשב @@ -1706,13 +1703,18 @@ 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 :ניקוד סוף שנה: {STRING} ###setting-zero-is-special +STR_CONFIG_SETTING_ENDING_YEAR_ZERO :לעולם לא +STR_CONFIG_SETTING_ECONOMY_TYPE :סוג כלכלה: {STRING} ###length 3 +STR_CONFIG_SETTING_ECONOMY_TYPE_ORIGINAL :מקורי STR_CONFIG_SETTING_ALLOW_SHARES :אפשר קניית מניות מחברות אחרות: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :כאשר מאופשר, מתיר קנייה ומכירה של מניות של חברות. מניות יהיו זמינות רק עבור חברות המגיעות לגיל מסוים +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :גיל מינימלי לחברה לסחור במניותיה: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :אחוז הרווח מקטע נסיעה לתשלום במערכות הזנה: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :אחוז הרווח הניתן לקטעי ביניים במערכות הזנה, דבר הנותן שליטה מוגברת על ההכנסות @@ -1733,6 +1735,7 @@ STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :רמזורי נ STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :הכל ###length 2 +STR_CONFIG_SETTING_SIGNAL_GUI_MODE_ALL_CYCLE_PATH :כל הרמזורים STR_CONFIG_SETTING_TOWN_LAYOUT :מתווה דרך לערים חדשות: {STRING} STR_CONFIG_SETTING_TOWN_LAYOUT_HELPTEXT :פריסה עבור רשת הכבישים של עיירות @@ -1759,10 +1762,13 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :מותר STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :מותר, מתווה עיר מותאם אישית ###length 2 +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :לינארי STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :מיקום עצים במהלך המשחק: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :שלוט בהופעה אקראית של עצים במהלך המשחק. זה עלול להשפיע על תעשיות המסתמכות על צמיחת עצים, לדוגמא מנסרות ###length 4 +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 :מיקום אופקי של סרגל הכלים הראשי בראש המסך @@ -1791,6 +1797,7 @@ 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_MIN_HELPTEXT :הגבל את הרזולוציה המקסימלית לשימוש עבור ספרייטים. הגבלת רזולוציית הספרייט תמנע משימוש בגרפיקה ברזולוציה גבוהה גם כאשר היא זמינה. זה יכול לעזור לשמור על מראה המשחק אחידה בעת שימוש בשילוב של קבצי GRF עם ובלי גרפיקה ברזולוציה גבוהה. ###length 3 STR_CONFIG_SETTING_TOWN_GROWTH :{STRING} : קצב ההתרחבות של העיירות @@ -1915,7 +1922,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :החלפת כי STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :אפשר לרכבות להחליף כיוון ברמזור, אם הן חיכו שם זמן ממושך ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(מומלץ) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(מומלץ) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}שנה ערך @@ -1940,6 +1947,7 @@ STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}הזיכ STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE} הקצאת {BYTES} בתים של מטמון נכשלה. המטמון הופחת ל-{BYTES} בתים. דבר זה יפחית את הביצועים של OpenTTD. כדי להפחית את דרישות הזיכרון ניתן לנסות לבטל את הגרפיקה ב-32bbp ו/או רמות ה-זום-אין # Video initalization errors +STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}... לא נמצא כרטיס מסך תואם, האצת חומרה מושבתת # Intro window STR_INTRO_CAPTION :{WHITE}OpenTTD {REV} @@ -1956,7 +1964,7 @@ STR_INTRO_HIGHSCORE :{BLACK}טבלת STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}הגדרות STR_INTRO_NEWGRF_SETTINGS :{BLACK}(NewGRF)הגדרות שדרוג גראפי STR_INTRO_ONLINE_CONTENT :{BLACK} בדוק תוכן מקוון -STR_INTRO_SCRIPT_SETTINGS :{BLACK}הגדרות סקריפטים של משחק/שחקני מחשב +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK} הגדרות סקריפטי משחק STR_INTRO_QUIT :{BLACK}יציאה STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}התחל משחק חדש. Ctrl+לחיצה מדלג על תצורת מפה @@ -1976,7 +1984,7 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}הצג STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}הצגת הגדרות STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}הצג הגדרות שדרוג גראפי STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK} חפש תוכן חדש/מעודכן להורדה -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK} הצג הגדרות סקריפטים של משחק/שחקני מחשב +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}הצג הגדרות בינה מלאכותית STR_INTRO_TOOLTIP_QUIT :{BLACK}צא מ-'OpenTTD' STR_INTRO_BASESET :{BLACK}חסרים {NUM} ספרייט עבור גרפיקות הבסיס שנבחרו. אנא בדוק עדכונים לערכה זו. @@ -2006,13 +2014,8 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}שנה STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}שנה את השנה הנוכחית STR_CHEAT_SETUP_PROD :{LTBLUE}אפשר שינוי ערכי התפוקה: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :אקלים ממוזג -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :אקלים קר -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :אקלים טרופי -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :ארץ הצעצועים - # Livery window +STR_LIVERY_CAPTION :{WHITE}{COMPANY} - ערכת צבעים STR_LIVERY_GENERAL_TOOLTIP :{BLACK}הצג הגדרות צבע כלליות STR_LIVERY_TRAIN_TOOLTIP :{BLACK}הצג הגדרות צבע לרכבות @@ -2108,6 +2111,7 @@ STR_FACE_TIE_EARRING_TOOLTIP :{BLACK} שנה # Matches ServerGameType ###length 3 +STR_NETWORK_SERVER_VISIBILITY_PUBLIC :פומבי # Network server list STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}משחק רשת @@ -2140,9 +2144,11 @@ STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}גרס STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}כתובת השרת: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_START_DATE :{SILVER}תאריך התחלה: {WHITE}{DATE_SHORT} STR_NETWORK_SERVER_LIST_CURRENT_DATE :{SILVER}תאריך נוכחי: {WHITE}{DATE_SHORT} +STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}סקריפט משחק: {WHITE}{STRING} (v{NUM}) STR_NETWORK_SERVER_LIST_PASSWORD :{SILVER}מוגן בסיסמה! STR_NETWORK_SERVER_LIST_SERVER_OFFLINE :{SILVER}שרת מנותק STR_NETWORK_SERVER_LIST_SERVER_FULL :{SILVER}שרת מלא +STR_NETWORK_SERVER_LIST_SERVER_TOO_OLD :{SILVER}השרת ישן מדי STR_NETWORK_SERVER_LIST_VERSION_MISMATCH :{SILVER}גרסה לא תואמת STR_NETWORK_SERVER_LIST_GRF_MISMATCH :{SILVER}אי התאמת קבצים גרפיים @@ -2165,6 +2171,7 @@ 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_VISIBILITY_LABEL :{BLACK}ראות STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} לקוח{P "" "ות"} STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}מספר מקסימלי של לקוחות: STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK} :מספר משתתפים מירבי @@ -2200,12 +2207,31 @@ STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}חברה STR_NETWORK_COMPANY_LIST_CLIENT_LIST :רשימת משתתפים # Network client list +STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}שם השרת שאתה משחק בו +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}האם אנשים אחרים יוכלו לראות את השרת שלך ברשימה הפומבית +STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}שחקן +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}פעולות ניהוליות לביצוע עבור לקוח זה +STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}שלח הודעה לשחקן הזה +STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}שלח הודעה לכל השחקנים של החברה הזאת +STR_NETWORK_CLIENT_LIST_SPECTATORS :צופים +STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(חברה חדשה) +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}זה מארח המשחק # Matches ConnectionType ###length 5 +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}משתתפים מרוחקים לא יכולים להתחבר +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_STUN :{BLACK}מאחורי NAT +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :חסום (באן) +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :שחרר סיסמה +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}האם אתה בטוח שברצונך להוציא את '{STRING}'? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}אתה בטוח שברצונך מחק את החברה '{COMPANY}'? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}אתה בטוח שברצונך לאפס את סיסמת החברה '{COMPANY}'? +STR_NETWORK_ASK_RELAY_CAPTION :{WHITE}השתמש ב"relay"? +STR_NETWORK_ASK_RELAY_NO :{BLACK}לא +STR_NETWORK_ASK_RELAY_YES_ONCE :{BLACK}כן, זה STR_NETWORK_SPECTATORS :צופים @@ -2245,6 +2271,8 @@ STR_NETWORK_ERROR_LOSTCONNECTION :{WHITE}הקשר STR_NETWORK_ERROR_SAVEGAMEERROR :{WHITE}טעינת משחק מקובץ נכשלה STR_NETWORK_ERROR_SERVER_START :{WHITE}הפעלת השרת נכשלה STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}שגיאת התקשרות +STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}שם השחקן שלך לא מוגדר, השם יכול להיות מוגדר בראש חלון "Multiplayer" +STR_NETWORK_ERROR_BAD_SERVER_NAME :{WHITE}שם השרת שלך לא הוגדר, אפשר להגדיר את שם השרת בחלק העליון של מסך ה"Multiplatyer" STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}אי התאמה לגרסת השרת STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}ססמה שגוייה STR_NETWORK_ERROR_SERVER_FULL :{WHITE}השרת מלא @@ -2291,11 +2319,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_1 :המשחק עד STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_2 :המשחק עדיין מופסק ({STRING}, {STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_3 :המשחק עדיין מופסק ({STRING}, {STRING}, {STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_4 :משחק עדיין מושהה ({STRING}, {STRING}, {STRING}, {STRING}) +STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_5 :המשחק עדיין מושהה ({STRING}, {STRING}, {STRING}, {STRING}, {STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_UNPAUSED :המשחק הומשך ({STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS :מספר שחקנים STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS :מתחבר ללקוחות STR_NETWORK_SERVER_MESSAGE_GAME_REASON_MANUAL :ידני STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT :סקריפט משחק +STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :מחכה לעדכון גרף קישור STR_NETWORK_MESSAGE_CLIENT_LEAVING :עוזב STR_NETWORK_MESSAGE_CLIENT_JOINED :הצטרף למשחק {STRING} *** @@ -2308,6 +2338,9 @@ STR_NETWORK_MESSAGE_NAME_CHANGE :{STRING} שינ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}השרת סגר את המשחק STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}השרת מופעל מחדש...{}אנא המתן... +STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}הרשמת שרת נכשלה +STR_NETWORK_ERROR_COORDINATOR_REUSE_OF_INVITE_CODE :{WHITE} שרת חדש עם אותו קוד-הזמנה כבר רשם את עצמו, מעביר למצב משחק "מקומי" +STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}השרת שלך לא מאפשר חיבורים מרוחקים # Content downloading window STR_CONTENT_TITLE :{WHITE}הורדת תוכן @@ -2384,6 +2417,7 @@ STR_MISSING_GRAPHICS_SET_MESSAGE :{BLACK}OpenTTD STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}כן, הורד את הגרפיקה STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}לא, צא מ-OpenTTD +STR_MISSING_GRAPHICS_ERROR :{BLACK}הורדת הגרפיקה נכשלה.{}אנא הורד את הגרפיקה ידנית. # Transparency settings window STR_TRANSPARENCY_CAPTION :{WHITE}הגדרות שקיפות @@ -2409,6 +2443,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}רווי STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}העמסת יתר +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}הדגשת שטח הכיסוי STR_STATION_BUILD_COVERAGE_OFF :{BLACK}מופסק @@ -2426,6 +2462,7 @@ 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 :בניית מסילות @@ -2476,6 +2513,7 @@ STR_STATION_CLASS_WAYP :נקודות ד # Signal window STR_BUILD_SIGNAL_CAPTION :{WHITE}בחירת רמזורים +STR_BUILD_SIGNAL_TOGGLE_ADVANCED_SIGNAL_TOOLTIP :{BLACK} החלף הצגת רמזורים מתקדמים STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}רמזור בלוק (מכאניים){}זהו הרמזורי הפשוט ביותר, מאפשר לרכבת אחת בלבד להמצא בבלוק מסויים בזמן נתון STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}רמזור כניסה (סמפור){}ירוקים כל עוד יש לפחות רמזור יציאה ירוק מקטע המסילה העוקב. אחרת מראה אדום STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}רמזור יציאה (סמפור){} מתנהג בדומה לרמזור הבלוק, אבל נחוץ להצגת הצבע הנכון ברמזורי כניסה ורמזורים משולבים @@ -2497,8 +2535,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}הגדל STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}בחר סוג הגשר עליו תעבור המסילה STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}בחירת גשר לכביש STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK} בחירת סוג הגשר – בחר את הסוג שברצונך לבנות -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :גשר תלוי, ברזל STR_BRIDGE_NAME_GIRDER_STEEL :גשר קורות, ברזל STR_BRIDGE_NAME_CANTILEVER_STEEL :גשר זיז, פלדה @@ -2530,6 +2566,8 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}בנה STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}שנה מצב בנה/הסר כבישים STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}שנה מצב בנה\מחק למבני חשמלית +STR_ROAD_NAME_ROAD :דרך +STR_ROAD_NAME_TRAM :רכבת קלה # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}כיוון המוסך @@ -2617,6 +2655,7 @@ 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_FOREST_LG_BUTTON :{BLACK}יער # Land generation window (SE) STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION :{WHITE}יצירת טופוגרפיה @@ -2669,10 +2708,12 @@ 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_INDUSTRY_BUILD_COST :{YELLOW}{CURRENCY_LONG}{BLACK} :מחיר STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY :{BLACK}צפה STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY :{BLACK}בנה STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY :{BLACK}ממן +STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_TOOLTIP :{BLACK}הסר את כל התעשיות שכרגע על המפה # Industry cargoes window STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION :{WHITE}שרשרת תעשיות עבור תעשיה {STRING} @@ -2714,8 +2755,10 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}{LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK} :מקבל {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({1:STRING} {0:COMMA}/8 ) STR_LANG_AREA_INFORMATION_RAIL_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 :סלעים @@ -2819,6 +2862,7 @@ STR_FRAMERATE_CAPTION :{WHITE}קצב STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) STR_FRAMERATE_RATE_GAMELOOP :{WHITE}קצב סימולציה: {STRING} STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}מספר פעימות משחק לשניה +STR_FRAMERATE_RATE_BLITTER :{BLACK}קצב רענון: {STRING} STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}מספר פריימים של וידאו המעובדים בשניה STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK} כמה מהר המשחק כרגע רץ, בהשוואה למהירות הצפוייה בקצב סימולציה רגיל. STR_FRAMERATE_CURRENT :נוכחי{WHITE} @@ -2838,16 +2882,20 @@ STR_FRAMERATE_DRAWING :{WHITE}עיבו STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} תצוגות עולם: STR_FRAMERATE_VIDEO :{BLACK}פלט וידאו: STR_FRAMERATE_SOUND :{WHITE} ערבוב צליל: +STR_FRAMERATE_GAMESCRIPT :{BLACK} סקריפט משחק: ###length 15 STR_FRAMETIME_CAPTION_GAMELOOP :לולאת משחק STR_FRAMETIME_CAPTION_GL_ECONOMY :טיפול במטען STR_FRAMETIME_CAPTION_GL_TRAINS :פעימות רכבת +STR_FRAMETIME_CAPTION_GL_ROADVEHS :פעימות כלי רכב 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_ALLSCRIPTS :סה"כ סקריפטי משחק ובינה מלאכותית +STR_FRAMETIME_CAPTION_AI :בינה מלאכותית {NUM} {STRING} # Save/load game/scenario @@ -2873,6 +2921,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_FILTER_TITLE :{BLACK}מחרוזת סינון: +STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}החלף קובץ STR_SAVELOAD_OSKTITLE :{BLACK}הכנס שם לשמירה @@ -2882,16 +2931,42 @@ STR_MAPGEN_MAPSIZE :{BLACK}:גוד STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}בחר את גודל המפה במשבצות. מספר המשבצות הזמינות תהיה קצת קטנה יותר. STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK} :מספר העיירות +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}שמות הערים +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}בחר סגנון של שמות הערים STR_MAPGEN_DATE :{BLACK} :תאריך STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK} :מספר התעשיות -STR_MAPGEN_LAND_GENERATOR :{BLACK} :מחולל פני שטח +STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}הפסגה הגבוהה ביותר: +STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN :{BLACK}הקטן את הגובה המרבי של הפסגה הגבוהה ביותר במפה באחד STR_MAPGEN_TERRAIN_TYPE :{BLACK} :סוג הקרקע -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK} :כמות ימים/אגמים +STR_MAPGEN_SEA_LEVEL :{BLACK} :כמות ימים/אגמים STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}נהרות: STR_MAPGEN_SMOOTHNESS :{BLACK} :חלקלקות STR_MAPGEN_VARIETY :{BLACK}הפצה מגוונת: STR_MAPGEN_GENERATE :{WHITE}יצירת קרקע +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :אנגלית +STR_MAPGEN_TOWN_NAME_FRENCH :צרפתית +STR_MAPGEN_TOWN_NAME_GERMAN :גרמנית +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :אנגלית +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :אמריקאי-לטיני +STR_MAPGEN_TOWN_NAME_SILLY :מצחיק +STR_MAPGEN_TOWN_NAME_SWEDISH :שוודית +STR_MAPGEN_TOWN_NAME_DUTCH :הולנדית +STR_MAPGEN_TOWN_NAME_FINNISH :פינית +STR_MAPGEN_TOWN_NAME_POLISH :פולנית +STR_MAPGEN_TOWN_NAME_SLOVAK :סלובקית +STR_MAPGEN_TOWN_NAME_NORWEGIAN :נורבגית +STR_MAPGEN_TOWN_NAME_HUNGARIAN :הונגרית +STR_MAPGEN_TOWN_NAME_AUSTRIAN :אוסטרית +STR_MAPGEN_TOWN_NAME_ROMANIAN :רומנית +STR_MAPGEN_TOWN_NAME_CZECH :צ'כית +STR_MAPGEN_TOWN_NAME_SWISS :שווצרית +STR_MAPGEN_TOWN_NAME_DANISH :דנית +STR_MAPGEN_TOWN_NAME_TURKISH :טורקית +STR_MAPGEN_TOWN_NAME_ITALIAN :איטלקית +STR_MAPGEN_TOWN_NAME_CATALAN :רומאית + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK} :שולי המפה STR_MAPGEN_NORTHWEST :{BLACK}צפון-מערב @@ -2909,6 +2984,7 @@ STR_MAPGEN_HEIGHTMAP_NAME :{BLACK} :שם STR_MAPGEN_HEIGHTMAP_SIZE_LABEL :{BLACK}גודל: STR_MAPGEN_HEIGHTMAP_SIZE :{ORANGE}{NUM} על {NUM} +STR_MAPGEN_SNOW_COVERAGE_QUERY_CAPT :{WHITE} כיסוי שלג באחוזים STR_MAPGEN_START_DATE_QUERY_CAPT :{WHITE}שנה את שנת הפתיחה # SE Map generation @@ -2980,6 +3056,7 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}גרסא STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}גירסה מינימלת תואמת: {SILVER}{NUM} STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE :{SILVER}{STRING}{BLACK}: פלטת צבעים +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :ברירת מחדל (D) STR_NEWGRF_SETTINGS_PARAMETER :{SILVER}{STRING}{BLACK} :פרמטריֿם STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}לא קיים מידע @@ -3027,6 +3104,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}הספר STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}עבור לספרייט הקודם, כאשר נדלג על כל הספרייטים המיוחדים ונחזור מתחילת הרשימה לסופה STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}הייצוג של הספרייט הנבחר. בעת ציור הספרייט, נתעלם מהיישור שלו STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}הזז את הספרייט, תוך שינוי ההיסט של צירי ה-X וה-Y. לחץ עם ctrl כדי להזיז את הספרייט שמונה יחידות בבת אחת + +###length 2 + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}איפוס יחסית STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}איפוס ההיסטים היחסיים הנוכחיים STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}היסט X: {NUM}, היסט Y: {NUM} (מוחלט) @@ -3041,7 +3122,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}אזהרה: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{SILVER}{STRING}{RED}: שגיאה STR_NEWGRF_ERROR_MSG_FATAL :{SILVER}{STRING}{RED} :שגיאה חמורה -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}התרחשה שגיאה קריטית ב-NewGRF:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} לא יעבוד עם גרסת ה-TTDPatch שדווחה ע"י OpenTTD. STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} היא עבור גרסת {STRING} של TTD. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} נועד להיות בשימוש יחד עם {STRING} @@ -3188,6 +3268,7 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}שחד # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} מטרות STR_GOALS_SPECTATOR_CAPTION :{WHITE}מטרות גלובליות +STR_GOALS_SPECTATOR :מטרות גלובליות STR_GOALS_TEXT :{ORANGE}{STRING} STR_GOALS_NONE :{ORANGE}- אין - STR_GOALS_PROGRESS :{ORANGE}{STRING} @@ -3330,6 +3411,8 @@ STR_FINANCES_CAPTION :{WHITE}{COMPANY STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}הכנסה +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}הוצאות תפעול ###length 13 @@ -3339,6 +3422,8 @@ STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}עלות STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}עלות תפעול רכבים STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD} עלות הפעלת כלי טייס STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD} עלות הפעלת כלי שייט +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}כלי טייס +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}כלי שייט STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}ריבית על ההלוואה STR_FINANCES_SECTION_OTHER :{GOLD}אחר @@ -3348,6 +3433,7 @@ STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}חשבו STR_FINANCES_LOAN_TITLE :{WHITE}הלוואה STR_FINANCES_MAX_LOAN :{BLACK}{CURRENCY_LONG}{WHITE}: הלוואה מירבית STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}לווה {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}הגדל את ההלוואה. Ctrl+לחיצה מלווה ככל שניתן STR_FINANCES_REPAY_BUTTON :{BLACK}החזר {CURRENCY_LONG} @@ -3384,6 +3470,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_NEW_FACE_BUTTON :{BLACK}פנים חדשות STR_COMPANY_VIEW_NEW_FACE_TOOLTIP :{BLACK}בחר פנים חדשות למנהל @@ -3420,7 +3507,14 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}תעשיות STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- אין - 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_PRODUCED_CARGO_FILTER :{BLACK}מטען שיוצר: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :כל סוגי המטען +STR_INDUSTRY_DIRECTORY_FILTER_NONE :אין # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} @@ -3430,6 +3524,8 @@ 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} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}דורש: STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} @@ -3462,6 +3558,7 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}שלח STR_VEHICLE_LIST_REPLACE_VEHICLES :החלף כלי רכב STR_VEHICLE_LIST_SEND_FOR_SERVICING :שלח לטיפול STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}{1:CURRENCY_LONG} :בשנה שעברה{NBSP} {0:CURRENCY_LONG}) :רווח השנה +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :שלח רכבת למוסך STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :שלח כלי רכב למוסך @@ -3492,6 +3589,7 @@ STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}קבוצ STR_GROUP_CREATE_TOOLTIP :{BLACK}לחץ ליצירת קבוצה חדשה STR_GROUP_DELETE_TOOLTIP :{BLACK}מחק את הקבוצה שנבחרה STR_GROUP_RENAME_TOOLTIP :{BLACK}שנה את שם הקבוצה +STR_GROUP_LIVERY_TOOLTIP :{BLACK}שינוי צבע הקבוצה שנבחרה STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}לחץ על מנת להגן על הכלים בקבוצה בפני החלפה אוטומטית STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}מחק קבוצה @@ -3519,6 +3617,7 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :כלי רכב # Vehicle availability ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :רכבות זמינות +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :כלי רכב חדשים STR_BUY_VEHICLE_SHIP_CAPTION :כלי שייט חדשים STR_BUY_VEHICLE_AIRCRAFT_CAPTION :כלי טייס חדש @@ -3544,6 +3643,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}כוח STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}טווח: {GOLD}{COMMA} משבצות STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}סוג כלי טיס: {GOLD}{STRING} +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK} בחירת קרונות - לחץ על קרון לקבלת מידע STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}רשימת כלי הרכב - בחר כלי רכב למידע @@ -3557,6 +3658,8 @@ STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}רכוש STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}רכוש כלי טייס ###length VEHICLE_TYPES +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}קנה והתאם כלי שייט +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}קנה והתאם כלי טייס ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}רכוש את קרון הרכבת שמודגש. Shift+לחיצה מציג הערכת עלות ללא רכישה @@ -3565,6 +3668,7 @@ STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}רכוש STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}רכוש את כלי הטייס שמודגש. Shift+לחיצה מציג הערכת עלות ללא רכישה ###length VEHICLE_TYPES +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}לרכוש ולאבזר את הרכבת הנבחרת. לחיצה+מקש Shift תציג עלות משוערת מבלי לבצע רכישה בפועל ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}שנה שם @@ -3693,6 +3797,7 @@ STR_ENGINE_PREVIEW_CAPTION :{WHITE}הודע 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 :קטר פס מגנטי @@ -3740,6 +3845,7 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}החלף STR_REPLACE_ENGINES :מנועים/קטרים STR_REPLACE_WAGONS :קרונות STR_REPLACE_ALL_RAILTYPE :כלל הרכבות +STR_REPLACE_ALL_ROADTYPE :כל הכלי רכב ###length 2 STR_REPLACE_HELP_RAILTYPE :{BLACK}בחר את סוג המסילה עבורה ברצונך להחליף קטרים @@ -3751,6 +3857,8 @@ STR_REPLACE_ELRAIL_VEHICLES :רכבות חש STR_REPLACE_MONORAIL_VEHICLES :רכבות חד-פס STR_REPLACE_MAGLEV_VEHICLES :רכבות פס-מגנטי +STR_REPLACE_ROAD_VEHICLES :רכבי כביש +STR_REPLACE_TRAM_VEHICLES :רכבות קלות STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}שמור על האורך המקורי של הרכבת בעת שימוש בהחלפה אוטומטית, במידה והקטר מאריך את הרכבת הסר קרונות מתחילת הרכבת @@ -3758,6 +3866,7 @@ STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}שמור STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} ###length VEHICLE_TYPES +STR_VEHICLE_VIEW_AIRCRAFT_CENTER_TOOLTIP :{BLACK}מרכז תצוגה ראשית על מיקום הכלי טייס. לחיצה כפולה תעקוב אחר הכלי טייס בתצוגה הראשית. Ctrl+Click פותחת נקודת מבט חדשה במיקום הכלי טייס ###length VEHICLE_TYPES STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}.שלח את הרכבת למוסך @@ -3774,6 +3883,7 @@ STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}פעול STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}הכרח את הרכבת להמשיך מבלי להמתין לרמזור STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}שנה את כיוון הנסיעה של הרכבת STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}הכרח את כלי הרכב להסתובב +STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP :{BLACK}מרכז תצוגה ראשית ביעד ההזמנה. Ctrl+Click פותח נקודת מבט חדשה במיקום יעד ההזמנה ###length VEHICLE_TYPES STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}התאם את הרכבת לנשיאת משא שונה @@ -3794,6 +3904,8 @@ STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}הצג STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}הצג פרטי כלי טייס ###length VEHICLE_TYPES +STR_VEHICLE_VIEW_ROAD_VEHICLE_STATUS_START_STOP_TOOLTIP :{BLACK}פעולת כלי רכב- לחץ כדי לעצור או להפעיל את כלי הרכב +STR_VEHICLE_VIEW_SHIP_STATE_STATUS_STOP_TOOLTIP :{BLACK}פעולת כלי שייט - לחץ כדי לעצור או להפעיל את כלי השייט # Messages in the start stop button in the vehicle view STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}טעינה / פריקה @@ -3812,6 +3924,7 @@ STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL :{LTBLUE} {1:VEL STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL :{ORANGE}בדרך אל {DEPOT}, {VELOCITY} STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL :{LTBLUE}קבלת שירות ב{DEPOT}, {VELOCITY} +STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_SERVICE_VEL :{LTBLUE}לא יכול להגיע ל {DEPOT}, {VELOCITY} # Vehicle stopped/started animations ###length 2 @@ -4174,12 +4287,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}אחד STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}חלון הדה-באג זמין רק עבור השרת # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}הגדרות משחק/בינה מלאכותית +STR_AI_CONFIG_CAPTION_AI :{WHITE} הגדרת בינה מלאכותית +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}הגדרות סקריפטי משחק STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}סקריפט המשחק אשר יטען במשחק הבא STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}שחקני המחשב אשר יטענו במשחק הבא STR_AI_CONFIG_HUMAN_PLAYER :שחקן אנושי STR_AI_CONFIG_RANDOM_AI :בינה מלאכותית אקראית STR_AI_CONFIG_NONE :(ללא) +STR_AI_CONFIG_MAX_COMPETITORS :{ORANGE}{COMMA}{LTBLUE} : מספר מתחרים מירבי STR_AI_CONFIG_MOVE_UP :{BLACK}הזז מעלה STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}הזז את ה-AI הנבחר מעלה ברשימה @@ -4189,8 +4304,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}הזז STR_AI_CONFIG_GAMESCRIPT :{SILVER}סקריפט משחק STR_AI_CONFIG_AI :{SILVER}שחקני מחשב -STR_AI_CONFIG_CHANGE :{BLACK}בחר {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :שחקן מחשב STR_AI_CONFIG_CHANGE_GAMESCRIPT :סקריפט משחק STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}טען סקריפט נוסף @@ -4212,11 +4325,13 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK} בחר STR_AI_LIST_CANCEL :{BLACK}בטל STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}אל תשנה את התסריט +STR_SCREENSHOT_CAPTION :{WHITE}צלם מסך +STR_SCREENSHOT_SCREENSHOT :תמונת מסך רגילה +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}זום ברירת מחדל לצילום מסך +STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}צילום מסך של כל המפה -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} פרמטרים +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :שחקן מחשב -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :סקריפט משחק STR_AI_SETTINGS_CLOSE :{BLACK}סגור STR_AI_SETTINGS_RESET :{BLACK}אתחל STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4352,6 +4467,7 @@ STR_ERROR_LOAN_ALREADY_REPAYED :{WHITE}... אי STR_ERROR_CURRENCY_REQUIRED :{WHITE}... דרושים {CURRENCY_LONG} STR_ERROR_CAN_T_REPAY_LOAN :{WHITE}לא ניתן להחזיר את ההלוואה... STR_ERROR_INSUFFICIENT_FUNDS :{WHITE}לא ניתן למסור כסף שנלווה מהבנק... +STR_ERROR_CAN_T_GIVE_MONEY :{WHITE}לא ניתן לתת כסף לחברה הזאת... STR_ERROR_CAN_T_BUY_COMPANY :{WHITE}לא ניתן לקנות את החברה... STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}לא ניתן לבנות את מטה החברה באתר זה... STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}אין באפשרותך לקנות 25% ממניות חברה זו... @@ -4377,6 +4493,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... יו STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}לא ניתן ליצור תעשיות... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}לא ניתן לבנות {STRING} כאן... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}לא ניתן לבנות כאן תעשיה מסוג זה... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}לא יכול להקים תעשייה... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... קרוב מידי לתעשיה אחרת STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... יש להקים עיר קודם STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... ניתן רק אחד בכל עיר @@ -4391,6 +4508,7 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... יע STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... ניתן/ת לבנייה רק מעל לקו השלג STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... ניתן/ת לבנייה רק מתחת לקו השלג +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}לא היו מקומות מתאימים בשביל התעשייה הזאת STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}אין מיקומים מתאימים לתעשיות '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}שנה את פרמטרי יצירת המפה לקבלת מפה טובה יותר @@ -4478,6 +4596,7 @@ STR_ERROR_DEPOT_WRONG_DEPOT_TYPE :סוג מוסך STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}ארוכה מידי לאחר ביצוע ההחלפה {VEHICLE} STR_ERROR_AUTOREPLACE_NOTHING_TO_DO :{WHITE}לא יושמו כללים להחלפה/חידוש אוטומטיים STR_ERROR_AUTOREPLACE_MONEY_LIMIT :(הגבלת כסף) +STR_ERROR_AUTOREPLACE_INCOMPATIBLE_CARGO :{WHITE}רכב חדש לא יכול לנשוא{STRING} # Rail construction errors STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}שילוב מסילות בלתי אפשרי @@ -4505,6 +4624,8 @@ 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_TRAMWAY :{WHITE}לא יכול לשנות סוג רכבת קלה כאן... +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}אין רכבת קלה מתאימה # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}לא ניתן לבנות כאן תעלה... @@ -4551,6 +4672,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}עצם STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... מטה חברה חוסם את הדרך STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}לא ניתן לקנות שטח זה... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... שטח זה כבר בבעלותך! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... הגעת למגבלת בניית האובייקטים # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}לא ניתן ליצור קבוצה... @@ -4622,6 +4744,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}לא נ STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... הרכב נהרס + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}כלי תחבורה לא יהיו זמינים STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}שנה הגדרות NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}כלי תחבורה עדיין לא זמינים @@ -4655,6 +4778,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}לא נ STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... רחוק מידי מהיעד הקודם STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... למטוס אין טווח גדול מספיק +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}לא ניתן ליצור לוח זמנים עבור רכב זה... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}כלי רכב יכולים להמתין בתחנות בלבד @@ -5079,6 +5204,7 @@ STR_FORMAT_DATE_ISO :{2:NUM}-{1:STRI STR_FORMAT_COMPANY_NUM :({COMMA} חברה) STR_FORMAT_GROUP_NAME :{COMMA} קבוצה +STR_FORMAT_GROUP_VEHICLE_NAME :{GROUP} #{COMMA} STR_FORMAT_INDUSTRY_NAME :{1:STRING.gen} {0:TOWN} ###length 2 diff --git a/src/lang/hindi.txt b/src/lang/hindi.txt index 42670e9c80e1a..79ab1757cfb80 100644 --- a/src/lang/hindi.txt +++ b/src/lang/hindi.txt @@ -50,6 +50,7 @@ STR_CARGO_SINGULAR_TOFFEE :टॉफी # Quantity of cargo STR_QUANTITY_NOTHING : STR_QUANTITY_VALUABLES :{COMMA}{NBSP}मूल्यवान वस्तुओं {P "का थैला" "के थैले"} +STR_QUANTITY_TOFFEE :{WEIGHT_LONG} टॉफी # Two letter abbreviation of cargo name STR_ABBREV_NOTHING : @@ -71,6 +72,7 @@ STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp + # Common window strings @@ -114,9 +116,10 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :निकास # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :समायोजन STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED :पथ-संकेतों के नाम दिखायें +STR_SETTINGS_MENU_TRANSPARENT_SIGNS :पारदर्शी संकेत # File menu ###length 5 @@ -196,6 +199,7 @@ STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLA # Company league window STR_COMPANY_LEAGUE_COMPANY_NAME :{ORANGE}{COMPANY} {BLACK}{COMPANY_NUM} '{STRING}' +STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_PRESIDENT :राष्ट्रपति # Performance detail window @@ -216,9 +220,11 @@ STR_HIGHSCORE_PRESIDENT_OF_COMPANY_ACHIEVES_STATUS :{BIG_FONT}{WHIT # Smallmap window ###length 7 +STR_SMALLMAP_TYPE_VEGETATION :वनस्पति STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}ट्रक लदान वीथी +STR_SMALLMAP_LEGENDA_ROUGH_LAND :{TINY_FONT}{BLACK}खुरदरा भूमि STR_SMALLMAP_LEGENDA_BARE_LAND :{TINY_FONT}{BLACK}रिक्त भूमि STR_SMALLMAP_LEGENDA_TOWNS :{TINY_FONT}{BLACK}नगर @@ -269,16 +275,6 @@ STR_GAME_OPTIONS_CURRENCY_FIM :फिनलै STR_GAME_OPTIONS_CURRENCY_ISK :आइसलैंडिक क्रोना (ISK) STR_GAME_OPTIONS_CURRENCY_HKD :हाँग काँग डॉलर (एचकेडी) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :दाईं ओर वाहन चलाएँ - - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :फ़्रेंच -STR_GAME_OPTIONS_TOWN_NAME_POLISH :पोलिश -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :तुर्की -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :इटैलियन - # Autosave dropdown ###length 5 @@ -292,8 +288,6 @@ STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM} -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :सामान्य - @@ -311,7 +305,6 @@ STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}एक - STR_VARIETY_MEDIUM :मध्यम ###length 5 @@ -325,6 +318,8 @@ STR_AI_SPEED_SLOW :धीमा ###length 4 +###length 4 + ###length 7 ###length 4 @@ -345,6 +340,7 @@ STR_CONFIG_SETTING_COMPANIES_OFF :बन्द ###length 3 +###setting-zero-is-special @@ -443,6 +439,9 @@ STR_CONFIG_SETTING_ORDER_REVIEW_OFF :नहीं ###length 3 +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :दाईं ओर वाहन चलाएँ + ###length 2 ###length 2 @@ -465,6 +464,7 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :बैंगन ###length 3 +STR_CONFIG_SETTING_SCROLLWHEEL_SCROLL :स्क्रॉल नक्शा ###length 4 STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :अक्षम @@ -505,6 +505,7 @@ STR_CONFIG_SETTING_SOUND_NEWS :समाचा +STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :एक कंपनी के पास जहाजों की अधिकतम संख्या @@ -564,6 +565,7 @@ STR_CONFIG_SETTING_TOWN_CARGOGENMODE :नगर म ###length 4 +STR_CONFIG_SETTING_TOOLBAR_POS :मुख्य टूलबार की स्थिति: {STRING} ###setting-zero-is-special STR_CONFIG_SETTING_SOFT_LIMIT_VALUE :{COMMA} ###setting-zero-is-special @@ -628,10 +630,9 @@ STR_ABANDON_SCENARIO_QUERY :{YELLOW}क् # Cheat window -###length 4 - # Livery window +STR_LIVERY_TRAIN_TOOLTIP :{BLACK} ट्रेन रंग योजनाएं दिखाएं ###length 23 @@ -706,6 +707,7 @@ STR_CONTENT_DETAIL_SUBTITLE_DOES_NOT_EXIST :{SILVER}यह # Order of these is important! +STR_CONTENT_TYPE_GS_LIBRARY :जीएस लाइब्रेरी # Content downloading progress window STR_CONTENT_DOWNLOAD_COMPLETE :{WHITE}डाउनलोड पूरा हुआ @@ -721,6 +723,8 @@ STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD :{WHITE}डा # Linkgraph legend window and linkgraph legend in smallmap +# Linkgraph tooltip + # Base for station construction window(s) # Join station window @@ -836,6 +840,12 @@ STR_FRAMETIME_CAPTION_GL_ECONOMY :माल प # World generation +###length 21 +STR_MAPGEN_TOWN_NAME_FRENCH :फ़्रेंच +STR_MAPGEN_TOWN_NAME_POLISH :पोलिश +STR_MAPGEN_TOWN_NAME_TURKISH :तुर्की +STR_MAPGEN_TOWN_NAME_ITALIAN :इटैलियन + # Strings for map borders at game generation STR_MAPGEN_BORDER_WATER :{BLACK}जल STR_MAPGEN_BORDER_RANDOM :{BLACK}यादृच्छिक @@ -866,6 +876,10 @@ STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :मूल (D) # Sprite aligner window +###length 2 + + + # NewGRF (self) generated warnings/errors STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING} @@ -1024,6 +1038,8 @@ STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :नई ट् STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}मूल्य : {GOLD}{CURRENCY_LONG}{BLACK} भार : {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}भार : {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) +###length 3 + ###length VEHICLE_TYPES ###length VEHICLE_TYPES @@ -1059,6 +1075,7 @@ STR_DEPOT_VEHICLE_TOOLTIP :{BLACK}{ENGINE} ###length VEHICLE_TYPES ###length VEHICLE_TYPES +STR_DEPOT_SELL_ALL_BUTTON_ROAD_VEHICLE_TOOLTIP :{BLACK}डिपो में सभी सड़क वाहन बेचते हैं ###length VEHICLE_TYPES @@ -1187,6 +1204,7 @@ STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :के बर STR_ORDER_NEAREST_DEPOT :निकटतम ###length 3 +STR_ORDER_TRAIN_DEPOT :ट्रेन डिपो ###next-name-looks-similar STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT :{STRING} {STRING} {STRING} @@ -1194,8 +1212,10 @@ STR_ORDER_GO_TO_DEPOT_FORMAT :{STRING} {DEPOT STR_ORDER_GO_TO_STATION :{STRING} {STATION} {STRING} +STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(स्टेशन का उपयोग नहीं कर सकते){POP_COLOUR} {STRING} {STATION} {STRING} +STR_ORDER_NO_LOAD :(कोई लोडिंग नहीं) @@ -1233,14 +1253,13 @@ STR_AI_DEBUG_NAME_AND_VERSION :{BLACK}{STRING} -STR_AI_CONFIG_CHANGE_NONE : # Available AIs window -# AI Parameters +# Script Parameters # Textfile window @@ -1305,6 +1324,7 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}अत +STR_ERROR_UNABLE_TO_FIND_ROUTE_TO :{WHITE} स्थानीय डिपो के लिए मार्ग खोजने में असमर्थ # Autoreplace related errors @@ -1315,6 +1335,7 @@ STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}पट # Road construction errors +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE} ट्राम प्रकार को यहाँ परिवर्तित नहीं कर सकते ... # Waterway construction errors STR_ERROR_MUST_BE_BUILT_ON_WATER :{WHITE}... पानी पर बनाया जाना चाहिये। @@ -1354,6 +1375,7 @@ STR_ERROR_CAN_T_SELL_TRAIN :{WHITE}रे + # Specific vehicle errors @@ -1362,6 +1384,8 @@ STR_ERROR_CAN_T_SELL_TRAIN :{WHITE}रे STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... वाहन सभी स्टेशनों तक नहीं जा सकता +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors # Sign related errors @@ -1406,6 +1430,7 @@ STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COAL_CAR :कोयला STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FRUIT_TRUCK :फल वाहन STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_X2001_ELECTRIC :'X2001' (विद्युतीय) STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOY_VAN :खिलौनों का डब्बा +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FIZZY_DRINK_TRUCK :फ़िज़ी ड्रिंक ट्रक STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_WATER_TANKER :पानी का टैंकर STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_BUBBLE_VAN :बबल वैन @@ -1414,6 +1439,7 @@ STR_VEHICLE_NAME_ROAD_VEHICLE_PLODDYPHUT_MKIII_BUS :प्लॉड STR_VEHICLE_NAME_ROAD_VEHICLE_MORELAND_WOOD_TRUCK :मोरलैंड काष्ठ ट्रक STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_ARMORED_TRUCK :फोस्टर कवचयुक्त ट्रक STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_CANDY_TRUCK :पावरनोट मिष्ठान्न ट्रक +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_BUBBLE_TRUCK :Wizzowow बबल ट्रक ###length 11 diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index f68899b9331d9..69ada0a6e12db 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -263,6 +263,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}LE STR_UNITS_POWER_METRIC :{COMMA}{NBSP}LE STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}LE/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}LE/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}LE/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}LE/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}LE/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}LE/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -289,7 +299,7 @@ STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Szűrő kifejezés: -STR_LIST_FILTER_OSKTITLE :{BLACK}Kulcsszó megadása a szűréshez +STR_LIST_FILTER_OSKTITLE :{BLACK}Egy vagy több kulcsszó megadása a szűréshez STR_LIST_FILTER_TOOLTIP :{BLACK}Írj ide egy kulcsszót ami alapján szűrni szeretnéd a listát STR_TOOLTIP_GROUP_ORDER :{BLACK}Csoportosítási szempont kiválasztása @@ -441,7 +451,7 @@ STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Út ép STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Villamospálya építése STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Faültetés. Shift lenyomásával megmutatja a becsült építési költséget STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Felirat lerakása -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Objektum elhelyezése. Shift lenyomásával megmutatja a várható költséget +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Objektum építése. Ctrl lenyomásával átlós terület jelölhető ki. Shift lenyomásával megmutatja a becsült építési költséget. # Scenario editor file menu ###length 7 @@ -454,10 +464,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Kilépés # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Alapbeállítások STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Beállítások -STR_SETTINGS_MENU_SCRIPT_SETTINGS :MI / Játékszkript beállítások +STR_SETTINGS_MENU_AI_SETTINGS :MI Beállítások +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Játékszkript beállítások STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF beállítások STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Átlátszósági beállítások STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Városnevek mutatása @@ -1029,36 +1040,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indiai Rúpia ( STR_GAME_OPTIONS_CURRENCY_IDR :Indonéz rúpia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Maláj ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Balra hajtás -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Jobbra hajtás - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Városnevek: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}A városnevek stílusának kiválasztása - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Angol (Eredeti) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francia -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Német -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Angol (További) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latin-amerikai -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Komolytalan -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Svéd -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holland -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finn -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Lengyel -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Szlovák -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norvég -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Magyar -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Osztrák -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romániai -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Cseh -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Svájci -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dán -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Török -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Olasz -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalán - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatikus mentés STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Az automatikus mentések közötti időtartam kiválasztása @@ -1089,22 +1070,21 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Ez a be STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync (Vertikális Szinkronizáció) STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Jelöld be ezt a négyzetet hogy engedélyezd a v-sync-et. A változtatás csak a játék újraindítása után fog érvényesülni. Kizárólag hardware gyorsítással működik! +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Jelenlegi meghajtó: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Felület mérete -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Használni kívánt felületméret kiválasztása +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Felület mérete +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Használd a csúszkát a felület méretének beállításához. Ctrl nyomva tartásával további folyamatos állítás +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Méret automatikus felismerése +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Jelöld be ezt, a felület méretének automatikus felismeréséhez -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(automatikus) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normál -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dupla méret -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Négyszeres méret +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Élek méretezése +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Jelöld be ezt a négyzetet hogy az interfész méretéhez igazítsd az éleket -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Betűméret -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Használni kívánt betűméret kiválasztása - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(automatikus) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normál -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dupla méret -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Négyszeres méret +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafika @@ -1156,8 +1136,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Előné STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Font (£) a pénznemedben STR_CURRENCY_CHANGE_PARAMETER :{BLACK}A saját pénznem paramétereinek megváltoztatása -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Ellenfelek száma legfeljebb: {ORANGE}{COMMA} - STR_NONE :Semmi STR_FUNDING_ONLY :Csak finanszírozás STR_MINIMAL :Minimális @@ -1207,6 +1185,12 @@ STR_SUBSIDY_X2 :2x STR_SUBSIDY_X3 :3x STR_SUBSIDY_X4 :4x +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Mérsékelt táj +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Szubarktikus táj +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Szubtrópusi táj +STR_CLIMATE_TOYLAND_LANDSCAPE :Játékvilág táj + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Nagyon sík STR_TERRAIN_TYPE_FLAT :Sík @@ -1217,9 +1201,10 @@ STR_TERRAIN_TYPE_CUSTOM :Egyéni magass STR_TERRAIN_TYPE_CUSTOM_VALUE :Egyéni magasság ({NUM}) ###length 4 +STR_CITY_APPROVAL_LENIENT :Részrehajló STR_CITY_APPROVAL_TOLERANT :Toleráns STR_CITY_APPROVAL_HOSTILE :Ellenséges -STR_CITY_APPROVAL_PERMISSIVE :Engedékeny +STR_CITY_APPROVAL_PERMISSIVE :Engedékeny (nincs hatással a cég tevékenységére) STR_WARNING_NO_SUITABLE_AI :{WHITE}Nincsen megfelelő MI...{}Letölthetsz néhány MI-t a tartalomletöltő rendszeren keresztül @@ -1285,6 +1270,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Jobbra STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maximális kezdeti hitelkeret: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximálisan kölcsönözhető összeg (az inflációtól eltekintve) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Kamatláb: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Banki hitel kamat; inflációt is szabályozza, ha be van kapcsolva @@ -1320,8 +1306,8 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Ha engedélyezv STR_CONFIG_SETTING_DISASTERS :Katasztrófák: {STRING} STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Ha engedélyezve van, néha katasztrófa történhet, ami megállíthatja vagy megsemmisítheti a járműveket és az infrastruktúrát -STR_CONFIG_SETTING_CITY_APPROVAL :Városi tanács hozzáállása a területének az átépítéséhez: {STRING} -STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Válaszd ki, hogy mennyi zaj és környezeti kár okozása befolyásolja a cég megítélését egy városban, mely hatással van a cég további építési lehetőségeire a város területén belül +STR_CONFIG_SETTING_CITY_APPROVAL :Helyi hatóság hozzáállása: {STRING} +STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Válaszd ki, hogy mennyi zaj és környezeti kár okozása befolyásolja a cég megítélését egy városban, mely hatással van a cég további építési lehetőségeire az adott városban STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :Térkép magasságkorlátja: {STRING} STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_HELPTEXT :Beállíthatod a térkép legmagasabb pontjának tengerszint feletti magasságát. "(automatikus)" esetén az értéket a térképgenerátor határozza meg. @@ -1511,6 +1497,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Vonalak széles STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :NewGRF nevének mutatása a járművásárlási ablakban: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :A járművásárlási ablakban egy külön sorban legyen kiírva a NewGRF neve, amiből a kiválasztott jármű jön. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Megmutatja az összes rakományt amit a járművek képesek szállítania lista ablakban {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Ha be van kapcsolva, a jármű szállítható rakománya megjelenik fölötte a jármű listában. STR_CONFIG_SETTING_LANDSCAPE :Táj: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :A tájak alapvető játékbeállításokat határoznak meg különféle árukkal és településnövekedési tényezőkkel. A NewGRF-ek és a játékszkriptek segítségével ez még tovább hangolható. @@ -1565,6 +1553,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Javított STR_CONFIG_SETTING_ROAD_SIDE :Közúti járművek: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Melyik oldalon közlekedjenek a közúti járművek +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Balra hajtás +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Jobbra hajtás + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Magasságtérkép forgatása: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Órairánnyal szemben @@ -1591,7 +1583,13 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Zöld STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Sötétzöld STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Sötétkék +STR_CONFIG_SETTING_LINKGRAPH_COLOURS :Rakományáramlási átfedési színek: {STRING} +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_HELPTEXT :Rakományáramlási átfedési színséma beállítása. ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :Zöldről pirosra (eredeti) +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Zöldből kékbe +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Szürkéről pirosra +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :Szürkeárnyalat STR_CONFIG_SETTING_SCROLLMODE :A látkép mozgatása: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :A látkép mozgatásának módja @@ -2093,7 +2091,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatikus meg STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :A vonatok automatikus megfordításának engedélyezése, ha azok túl hosszú ideje várakoznak egy jelző előtt ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Ajánlott) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Ajánlott) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Válassz beállítási értéket @@ -2136,7 +2134,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Rekord t STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Beállítások STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF beállítások STR_INTRO_ONLINE_CONTENT :{BLACK}Letölthető tartalmak -STR_INTRO_SCRIPT_SETTINGS :{BLACK}MI / Játékszkript beállítások +STR_INTRO_AI_SETTINGS :{BLACK}MI Beállítások +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Játékszkript beállítások STR_INTRO_QUIT :{BLACK}Kilépés STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Új játék kezdése. Ctrl+kattintással átugorhatod a térkép beállításokat @@ -2156,7 +2155,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Rekord t STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}A beállítások megjelenítése STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF beállítások megjelenítése STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Új és frissített tartalmak megtekintése és letöltése -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}MI és játékszkript beállítások megjelenítése +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}MI beállítások megjelenítése +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Játékszkript beállítások megjelenítése STR_INTRO_TOOLTIP_QUIT :{BLACK}Kilépés az OpenTTD-ből STR_INTRO_BASESET :{BLACK}A jelenleg kiválasztott grafikus alapcsomagból {NUM} sprite hiányzik. Frissítsd a grafikus alapcsomagot! @@ -2188,12 +2188,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Dátum STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Aktuális év megváltoztatása STR_CHEAT_SETUP_PROD :{LTBLUE}A nyersanyagüzemek termelése változtatható: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Mérsékelt táj -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Szubarktikus táj -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Szubtrópusi táj -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Játékvilág táj - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} színsémája @@ -2426,7 +2420,6 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Új vállalat) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Hozz létre egy új vállalatot és csatlakozz STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Ez vagy te STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Ez a játék elindítója -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} kliens / {NUM} vállalat # Matches ConnectionType ###length 5 @@ -2553,11 +2546,11 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :várakozás a k STR_NETWORK_MESSAGE_CLIENT_LEAVING :kilépés STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} csatlakozott a játékhoz -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} csatlakozott a játékhoz ({2:NUM}. számú kliens) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} csatlakozott a(z) {2:NUM}. számú vállalathoz +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} csatlakozott a játékhoz ({2:NUM}. számú kliens) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} csatlakozott a(z) {2:NUM}. számú vállalathoz STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} csatlakozott a megfigyelőkhöz -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} új vállalatot alapított (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} kilépett a játékból ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} új vállalatot alapított (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} kilépett a játékból ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} nevet változtatott. Új neve: {STRING} STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} a következő összeget utalta {1:STRING} részére: {2:CURRENCY_LONG} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}A szerver leállította a játékot @@ -2673,6 +2666,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}telített STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}túlterhelt +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} elszállítva havonta innen: {STATION} ide: {STATION} ({COMMA}% elszállítva){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} visszaszállításra ({COMMA}% elszállítva) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Átlagos utazási idő: {NUM}{NBSP}nap{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Lefedett terület mutatása: STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Ki @@ -2681,6 +2679,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Az állo STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Az állomással lefedett terület mutatása (vonzáskörzet) STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Elfogad:{GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Termel: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Javítás költsége: {GOLD}{CURRENCY_SHORT}/év # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Állomás egyesítése @@ -2763,8 +2762,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Automata STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Válassz egy vasúti hidat STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Közúti híd építése STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Híd kiválasztása - kattints arra a hídra, amit meg akarsz építeni -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Függő, acél STR_BRIDGE_NAME_GIRDER_STEEL :Gerendás, acél STR_BRIDGE_NAME_CANTILEVER_STEEL :Rácsos, acél @@ -2868,11 +2865,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Tájrend STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Egy pont lesüllyesztése. Húzással az első kiválasztott sarkot lesüllyeszti, majd a kiválasztott területet vele egy szintbe hozza. Ctrl lenyomásával átlós terület jelölhető ki. Shift lenyomásával megmutatja a terepsüllyesztés várható építési költségét STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Egy sarokpont megemelése. Húzással az első kiválasztott sarkot megemeli, majd a kiválasztott területet vele egy szintbe hozza. Ctrl lenyomásával átlós terület jelölhető ki. Shift lenyomásával megmutatja a terepemelés várható építési költségét STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Talaj a kijelölt sarokpont szintjére hozása. Ctrl lenyomásával átlós terület jelölhető ki. Shift lenyomásával megmutatja az átalakítás várható költségét -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Földterület megvétele későbbi használatra. Shift lenyomásával megmutatja a várható költséget +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Földterület megvétele későbbi használatra. Ctrl lenyomásával átlós terület jelölhető ki. Shift lenyomásával megmutatja a várható költséget # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Objektum kiválasztása -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Építendő objektum kiválasztása. Shift lenyomásával megmutatja a várható költséget +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Építendő objektum kiválasztása. Ctrl lenyomásával átlós terület jelölhető ki. Shift lenyomásával megmutatja a becsült költséget STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Építendő objektum típusának kiválasztása STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Objektum előnézete STR_OBJECT_BUILD_SIZE :{BLACK}Méret: {GOLD}{NUM} x {NUM} mező @@ -2916,6 +2913,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Egy vél STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Település építése véletlenszerű helyre STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Sok véletlen település STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Véletlenszerüen elhelyez a térképen sok települést. +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Minden város növelése +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Minden város enyhe növelése STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Városnév: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}A város nevének megadása @@ -3194,6 +3193,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Térkép STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Válaszd ki a térkép méretét. Az elérhető mezők száma egy kicsit kevesebb lesz STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Várossűrűség: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Városnevek: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}A városnevek stílusának kiválasztása STR_MAPGEN_DATE :{BLACK}Dátum: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Gazd. épületek száma: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Legmagasabb pont: @@ -3207,13 +3208,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Sivatag STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}A sivatag kiterjedésének növelése 10%-kal STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}A sivatag kiterjedésének csökkentése 10%-kal STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Térkép generátor: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tereptípus: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Tengerszint: +STR_MAPGEN_SEA_LEVEL :{BLACK}Tengerszint: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Folyók: STR_MAPGEN_SMOOTHNESS :{BLACK}Simaság: STR_MAPGEN_VARIETY :{BLACK}Változatosság eloszlása: STR_MAPGEN_GENERATE :{WHITE}Generál +STR_MAPGEN_NEWGRF_SETTINGS :NewGRF Beállítások +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}NewGRF beállítások megjelenítése +STR_MAPGEN_AI_SETTINGS :{BLACK}MI Beállítások +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}MI beállítások megjelenítése +STR_MAPGEN_GS_SETTINGS :{BLACK}Játékszkript Beállítások +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Játékszkript beállítások megjelenítése + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Angol (Eredeti) +STR_MAPGEN_TOWN_NAME_FRENCH :Francia +STR_MAPGEN_TOWN_NAME_GERMAN :Német +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Angol (További) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latin-amerikai +STR_MAPGEN_TOWN_NAME_SILLY :Komolytalan +STR_MAPGEN_TOWN_NAME_SWEDISH :Svéd +STR_MAPGEN_TOWN_NAME_DUTCH :Holland +STR_MAPGEN_TOWN_NAME_FINNISH :Finn +STR_MAPGEN_TOWN_NAME_POLISH :Lengyel +STR_MAPGEN_TOWN_NAME_SLOVAK :Szlovák +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norvég +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Magyar +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Osztrák +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romániai +STR_MAPGEN_TOWN_NAME_CZECH :Cseh +STR_MAPGEN_TOWN_NAME_SWISS :Svájci +STR_MAPGEN_TOWN_NAME_DANISH :Dán +STR_MAPGEN_TOWN_NAME_TURKISH :Török +STR_MAPGEN_TOWN_NAME_ITALIAN :Olasz +STR_MAPGEN_TOWN_NAME_CATALAN :Katalán # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Térkép határai: @@ -3272,7 +3301,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Részlet STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Aktív NewGRF fájlok STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Inaktív NewGRF fájlok STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Lista kiválasztása: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Szűrendő kifejezés: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Szűrő kifejezés: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Kiválasztott lista betöltése STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Lista mentése STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}A kiválasztott elemek listába mentése @@ -3359,6 +3388,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Előző STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Továbbhaladás az előző normál spritera, kihagyva bármilyen ál/átszínező/betű spriteokat, az elején folytatva az utolsóval STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}A jelenleg kiválasztott sprite ábrázolása. Az elhelyezkedés kikapcsolt sprite-rajzolás közben STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Sprite elmozdítása, módosítva az X és Y offszeteket. Ctrl+kattintással a spriteot nyolc egységgel mozgatja + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Eltolás központosítva +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite középpontolás + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Célkereszt + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Eltolás visszaállítása STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}A jelenlegi relatív eltolás visszaállítása STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X eltolás: {NUM}, Y eltolás: {NUM} (Abszolút) @@ -3373,18 +3409,16 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Figyelmeztetés: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Hiba: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Végzetes hiba: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Egy végzetes NewGRF hiba történt:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF hiba történt:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} nem fog működni az OpenTTD által jelentett TTDPatch verzióval -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} a TTD {STRING} verziójához van -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} úgy lett tervezve, hogy együtt lesz használva ezzel: {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Hibás paraméterérték ehhez: {1:STRING}: paraméter {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} muszáj, hogy betöltődjön ezelőtt: {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} muszáj, hogy ezután töltődjön be: {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} csak a {STRING} vagy újabb verziójú OpenTTD-vel működik +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} a TTD {2:STRING} verziójához van +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} úgy lett tervezve, hogy együtt lesz használva ezzel: {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Hibás paraméterérték ehhez: {1:STRING}: paraméter {2:STRING} ({NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} muszáj, hogy betöltődjön ezelőtt: {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} muszáj, hogy ezután töltődjön be: {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} csak a {2:STRING} vagy újabb verziójú OpenTTD-vel működik STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :az adott GRF fájl célja egy másik lefordítása STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Túl sok NewGRF van betöltve -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :{1:STRING} betöltése mint statikus NewGRF {STRING} mellett ütközést okozhat +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :{1:STRING} betöltése mint statikus NewGRF {2:STRING} mellett ütközést okozhat STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Váratlan sprite (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Ismeretlen Action 0 tulajdonság {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Érvénytelen ID használat (sprite {3:NUM}) @@ -3516,14 +3550,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Kizárólagos s STR_LOCAL_AUTHORITY_ACTION_BRIBE :Önkormányzat megvesztegetése ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Kis helyi reklámhadjárat indítása, hogy több utast és rakományt vonzz a megállóidba.{}A város körül kis területen ideiglenesen javítja az állomásaid minősítését.{}Ára: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Közepes helyi reklámhadjárat indítása, hogy több utast és rakományt vonzz a megállóidba.{}A város körül közepes méretű területen ideiglenesen javítja az állomásaid minősítését.{}Ára: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Nagy helyi reklámhadjárat indítása, hogy több utast és rakományt vonzz a megállóidba.{}A város körül nagy területen ideiglenesen javítja az állomásaid minősítését.{}Ára: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}A városi úthálózat felújításának támogatása.{}Hat hónapig jelentősen összezavarja a közúti forgalmat.{}Ára: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Szobor építése a vállalatod tiszteletére.{}Javítja az állomásaid értékelését a városban.{}Ára: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Új kereskedelmi épületek építésének támogatása a városban.{}A város egy ideig gyorsabban fog növekedni.{}Ára: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Egy éves kizárólagos szállítási jogok vásárlása a városban.{}Az önkormányzat megtiltja az utasoknak és a rakományoknak, hogy más vállalatok állomásait használják.{}Ára: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}A megítélésed növelése az önkormányzat megvesztegetésével, komoly büntetést kockáztatva, ha az kiderül.{}Ára: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Kis helyi reklámhadjárat indítása, hogy több utast és rakományt vonzz a megállóidba.{}A város körül kis területen ideiglenesen javítja az állomásaid minősítését.{}{POP_COLOUR}Ára: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Közepes helyi reklámhadjárat indítása, hogy több utast és rakományt vonzz a megállóidba.{}A város körül közepes méretű területen ideiglenesen javítja az állomásaid minősítését.{}{POP_COLOUR}Ára: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Nagy helyi reklámhadjárat indítása, hogy több utast és rakományt vonzz a megállóidba.{}A város körül nagy területen ideiglenesen javítja az állomásaid minősítését.{}{POP_COLOUR}Ára: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}A városi úthálózat felújításának támogatása.{}Hat hónapig jelentősen összezavarja a közúti forgalmat.{}{POP_COLOUR}Ára: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Szobor építése a vállalatod tiszteletére.{}Javítja az állomásaid értékelését a városban.{}{POP_COLOUR}Ára: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Új kereskedelmi épületek építésének támogatása a városban.{}A város egy ideig gyorsabban fog növekedni.{}{POP_COLOUR}Ára: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Egy éves kizárólagos szállítási jogok vásárlása a városban.{}Az önkormányzat megtiltja az utasoknak és a rakományoknak, hogy más vállalatok állomásait használják.{}{POP_COLOUR}Ára: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}A megítélésed növelése az önkormányzat megvesztegetésével, komoly büntetést kockáztatva, ha az kiderül.{}{POP_COLOUR}Ára: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} céljai @@ -3676,24 +3710,38 @@ STR_FINANCES_CAPTION :{WHITE}{COMPANY STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}Jövedelem +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Működési Költségek +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Tőke Költségek ###length 13 STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Építkezés STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Új járművek -STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Vonat működtetési költség -STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Közúti jármű műk. költség -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Repülőgép műk. költség -STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Hajó működtetési költség +STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Vonatok +STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Közúti Járművek +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Repülőgép +STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Hajók +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Infrastruktúra +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Vonatok +STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}Közúti Járművek +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Repülőgép +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Hajók STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Kölcsön kamata STR_FINANCES_SECTION_OTHER :{GOLD}Egyéb -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} -STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_TOTAL_CAPTION :{WHITE}Összesen +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} +STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Nyereség STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Banki egyenleg +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Saját források STR_FINANCES_LOAN_TITLE :{WHITE}Kölcsön +STR_FINANCES_INTEREST_RATE :{WHITE}Banki hitel Kamat: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Max. kölcsön: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Kölcsönkér {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Kölcsön növelése. Ctrl+kattintással amennyivel csak lehet STR_FINANCES_REPAY_BUTTON :{BLACK}Visszafizet {CURRENCY_LONG} @@ -3794,7 +3842,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Termel: STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Elfogad: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} várakozik{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Termelés megváltoztatása (8 többszörösei 2040-ig) @@ -3824,6 +3872,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}A listá STR_VEHICLE_LIST_REPLACE_VEHICLES :Járművek lecserélése STR_VEHICLE_LIST_SEND_FOR_SERVICING :Javításra küld STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Idei nyereség: {CURRENCY_LONG} (Tavalyi: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Elküldi járműtelepre STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Elküldi garázsba @@ -3915,6 +3965,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Maximál STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Hatótávolság: {GOLD}{COMMA} mező STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Típus: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Minden rakománytípus +STR_CARGO_TYPE_FILTER_FREIGHT :Tehervonat +STR_CARGO_TYPE_FILTER_NONE :Nincs + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Vasúti jármű kiválasztása - kattints egy járműre az adataihoz. Ctrl+kattintással a járműtípus elrejthető/felfedhető STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Közúti jármű kiválasztása - kattints egy járműre az adataihoz. Ctrl+kattintással a járműtípus elrejthető/felfedhető @@ -4083,7 +4138,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :repülőgép STR_ENGINE_PREVIEW_SHIP :hajó STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Ár: {CURRENCY_LONG} Súly: {WEIGHT_SHORT}{}Sebesség: {VELOCITY} Teljesítmény: {POWER}{}Üzemeltetés: {CURRENCY_LONG}/év{}Kapacitás: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Ár: {CURRENCY_LONG} Súly: {WEIGHT_SHORT}{}Sebesség: {VELOCITY} Teljesítmény: {POWER} Maximális vonóerő: {6:FORCE}{}Üzemeltetés: {4:CURRENCY_LONG}/év{}Kapacitás: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Ár: {0:CURRENCY_LONG} Súly: {1:WEIGHT_SHORT}{}Sebesség: {2:VELOCITY} Teljesítmény: {3:POWER} Maximális vonóerő: {6:FORCE}{}Üzemeltetés: {4:CURRENCY_LONG}/év{}Kapacitás: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Ár: {CURRENCY_LONG} Végsebesség: {VELOCITY}{}Kapacitás: {CARGO_LONG}{}Üzemeltetés: {CURRENCY_LONG}/év STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Ár: {CURRENCY_LONG} Sebesség: {VELOCITY}{}Típus: {STRING}{}Kapacitás: {CARGO_LONG}, {CARGO_LONG}{}Üzemeltetés: {CURRENCY_LONG}/év STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Ár: {CURRENCY_LONG} Sebesség: {VELOCITY}{}Típus: {STRING}{}Kapacitás: {CARGO_LONG}{}Üzemeltetés: {CURRENCY_LONG}/év @@ -4242,12 +4297,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Súly: { STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Súly: {LTBLUE}{WEIGHT_SHORT} {BLACK}Teljesítmény: {LTBLUE}{POWER}{BLACK} Végsebesség: {LTBLUE}{VELOCITY} {BLACK}Vonóerő: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Idei haszon: {LTBLUE}{CURRENCY_LONG} (tavalyi: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Idei haszon: {LTBLUE}{CURRENCY_LONG} (tavalyi: {CURRENCY_LONG}) {BLACK}Minimum teljesítmény: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Megbízhatóság: {LTBLUE}{COMMA}% {BLACK}Lerobbanások az utolsó javítás óta: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Vásárlás éve: {LTBLUE}{NUM}{BLACK} Érték: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Kapacitás: {LTBLUE}Nincs{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapacitás: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapacitás: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapacitás: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapacitás: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Kapacitás: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Szállítási díj: {LTBLUE}{CURRENCY_LONG} @@ -4273,8 +4329,8 @@ STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Érték: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Teljes szállítási kapacitása ennek a vonatnak: -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Üres STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} {STATION} állomásról @@ -4513,25 +4569,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}A menetr STR_TIMETABLE_STATUS_START_AT :{BLACK}A menetrend megkezdésének dátuma {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Indulás dátuma -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Menetrend kezdeti dátumának kiválasztása. A ctrl+kattintás azon kívül, hogy beállítja ennek a menetrendnek a kezdetét, egyenletesen elosztja az ezen a menetrenden osztozó járműveket a jelenlegi utasításuk alapján, amennyiben a menetrend teljesen időzítve van. +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Menetrend kezdeti dátumának kiválasztása. A ctrl+kattintás egyenletesen elosztja az ezen a menetrenden osztozó járműveket a kezdeti dátumtól fogva a jelenlegi utasításuk alapján, amennyiben a menetrend teljesen időzítve van. STR_TIMETABLE_CHANGE_TIME :{BLACK}Idő megváltoztatása -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}A kijelölt utasítás végrehajtási idejét változtatja meg +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}A kijelölt utasítás végrehajtási idejét változtatja meg. Ctrl+kattintással beállítod az időt az összes utasításhoz. STR_TIMETABLE_CLEAR_TIME :{BLACK}Idő törlése -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}A kijelölt menetrendi sorhoz tartozó végrehajtási idő törlése +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}A kijelölt menetrendi sorhoz tartozó végrehajtási idő törlése. Ctrl+Klikkel kitörlöd az időt az összes utasításnál. STR_TIMETABLE_CHANGE_SPEED :{BLACK}Sebességkorlátozás megváltoztatása -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Kijelölt utasítás sebességkorlátozásának megváltoztatása +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Kijelölt utasítás sebességkorlátozásának megváltoztatása. Ctrl+kattintással beállíthatod a sebességet az összes utasításhoz. STR_TIMETABLE_CLEAR_SPEED :{BLACK}Sebességkorlátozás törlése -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Sebességkorlátozás törlése a kijelölt utasításból +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Sebességkorlátozás törlése a kijelölt utasításból. Ctrl+kattintással kitörlöd a sebességet az összes utasításból. STR_TIMETABLE_RESET_LATENESS :{BLACK}Késés nullázása STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Késés-számláló nullázása, azaz a jármű pontos lesz STR_TIMETABLE_AUTOFILL :{BLACK}Automatikus kitöltés -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Menetrend automatikus kitöltése a következő út értékeivel (Ctrl+kattintással megtartja a várakozási időket) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Menetrend automatikus kitöltése a következő út értékeivel Ctrl+kattintással megtartja a várakozási időket STR_TIMETABLE_EXPECTED :{BLACK}Várható STR_TIMETABLE_SCHEDULED :{BLACK}Tervezett @@ -4575,12 +4631,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Az egyik STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Az MI / Játékszkript nyomkövetés ablak csak a szerver számára elérhető # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}MI / Játékszkript beállítások +STR_AI_CONFIG_CAPTION_AI :{WHITE}MI Konfigurálás +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Játékszkript konfiguráció STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}A következő játékban betöltődő játékszkript STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}A következő játékban betöltődő MI-k STR_AI_CONFIG_HUMAN_PLAYER :Játékos STR_AI_CONFIG_RANDOM_AI :Véletlenszerűen választott MI STR_AI_CONFIG_NONE :(nincs) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Ellenfelek száma legfeljebb: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Mozgatás Fel STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Kiválasztott MI mozgatása felfelé a listában @@ -4588,12 +4646,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Mozgatá STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Kiválasztott MI mozgatása lefelé a listában STR_AI_CONFIG_GAMESCRIPT :{SILVER}Játékszkript +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Paraméterek STR_AI_CONFIG_AI :{SILVER}MI-k -STR_AI_CONFIG_CHANGE :{BLACK}{STRING} kiválasztása -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :MI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Játékszkript +STR_AI_CONFIG_CHANGE_AI :{BLACK}MI kiválasztása +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Játékszkript kiválasztása STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Másik szkript betöltése STR_AI_CONFIG_CONFIGURE :{BLACK}Beállítások STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}A szkript paramétereinek beállítása @@ -4621,10 +4678,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Teljes t STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Magasságtérkép mentése STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minitérkép mentése -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Paraméterek -STR_AI_SETTINGS_CAPTION_AI :MI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Játékszkript +# Script Parameters +STR_AI_SETTINGS_CAPTION_AI :{WHITE}MI paraméterei STR_AI_SETTINGS_CLOSE :{BLACK}Bezárás STR_AI_SETTINGS_RESET :{BLACK}Visszaállítás STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4788,6 +4843,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... túl STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nem tudok gazdasági épületet generálni... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Nem építhető ide {STRING}... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Nem építheted ide ezt a gazdasági épületet... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Nem lehet az iparágat kutatni... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... túl közel egy másik gazdasági épülethez STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... előbb települést kell építened STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... városonként csak egy lehet @@ -4802,6 +4858,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... erd STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... csak a hóhatár fölé építhető STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... csak a hóhatár alá építhető +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Az adományozás sikertelen a rossz szerencsének köszönhetően; próbáld újra +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Nem volt megfelelő hely ennek az iparág kutatására STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Nem volt megfelelő hely '{STRING}' elhelyezésére STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Változtasd meg a térképgenerálás paramétereit, hogy jobb térképet kapj @@ -4969,6 +5027,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objektum STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... vállalat székháza van az útban STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Nem veheted meg ezt a földterületet... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... már a tiéd! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... objektum építési limit elérve # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Csoport létrehozás sikertelen... @@ -5041,6 +5100,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Nem vál STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... jármű megsemmisült +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... nem minden jármű egyforma + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Egyáltalán nincsenek elérhető járművek STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Változtasd meg a NewGRF konfigurációdat! STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Még nincsenek elérhető járművek @@ -5067,6 +5128,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Nem lehe STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... a jármű nem tud az összes állomásra eljutni STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... a jármű nem tud a megadott állomásra eljutni STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... egy jármű, amivel meg van osztva ez az utasítás, nem tud a megadott állomásra eljutni +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... nem minden járműnek ugyanaz az utasításlistája +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... nem minden jármű osztja meg az utasításlistáját STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Nem lehet megosztani a menetrendet... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Nem lehet befejezni a menetrend megosztását... @@ -5074,6 +5137,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Nem lehe STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... túl távol van az előző céltól STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... a repülőgépnek kicsi a hatótávolsága +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}A jármű nem időzíthető STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}A járművek csak az állomáson várakozhatnak diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index 651e04f8417fa..80ddcfd854ddf 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -198,6 +198,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}hö. STR_UNITS_POWER_METRIC :{COMMA}hö. STR_UNITS_POWER_SI :{COMMA}kW + STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}tonn STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -354,9 +355,8 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Hætta # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Stillingar -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Gervigreind/leikjaforskrift STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF stillingar STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Gegnsæisstillingar STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Bæjanöfn sýnd @@ -895,36 +895,6 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :Sérsniðinn... STR_GAME_OPTIONS_CURRENCY_GEL :Lari (Gel) STR_GAME_OPTIONS_CURRENCY_IRR :Íranskt ríal (IRR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Vinstristefna -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Hægristefna - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Bæjanöfn -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Tungumál bæjarnafna - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Ensk (Upphafleg) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Frönsk -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Þýsk -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Ensk (Aukaleg) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Rómönsk-Amerísk -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Fáránleg -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Sænsk -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Hollensk -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finnsk -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Pólsk -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slóvakísk -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norsk -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungversk -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austurrísk -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rúmensk -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tékknesk -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Svissnesk -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dönsk -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Tyrknesk -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Ítölsk -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalónsk - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Sjálfvirk vistun STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Tíðni sjálfvirkra vistana @@ -954,7 +924,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :annað - STR_GAME_OPTIONS_BASE_GRF :{BLACK}Grunngrafík STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Nota grunngrafíkina STR_GAME_OPTIONS_BASE_GRF_STATUS :{RED}{NUM} týnd{P "" ar} eða ónýt{P "" ar} skrá{P "" r} @@ -997,8 +966,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Dæmi: STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10.000 pund (£) í þessum gjaldmiðli STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Breyta sérsniðnum gjaldmiðli -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Hámarksfjöldi keppinauta: {ORANGE}{COMMA} - STR_NONE :Engin STR_FUNDING_ONLY :Með fjármögnun STR_MINIMAL :Lágmark @@ -1048,6 +1015,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Temprað landslag +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Heimskautalandslag +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Miðjarðarlandslag +STR_CLIMATE_TOYLAND_LANDSCAPE :Leikfangalandslag + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Mjög slétt STR_TERRAIN_TYPE_FLAT :Slétt @@ -1113,6 +1086,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Hægri STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Hámarkslán: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Hámarks upphæð sem fyrirtæki getur fengið lánað (ekki er gert ráð fyrir verðbólgu) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Vextir: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Vextir á lánum, stjórnar einnig verðbólgu, ef hún er virk @@ -1354,6 +1328,10 @@ STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :Venjulega STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Nýstárlega +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Vinstristefna +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Hægristefna + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Snúningur hæðakorts: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Rangsælis @@ -1759,7 +1737,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Snúa járnbrau STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Leyfa járnbrautarlestum að snúa við á umferðarmerkjum ef þau hafa beðið þar í langan tíma ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Ráðlegt) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Ráðlegt) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Breyta gildi stillingar @@ -1799,7 +1777,6 @@ STR_INTRO_GAME_OPTIONS :{BLACK}Stilling STR_INTRO_HIGHSCORE :{BLACK}Stigatafla STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Stillingar STR_INTRO_ONLINE_CONTENT :{BLACK}Ná í viðbætur af netinu -STR_INTRO_SCRIPT_SETTINGS :{BLACK}GG/forskriftar stillingar STR_INTRO_QUIT :{BLACK}Hætta STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Hefja nýjan leik. Ctrl+smella sleppir kortastillingum @@ -1818,7 +1795,6 @@ STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Stilla O STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Birta stigatöflu STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Sýna NewGRF stillingar STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Skoða viðbætur sem hægt er að ná í af netinu -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Birta stillingar fyrir gervigreind/forskrift STR_INTRO_TOOLTIP_QUIT :{BLACK}Hætta í OpenTTD STR_INTRO_TRANSLATION :{BLACK}Það vantar {NUM} þýðing{P u ar} í þetta tungumál. Vinsamlegast hjálpaðu við að gera OpenTTD betra með því að skrá þig sem þýðanda. Nánari upplýsingar í readme.txt. @@ -1845,12 +1821,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Breyta STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Breyta um ár STR_CHEAT_SETUP_PROD :{LTBLUE}Leyfa breytingar á verðmæti framleiðslu: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Temprað landslag -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Heimskautalandslag -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Miðjarðarlandslag -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Leikfangalandslag - # Livery window STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Grunnlitur fyrirtækis @@ -2241,6 +2211,8 @@ STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Gera hlu # Linkgraph legend window and linkgraph legend in smallmap +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Svæði sem tilheyrir stöð STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Fela @@ -2329,8 +2301,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Auka þ STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Veldu tegund brúar STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Veldu vegabrú STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Brúarval - smelltu á brú að eigin vali til að reysa hana -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Hengibrú, stál STR_BRIDGE_NAME_GIRDER_STEEL :Burðarbitabrú, stál STR_BRIDGE_NAME_CANTILEVER_STEEL :Svifbitabrú, stál @@ -2681,16 +2651,40 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kortast STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Veldu stærð kortsins í reitum. Fjöldi reita verða aðeins færri STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Fjöldi bæja: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Bæjanöfn +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Tungumál bæjarnafna STR_MAPGEN_DATE :{BLACK}Dags.: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Fjöldi iðnaða: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Landmyndun: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Gerð lands: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Magn sjávar: +STR_MAPGEN_SEA_LEVEL :{BLACK}Magn sjávar: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Ár: STR_MAPGEN_SMOOTHNESS :{BLACK}Sléttleiki lands: STR_MAPGEN_VARIETY :{BLACK}Fjölbreytileikadreifing: STR_MAPGEN_GENERATE :{WHITE}Mynda land +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Ensk (Upphafleg) +STR_MAPGEN_TOWN_NAME_FRENCH :Frönsk +STR_MAPGEN_TOWN_NAME_GERMAN :Þýsk +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Ensk (Aukaleg) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Rómönsk-Amerísk +STR_MAPGEN_TOWN_NAME_SILLY :Fáránleg +STR_MAPGEN_TOWN_NAME_SWEDISH :Sænsk +STR_MAPGEN_TOWN_NAME_DUTCH :Hollensk +STR_MAPGEN_TOWN_NAME_FINNISH :Finnsk +STR_MAPGEN_TOWN_NAME_POLISH :Pólsk +STR_MAPGEN_TOWN_NAME_SLOVAK :Slóvakísk +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norsk +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungversk +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austurrísk +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rúmensk +STR_MAPGEN_TOWN_NAME_CZECH :Tékknesk +STR_MAPGEN_TOWN_NAME_SWISS :Svissnesk +STR_MAPGEN_TOWN_NAME_DANISH :Dönsk +STR_MAPGEN_TOWN_NAME_TURKISH :Tyrknesk +STR_MAPGEN_TOWN_NAME_ITALIAN :Ítölsk +STR_MAPGEN_TOWN_NAME_CATALAN :Katalónsk + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Hliðar korts: STR_MAPGEN_NORTHWEST :{BLACK}Norðvestur @@ -2816,6 +2810,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Fyrri hr STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Fara á fyrri venjulegu hreyfimynd, sleppir gervi/endurlitun/letur hreyfimyndum og fer aftast í listen þegar upphafi er náð. STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Framsetning á valinni hreyfimynd. Samstillingu er sleppt við teikningu á þessari hreyfimynd. STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Færðu hreyfimyndina, breytir X og Y hliðrun + +###length 2 + + STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Veldu hreyfimynd STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Veldu hreyfimynd hvaðan sem er af skjánum @@ -2826,7 +2824,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Aðvörun: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Villa: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Banvænt: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Alvarleg NewGRF villa átti sér stað:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} Mun ekki virka með útgáfu TTDPatch sem OpenTTD gefur til kynna. STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} er fyrir {STRING} útgáfu af TTD. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} er hannað til að notast með {STRING} @@ -3280,6 +3277,8 @@ STR_PURCHASE_INFO_ALL_BUT :Allt nema {CARG STR_PURCHASE_INFO_MAX_TE :{BLACK}Hámarks togkrafur: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Drægni: {GOLD}{COMMA} reitir +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Lestarlisti - smelltu á farartæki fyrir meiri upplýsingar STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Bifreiðalisti - ýttu á bifreið fyrir nánari upplýsingar @@ -3881,12 +3880,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Ein af f STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Aflúsunargluggi gervigreindar/forskriftar er aðeins aðgengilegur á þjóni # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Stilling gervigreindar/forskriftar STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Forskriftin sem verður hlaðin í næsta leik STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Gervigreindin sem verður hlaðin í næsta leik STR_AI_CONFIG_HUMAN_PLAYER :Mennskur leikmaður STR_AI_CONFIG_RANDOM_AI :Gervigreind af handahófi STR_AI_CONFIG_NONE :(engin) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Hámarksfjöldi keppinauta: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Færa upp STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Færa valda gerfigreind upp listann @@ -3896,8 +3895,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Færa va STR_AI_CONFIG_GAMESCRIPT :{SILVER}Forskrift STR_AI_CONFIG_AI :{SILVER}Gervigreindir -STR_AI_CONFIG_CHANGE :{BLACK}Veldu {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :gervigreind STR_AI_CONFIG_CHANGE_GAMESCRIPT :Forskrift STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Hlaða annarri forskrift @@ -3920,10 +3917,8 @@ STR_AI_LIST_CANCEL :{BLACK}Hætta v STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Hætta við breytingar forskriftar -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} breytur +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :Gervigreindar -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Leikja forskriftar STR_AI_SETTINGS_CLOSE :{BLACK}Loka STR_AI_SETTINGS_RESET :{BLACK}Frumstilla STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4322,6 +4317,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Get ekki STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... ökutæki er eyðilagt + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Engin farartæki verða í boði STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Breyta NewGRF stillingunum þínum @@ -4353,6 +4349,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Get ekki STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... of langt frá fyrri stað STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... flugvél hefur ekki næga drægni +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Get ekki gert áætlun farartækis... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Farartæki getur aðeins beðið við stöð diff --git a/src/lang/ido.txt b/src/lang/ido.txt index e908950a9abc9..7c77b14082b14 100644 --- a/src/lang/ido.txt +++ b/src/lang/ido.txt @@ -196,6 +196,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}kp STR_UNITS_POWER_METRIC :{COMMA}kp STR_UNITS_POWER_SI :{COMMA}kW + STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -286,7 +287,7 @@ STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Pozez ob STR_SCENEDIT_FILE_MENU_SEPARATOR : # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_FULL_DETAIL :Plene detaloza STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS :Diafana konstrukturi @@ -472,11 +473,6 @@ STR_GAME_OPTIONS_CAPTION :{WHITE}Ludo Sel ###length 42 -###length 2 - - -###length 21 - # Autosave dropdown ###length 5 @@ -497,7 +493,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :altra - # Custom currency window @@ -505,7 +500,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :altra - STR_NUM_LOW :Basa STR_NUM_NORMAL :Normala STR_NUM_HIGH :Alta @@ -536,6 +530,8 @@ STR_SEA_LEVEL_CUSTOM_PERCENTAGE :Kustumigita ({N ###length 4 +###length 4 + ###length 7 ###length 4 @@ -556,6 +552,7 @@ STR_CONFIG_SETTING_NONE :Nulo ###length 3 +###setting-zero-is-special @@ -650,6 +647,8 @@ STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :normala ###length 2 +###length 2 + @@ -820,8 +819,6 @@ STR_QUIT_NO :{BLACK}Ne # Cheat window -###length 4 - # Livery window @@ -906,6 +903,8 @@ STR_NETWORK_SERVER_MESSAGE :*** {1:STRING} # Linkgraph legend window and linkgraph legend in smallmap +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Aceptas: {GOLD}{CARGO_LIST} @@ -1029,6 +1028,8 @@ STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NovaGRF # World generation STR_MAPGEN_BY :{BLACK}* +###length 21 + # Strings for map borders at game generation @@ -1063,6 +1064,10 @@ STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE :Fervoyo-tipo # Sprite aligner window +###length 2 + + + # NewGRF (self) generated warnings/errors STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING} @@ -1226,6 +1231,8 @@ STR_GROUP_DEFAULT_AIRCRAFTS :Negrupigita aer ###length VEHICLE_TYPES +###length 3 + ###length VEHICLE_TYPES ###length VEHICLE_TYPES @@ -1440,14 +1447,13 @@ STR_AI_DEBUG_NAME_AND_VERSION :{BLACK}{STRING} -STR_AI_CONFIG_CHANGE_NONE : # Available AIs window -# AI Parameters +# Script Parameters STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -1568,6 +1574,7 @@ STR_ERROR_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Tro mult + # Specific vehicle errors @@ -1575,6 +1582,8 @@ STR_ERROR_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Tro mult # Order related errors +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors # Sign related errors diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index 1a70e917c59dc..29e1bc03f6295 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}dk STR_UNITS_POWER_METRIC :{COMMA}{NBSP}dk STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/waktu +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -225,9 +235,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Kata penyaring: -STR_LIST_FILTER_OSKTITLE :{BLACK}Masukkan kata penyaring -STR_LIST_FILTER_TOOLTIP :{BLACK}Masukkan kata kunci untuk menyaring daftar +STR_LIST_FILTER_TITLE :{BLACK}Saring: +STR_LIST_FILTER_OSKTITLE :{BLACK}Masukkan satu atau lebih kata kunci untuk penyaringan pada list +STR_LIST_FILTER_TOOLTIP :{BLACK}Masukkan 1 atau lebih kata kunci untuk menyaring daftar STR_TOOLTIP_GROUP_ORDER :{BLACK}Pilihkan urutan kelompok STR_TOOLTIP_SORT_ORDER :{BLACK}Pilih modus pengurutan (menurun/menaik) @@ -376,9 +386,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Pertumbu STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Membuat Industri STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Pembangunan Jalan STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Pembangunan Jalur Tram -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Menanam Pohon. Shift untuk menampilkan perkiraan biaya +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Tanam Pohon. Ctrl untuk memilih area secara diagonal. Shift untuk menampilkan perkiraan biaya STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Memasang pengenal -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Tempatkan Obyek. Shift untuk menampilkan perkiraan biaya +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Tempatkan Obyek. Ctrl untuk memilih area secara diagonal. Shift untuk menampilkan perkiraan biaya # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Keluar # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Pengaturan permainan STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Pengaturan -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Pengaturan AI / Skrip Permainan +STR_SETTINGS_MENU_AI_SETTINGS :Pengaturan AI +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Pengaturan Game script STR_SETTINGS_MENU_NEWGRF_SETTINGS :Pengaturan NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Pengaturan Transparansi STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Nama kota ditampilkan @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :India Rupee (IN STR_GAME_OPTIONS_CURRENCY_IDR :Rupiah Indonesia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit Malaysia (MYR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}Pilih model nama kota - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Inggris (Orisinil) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Perancis -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Jerman -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Inggris (Tambahan) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Amerika-Latin -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Lucu -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Swedia -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Belanda -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandia -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polandia -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovakia -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norwegia -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungaria -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austria -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romania -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Ceko -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Swiss -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Denmark -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turki -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italia -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalan - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Simpan Otomatis STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Pilih selang waktu permainan otomatis disimpan @@ -1027,21 +1008,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Centang STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Pengendali piranti: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Ukuran antarmuka -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Pilih ukuran elemen antarmuka yang akan digunakan +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Ukuran antarmuka +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Geser slider untuk mengatur ukuran antarmuka. Tekan tombol Ctrl untuk pengaturan terus menerus +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Otomatis deteksi ukuran +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Pilih kotak ini untuk mendeteksi ukuran antarmuka secara otomatis -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(deteksi-otomatis) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Kali dua -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Kali empat +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Skala bevel +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Pilih kotak ini untuk pengaturan perbandingan ukuran bevel dengan ukuran antarmuka -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Ukuran font -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Pilih ukuran font antarmuka yang akan digunakan - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(deteksi-otomatis) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Kali dua -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :4 kali +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafik @@ -1093,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Contoh: STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pound (£) pada mata uang Anda STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Ubah sendiri parameter mata uang -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Jumlah pesaing maksimal: {ORANGE}{COMMA} - STR_NONE :Tidak ada STR_FUNDING_ONLY :Hanya pendanaan STR_MINIMAL :Minimal @@ -1144,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Lanskap 'Sedang' +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Lansekap 'Sub Arktik' +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Lansekap 'Sub Tropis' +STR_CLIMATE_TOYLAND_LANDSCAPE :Lansekap 'Taman Bermain' + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Sangat Datar STR_TERRAIN_TYPE_FLAT :Datar @@ -1163,7 +1146,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}Tidak te # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Pengaturan -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Penyaring kata: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Saring: 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 @@ -1223,6 +1206,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Kanan STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maksimum pinjaman awal: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Jumlah maksimum yang dapat dipinjam (tanpa menghitung inflasi) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Bunga pinjaman: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Bunga pinjaman; juga mengendalikan inflasi jika dinyalakan @@ -1449,6 +1433,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Tebalnya garis STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Tampilkan nama NewGRF di jendela beli kendaraan: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Tambahkan garis ke jendela beli kendaraan, yang menunjukkan NewGRF kendaraan yang dipilih berasal. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Tampilkan di windows senarai jenis kargo yang bisa diangkut oleh kendaraan {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Jika aktif maka beban transportasi kendaraan akan terlihat diatasnya di daftar kendaraan STR_CONFIG_SETTING_LANDSCAPE :Bentang Darat: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Lanskap mendefinisikan skenario gameplay dasar dengan kargo yang berbeda dan persyaratan pertumbuhan kota. NewGRF dan Game Scripts memungkinkan kontrol yang lebih halus @@ -1503,6 +1489,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Telah ditingkat STR_CONFIG_SETTING_ROAD_SIDE :Kendaraan jalan raya: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Memilih sisi mengemudi +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Berkendara di lajur kiri +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Berkendara di lajur kanan + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Perputaran peta Heightmap: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Melawan arah jam @@ -1936,13 +1926,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Ambil {STRING}{ STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Waktu dibutuhkan untuk setiap perhitungan dari komponen 'linkgraph'. Ketika perhitungan dimulai, ada utas 'dibuat' yang boleh dijalankan untuk jumlah hari ini. Semakin pendek anda mengatur ini lebih mungkin utas ini belum selesai ketika itu seharusnya. Kemudian permainan berhenti sampai itu ("lag"). Semakin lama anda mengatur semakin lama itu untuk distribusinya untuk memperbarui ketika rute mengganti. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modus distribusi untuk penumpang: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"simetris" berarti kira-kira jumlah penumpang yang sama akan pergi dari stasiun A ke stasiun B sebagaimana dari B ke A. "asimetris" berarti jumlah penumpang yang pergi ke kedua arah bisa berbeda-beda. "manual" berarti bahwa tidak ada distribusi otomatis akan dilakukan untuk penumpang. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simetris" berarti kira-kira jumlah penumpang sama akan pergi dari stasiun A ke stasiun B sebagaimana dari B ke A. "Asimetris" berarti jumlah penumpang pergi pada kedua arah bisa berbeda-beda. "Manual" berarti bahwa tidak ada distribusi otomatis akan dilakukan untuk penumpang. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Modus distribusi untuk surat: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"simetris" berarti kira-kira jumlah surat yang sama akan pergi dari stasiun A ke stasiun B sebagaimana dari B ke A. "asimetris" berarti jumlah surat yang pergi ke kedua arah bisa berbeda-beda. "manual" berarti bahwa tidak ada distribusi otomatis akan dilakukan untuk surat. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Simetris" berarti kira-kira jumlah surat yang sama akan dikirim dari stasiun A ke stasiun B sebagaimana dari B ke A. "Asimetris" berarti jumlah surat dikirim pada kedua arah bisa berbeda-beda. "Manual" berarti tidak ada distribusi otomatis akan dilakukan untuk surat. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Modus distribusi untuk kelas kargo BERLAPIS BAJA: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Kelas kargo BERLAPIS BAJA meliputi barang berharga pada iklim sedang, intan pada sub tropis atau emas pada iklim sub arktik. NewGRF mungkin mengubah itu. "simetris" berarti bahwa jumlah kargo kira-kira akan terkirim sama dari stasiun A ke stasiun B sebagaimana dari B ke A. "asimetris" berarti jumlah kargo terkirim bisa berbeda pada kedua arah. "manual" berarti bahwa tidak ada distribusi otomatis akan dilakukan untuk kargo itu. Disarankan untuk memilih asimetris atau manual ketika bermain sub arktik, karena bank tidak mengirim emas kembali ke tambang emas. Untuk iklim tropis dan sub tropis anda juga bisah pilih simetris karena bank akan mengirim kembali beberapa barang berharga ke bank asalnya. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Kelas kargo LAPIS-BAJA meliputi barang berharga pada iklim sedang, berlian pada iklim sub tropis atau emas pada iklim sub arktik. NewGRF bisa merubah ketentuan tersebut. "Simetris" berarti jumlah kargo kira-kira akan terkirim sama banyak dari stasiun A ke stasiun B sebagaimana dari B ke A. "Asimetris" berarti jumlah kargo terkirim bisa berbeda pada kedua arah. "Manual" berarti tidak ada distribusi otomatis yang akan dilakukan untuk kargo tersebut. Disarankan memilih asimetris atau manual ketika bermain pada sub arktik atau sub tropis, karena bank hanya sebagai penerima pada iklim tersebut. Untuk iklim sedang anda bisa memilih simetris karena bank akan mengirim barang berharga pula ke bank asal. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modus distribusi untuk kelas kargo yang lain: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asimetris" berarti jumlah kargo yang pergi ke kedua arah bisa berbeda-beda. "manual" berarti bahwa tidak ada distribusi otomatis akan dilakukan untuk kargo. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimetris" berarti jumlah kargo dikirim pada kedua arah bisa berbeda-beda. "Manual" berarti tidak ada distribusi otomatis akan dilakukan untuk kargo tersebut. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimetris @@ -2037,7 +2027,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Berputar otomat STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Perbolehkan kereta berputar di sinyal, jika telah menunggu lama ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recommended) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Ganti nilai tetapan @@ -2080,7 +2070,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Tabel Ni STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Pengaturan STR_INTRO_NEWGRF_SETTINGS :{BLACK}Pengaturan NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Cari Konten Daring -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Pengaturan Skrip AI/Permainan +STR_INTRO_AI_SETTINGS :{BLACK}Pengaturan AI +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Pengaturan Game Script STR_INTRO_QUIT :{BLACK}Keluar STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Mulai permainan baru. Ctrl-Klik melewatkan konfigurasi peta @@ -2100,7 +2091,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Tampilka STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Tampilkan pengaturan STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Tampilkan pengaturan NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Cari konten baru dan pembaruan untuk diunduh -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Tampilkan pengaturan permainan dan AI +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Tampilkan pengaturan AI +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Tampilan pengaturan game script STR_INTRO_TOOLTIP_QUIT :{BLACK}Keluar OpenTTD STR_INTRO_BASESET :{BLACK}Kumpulan grafik dasar yang dipilih saat ini hilang {NUM} sprite {P ..}. Silakan periksa pembaruan untuk baseset. @@ -2113,9 +2105,9 @@ STR_QUIT_YES :{BLACK}Ya STR_QUIT_NO :{BLACK}Tidak # Abandon game -STR_ABANDON_GAME_CAPTION :{WHITE}Batalkan Permainan +STR_ABANDON_GAME_CAPTION :{WHITE}Tinggalkan Permainan STR_ABANDON_GAME_QUERY :{YELLOW}Apakah anda yakin untuk meninggalkan permainan? -STR_ABANDON_SCENARIO_QUERY :{YELLOW}Apakan anda yakin untuk mengabaikan skenario ini ? +STR_ABANDON_SCENARIO_QUERY :{YELLOW}Apakah anda yakin untuk mengabaikan skenario ini ? # Cheat window STR_CHEATS :{WHITE}Kode Curang @@ -2132,12 +2124,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Ganti t STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Ubah tahun sekarang STR_CHEAT_SETUP_PROD :{LTBLUE}Aktifkan modifikasi nilai produksi: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Lanskap 'Sedang' -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Lansekap 'Sub Arktik' -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Lansekap 'Sub Tropis' -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Lansekap 'Taman Bermain' - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Skema Warna @@ -2370,7 +2356,6 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Perusahaan bar 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_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klien / {NUM} Perusahaan # Matches ConnectionType ###length 5 @@ -2497,13 +2482,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :menunggu pembar STR_NETWORK_MESSAGE_CLIENT_LEAVING :pergi STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} telah bergabung -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} sudah bergabung ke dalam permainan (Client #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} bergabung dalam perusahaan #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} sudah bergabung ke dalam permainan (Client #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} bergabung dengan perusahaan #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} bergabung menjadi penonton -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} mulai mendirikan perusahaan (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} meninggalkan permainan ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} mulai mendirikan perusahaan (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} meninggalkan permainan ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} telah mengganti namanya menjadi {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} memberikan {2:CURRENCY_LONG} kepada {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} memberikan {2:CURRENCY_LONG} kepada {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server menutup sesi STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server memulai ulang...{}Tunggulah... STR_NETWORK_MESSAGE_KICKED :*** {STRING} telah dikeluarkan. Alasan: ({STRING}) @@ -2617,6 +2602,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}sudah penuh (jenuh) STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}kelebihan beban +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} di transportasikan per bulan dari {STATION} ke {STATION} ({COMMA}% dari kapasitas){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} akan dikirim kembali ({COMMA}% dari kapasitas) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Rataan waktu tempuh: {NUM}{NBSP}hari{} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Jangkauan layanan STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Non-aktifkan @@ -2625,6 +2615,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Jangan s STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Soroti area yang dapat dilayani dari lokasi yang hendak dibangun STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Menerima: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Suplai: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Biaya perawatan: {GOLD}{CURRENCY_SHORT}/tahun # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Gabung stasiun @@ -2707,8 +2698,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Tambah k STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Pilih Jembatan Rel STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Pilih Jembatan STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Pilihan jembatan - Klik pada jembatan yang ingin anda bangun -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Suspensi, Baja STR_BRIDGE_NAME_GIRDER_STEEL :Balok, Baja STR_BRIDGE_NAME_CANTILEVER_STEEL :Beton, Baja @@ -2812,11 +2801,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Proses L STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Turunkan penjuru dataran. Drag untuk menurunkan penjuru pertama dan meratakan area setinggi penjuru yg baru. Ctrl untuk memilih secara diagonal. Shift untuk menampilkan perkiraan biaya STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Naikkan penjuru dataran. Drag untuk menaikkan penjuru pertama dan meratakan area setinggi penjuru yg baru. Ctrl untuk memilih secara diagonal. Shift untuk menampilkan perkiraan biaya STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Ratakan permukaan setinggi ujung kotak terpilih. Ctrl untuk memilih area secara diagonal. Shift untuk menampilkan perkiraan biaya -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Beli tanah untuk digunakan pada masa depan. Shift untuk menampilkan perkiraan biaya +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Beli tanah untuk digunakan pada masa depan. Ctrl memilih area secara diagonal. Shift untuk menampilkan perkiraan biaya # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Pemilihan obyek -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Pilih obyek yg akan dibangun. Shift untuk menampilkan perkiraan biaya +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Pilih obyek yg akan dibangun. Ctrl untuk memilih area secara diagonal. Shift untuk menampilkan perkiraan biaya STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Pilih kelas dari objek yang dibangun STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Pra-tayang obyek STR_OBJECT_BUILD_SIZE :{BLACK}Ukuran: {GOLD}{NUM} x {NUM} kotak @@ -2828,7 +2817,7 @@ STR_OBJECT_CLASS_TRNS :Pemancar STR_PLANT_TREE_CAPTION :{WHITE}Pepohonan STR_PLANT_TREE_TOOLTIP :{BLACK}Pilih jenis pohon untuk ditanam. Jika pohon sudah tertanam, ini akan menambah jenis pohon secara acak dari tipe yang sama. STR_TREES_RANDOM_TYPE :{BLACK}Tanam pohon secara acak -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Tempatkan tipe tumbuhan secara acak. Shift untuk menampilkan perkiraan biaya +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Tanam tipe pepohonan secara acak. Ctrl untuk memilih area secara diagonal. Shift untuk menampilkan perkiraan biaya STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Pohon Acak STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Menanam pohon secara acak pada lansekap STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2860,6 +2849,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Kota sec STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Membangun kota di lokasi secara acak STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Buat kota secara acak STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Dukung Peta dengan penempatan kota secara otomatis +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Perluas seluruh kota +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Buat seluruh kota sedikit berkembang STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nama kota: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Masukkan nama kota @@ -3124,7 +3115,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Rincian STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Tidak ada informasi yang tersedia STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter string: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Saring: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Timpa Berkas STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Yakin ingin menimpa berkas yang ada? STR_SAVELOAD_DIRECTORY :{STRING} (Direktori) @@ -3138,6 +3129,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Ukuran P STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Pilih ukuran peta dalam petak. Jumlah dari petak yang tersedia akan sedikit lebih kecil STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Jumlah Kota: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nama kota: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Pilih model nama kota STR_MAPGEN_DATE :{BLACK}Tgl: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Jumlah industri: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Puncak tertinggi: @@ -3151,13 +3144,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Cakupan 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_LAND_GENERATOR :{BLACK}Algoritma pulau: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Jenis dataran: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Area perairan: +STR_MAPGEN_SEA_LEVEL :{BLACK}Area perairan: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Sungai: STR_MAPGEN_SMOOTHNESS :{BLACK}Kehalusan: STR_MAPGEN_VARIETY :{BLACK}Macam penyebaran: STR_MAPGEN_GENERATE :{WHITE}Buat Peta +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Pengaturan NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Tampilkan pengaturan NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Pengaturan AI +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Tampilkan pengaturan AI +STR_MAPGEN_GS_SETTINGS :{BLACK}Pengaturan Script Permainan +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Tampilkan pengaturan game script + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Inggris (Orisinil) +STR_MAPGEN_TOWN_NAME_FRENCH :Perancis +STR_MAPGEN_TOWN_NAME_GERMAN :Jerman +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Inggris (Tambahan) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Amerika-Latin +STR_MAPGEN_TOWN_NAME_SILLY :Lucu +STR_MAPGEN_TOWN_NAME_SWEDISH :Swedia +STR_MAPGEN_TOWN_NAME_DUTCH :Belanda +STR_MAPGEN_TOWN_NAME_FINNISH :Finlandia +STR_MAPGEN_TOWN_NAME_POLISH :Polandia +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovakia +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norwegia +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungaria +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austria +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romania +STR_MAPGEN_TOWN_NAME_CZECH :Ceko +STR_MAPGEN_TOWN_NAME_SWISS :Swiss +STR_MAPGEN_TOWN_NAME_DANISH :Denmark +STR_MAPGEN_TOWN_NAME_TURKISH :Turki +STR_MAPGEN_TOWN_NAME_ITALIAN :Italia +STR_MAPGEN_TOWN_NAME_CATALAN :Catalan # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Jenis Tepi Peta: @@ -3216,7 +3237,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Rincian STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}File NewGRF aktif STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}File NewGRF tidak aktif STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Pilih preset: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Saring kata: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Saring: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Baca kembali setingan terdahulu yang terpilih STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Simpan STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Simpan daftar ini dalam daftar aturan @@ -3303,6 +3324,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Sprite s STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Lanjutkan ke sprite normal sebelumnya, lewati sembarang sprite bayangan/warna ulang/huruf dan pembungkus saat mulai STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Mewakili sprite yang sedang dipilih. Penjajaran diabaikan ketika sprite ini digambar STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Pindahkan sprite, mengubah offset X dan Y + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Offset di tengah +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite di tengah + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Crosshair + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Reset relatif STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Reset offset relatif saat ini STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X offset: {NUM}, Y offset: {NUM} (Absolute) @@ -3317,18 +3345,16 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Peringatan: {SILVER}{STRING} 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} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Parameter yang salah untuk {1:STRING}: parameter {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} harus dimuat sebelum {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} harus dimuat sesudah {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} membutuhkan OpenTTD versi {STRING} atau yang lebih tinggi +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} untuk TTD versi {2:STRING} +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} didesain untuk digunakan dengan {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Parameter yang salah untuk {1:STRING}: parameter {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} harus dimuat sebelum {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} harus dimuat sesudah {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} membutuhkan OpenTTD versi {2:STRING} atau diatasnya STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :Berkas NewGRF telah didesain untuk diterjemahkan STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Terlalu banyak berkas NewGRF yang dimuat -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Memuat NewGRF {1:STRING} secara statis dengan {STRING} dapat menyebabkan de-sinkronisasi +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Memuat NewGRF {1:STRING} secara statis dengan {2:STRING} dapat menyebabkan de-sinkronisasi STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Sprite salah / tidak terduga (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Properti Action 0 tidak diketahui {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Mencoba menggunakan ID invalid (sprite {3:NUM}) @@ -3460,14 +3486,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Beli hak transp STR_LOCAL_AUTHORITY_ACTION_BRIBE :Suap pemkot setempat ###length 8 -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} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Prakarsai kampanye iklan singkat, agar penumpang dan kargo lebih mengutamakan jasa perusahaan transportasi anda.{}Memberikan peningkatan sementara pada peringkat stasiun dalam radius kecil disekitar pusat kota.{}{POP_COLOUR}Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Prakarsai kampanye iklan sedang, agar penumpang dan kargo lebih mengutamakan jasa perusahaan transportasi anda.{}Memberikan peningkatan sementara pada peringkat stasiun dalam radius sedang di sekitar pusat kota.{}{POP_COLOUR}Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{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..{}{POP_COLOUR}Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Danai perbaikan jalanan perkotaan.{}Akan menyebabkan kemacetan arus lalu lintas hingga 6 bulan.{}{POP_COLOUR}Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Bangun patung sebagai kebanggaan perusahaan anda.{}Memberikan peningkatan permanen pada mutu stasiun di kota ini.{}{POP_COLOUR}Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Biayai pembangunan gedung baru di kota.{}Memberikan penggalak sementara pada pertumbuhan kota di kota ini,{}{POP_COLOUR}Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Beli hak monopoli transportasi di kota ini untuk 1 tahun.{}Pemerintah kota tidak akan mengizinkan penumpang dan kargo untuk memakai stasiun pesaing Anda.{}{POP_COLOUR} Biaya: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Lakukan suap pada pemkot untuk menaikan peringkat, beresiko denda jika tertangkap.{}{POP_COLOUR}Biaya: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Target @@ -3640,15 +3666,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Kapal STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Bunga Pinjaman STR_FINANCES_SECTION_OTHER :{GOLD}Lainnya +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Laba bersih +STR_FINANCES_PROFIT :{WHITE}Keuntungan STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Saldo Bank STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Dana Pribadi STR_FINANCES_LOAN_TITLE :{WHITE}Pinjaman STR_FINANCES_INTEREST_RATE :{WHITE}Bunga Pinjaman: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Pinjaman maks.: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Pinjam {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Tambah jumlah pinjaman. Tekan Ctrl+Click untuk meminjam sebanyak mungkin. STR_FINANCES_REPAY_BUTTON :{BLACK}Bayar {CURRENCY_LONG} @@ -3749,7 +3778,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produksi STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Membutuhkan: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} menunggu{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Perubahan produksi (kelipatan 8, hingga 2040) @@ -3779,6 +3808,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Kirim pe STR_VEHICLE_LIST_REPLACE_VEHICLES :Ganti kendaraan STR_VEHICLE_LIST_SEND_FOR_SERVICING :Perintahkan untuk diperbaiki STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Laba tahun ini: {CURRENCY_LONG} (tahun lalu: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Perintahkan ke bengkel STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Perintahkan ke Bengkel @@ -3870,6 +3901,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Traksi M STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Jangkauan: {GOLD}{COMMA} kotak STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Jenis pesawat: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Semua jenis kargo +STR_CARGO_TYPE_FILTER_FREIGHT :Kargo +STR_CARGO_TYPE_FILTER_NONE :Tidak ada + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Daftar pilihan kereta - klik pada kereta untuk menampilkan informasi STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Daftar pilihan kendaraan - klik pada kendaraan untuk menampilkan informasi @@ -4038,7 +4074,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :pesawat STR_ENGINE_PREVIEW_SHIP :kapal STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Biaya: {CURRENCY_LONG} Berat: {WEIGHT_SHORT}{}Kecepatan: {VELOCITY} Daya: {POWER}{}Biaya ops.: {CURRENCY_LONG}/thn{}Kapasitas: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Biaya: {CURRENCY_LONG} Berat: {WEIGHT_SHORT}{}Kecepatan: {VELOCITY} Power: {POWER} Max. T.E.: {6:FORCE}{}Biaya Operasional: {4:CURRENCY_LONG}/yr{}Kapasitas: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Biaya: {0:CURRENCY_LONG} Berat: {1:WEIGHT_SHORT}{}Kecepatan: {2:VELOCITY} Daya: {3:POWER} Max. T.E.: {6:FORCE}{}Biaya Operasional: {4:CURRENCY_LONG}/yr{}Kapasitas: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Biaya: {CURRENCY_LONG} Kec. Max: {VELOCITY}{}Kapasitas: {CARGO_LONG}{}Bea Berjalan: {CURRENCY_LONG}/thn STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Biaya: {CURRENCY_LONG} Kec. Max.: {VELOCITY}{}Jenis pesawat: {STRING}{}Kapasitas: {CARGO_LONG}, {CARGO_LONG}{}Biaya operasi: {CURRENCY_LONG}/thn STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Biaya: {CURRENCY_LONG} Kec. Max.: {VELOCITY}{}Jenis pesawat: {STRING}{}Kapasitas: {CARGO_LONG}{}Biaya operasi: {CURRENCY_LONG}/thn @@ -4197,12 +4233,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Berat: { STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Berat: {LTBLUE}{WEIGHT_SHORT} {BLACK}Tenaga: {LTBLUE}{POWER}{BLACK} Kec. Max: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Keuntungan tahun ini: {LTBLUE}{CURRENCY_LONG} (tahun lalu: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Keuntungan tahun ini: {LTBLUE}{CURRENCY_LONG} (tahun kemarin: {CURRENCY_LONG}) {BLACK}Performa minimum: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Reliabilitas: {LTBLUE}{COMMA}% {BLACK}Mogok sejak perbaikan terakhir : {LTBLUE}{COMMA} kali STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Dibuat: {LTBLUE}{NUM}{BLACK} Nilai: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Kapasitas: {LTBLUE}Tidak ada{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Daya Muat: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Daya Muat: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapasitas: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Daya Muat: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Daya Muat: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Nilai Transfer: {LTBLUE}{CURRENCY_LONG} @@ -4468,25 +4505,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Jadwal m STR_TIMETABLE_STATUS_START_AT :{BLACK}Jadwal ini akan dimulai pada {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Tanggal mulai -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Pilih sebarang hari sebagai titik mula timetable. Ctrl+Click akan men-set titik awal timetable dan akan menyebarkan semua kendaraan yang berorder sama secara merata berdasarkan order relatif, jika order tersebut sepenuhnya terjadwalkan. +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Pilih tanggal titik mula timetable. Ctrl+Click untuk mendistribusikan semua kendaraan dengan instruksi sama secara merata dari tanggal yang telah dipilih berdasarkan instruksi relatif tiap kendaraan, hanya jika intruksi tersebut sepenuhnya terjadwal. STR_TIMETABLE_CHANGE_TIME :{BLACK}Ubah Durasi -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Ubah jumlah waktu yang seharusnya dibutuhkan, pada tujuan yang terpilih +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Ubah jumlah waktu yang seharusnya dibutuhkan, pada tujuan yang terpilih. Ctrl+Click untuk mengubah keseluruhan tujuan STR_TIMETABLE_CLEAR_TIME :{BLACK}Hapus waktu -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Hapus jumlah waktu pada tujuan yang terpilih +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Hapus jumlah waktu pada tujuan yang terpilih. Ctrl+Click untuk menghapus keseluruan tujuan STR_TIMETABLE_CHANGE_SPEED :{BLACK}Ubah batas kecepatan -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Ubah batas kecepatan maks. pada tujuan terpilih +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Ubah batas kecepatan maks pada tujuan terpilih. Ctrl+Click mengeset kecepatan di seluruh pilihan STR_TIMETABLE_CLEAR_SPEED :{BLACK}Hapus batas kecepatan -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Hapus batas kecepatan maks. pada tujuan terpilih +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Hapus batas kecepatan maks pada tujuan terpilih. Ctrl+Click mengeset kecepatan di seluruh pilihan STR_TIMETABLE_RESET_LATENESS :{BLACK}Reset STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Kembalikan penghitung waktu keterlambatan seperti semula, sehingga kendaraan akan selalu tepat waktu STR_TIMETABLE_AUTOFILL :{BLACK}Otomatis -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Isi jadwal keberangkatan secara otomatis dari perjalanan berikutnya (Ctrl-klik agar waktu tinggalnya tetap) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Isi jadwal keberangkatan secara otomatis berdasarkan perjalanan berikutnya. Ctrl+klik untuk mempertahankan waktu tunggu) STR_TIMETABLE_EXPECTED :{BLACK}Harapan STR_TIMETABLE_SCHEDULED :{BLACK}Dijadwalkan @@ -4530,12 +4567,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Salah sa STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Jendela "Debug" skrip AI hanya tersedia untuk server # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Konfigurasi AI +STR_AI_CONFIG_CAPTION_AI :{WHITE}Konfigurasi AI +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Konfigurasi Game Script STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Skrip Permainan yang akan di jalankan di permainan berikutnya STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AI yg akan dijalankan pada permainan berikutnya STR_AI_CONFIG_HUMAN_PLAYER :Pemain Manusia STR_AI_CONFIG_RANDOM_AI :AI Acak STR_AI_CONFIG_NONE :(tidak ada) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Jumlah pesaing maksimal: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Naikkan STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Naikkan AI terpilih dalam daftar @@ -4543,12 +4582,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Turunkan STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Turunkan AI terpilih dalam daftar STR_AI_CONFIG_GAMESCRIPT :{SILVER}Skrip Permainan +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parameter STR_AI_CONFIG_AI :{SILVER}AI -STR_AI_CONFIG_CHANGE :{BLACK}Pilih {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Skrip Permainan +STR_AI_CONFIG_CHANGE_AI :{BLACK}Pilih AI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Skrip Permainan STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Muat skrip yang lain STR_AI_CONFIG_CONFIGURE :{BLACK}Konfigurasikan STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Mengkonfigurasi parameter skrip AI @@ -4576,10 +4614,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK} Tangkap STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Tangkapan layar Peta Ketinggian STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Tangkapan layar minimap -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameter -STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Skrip Permainan +# Script Parameters +STR_AI_SETTINGS_CAPTION_AI :{WHITE}Parameter AI STR_AI_SETTINGS_CLOSE :{BLACK}Tutup STR_AI_SETTINGS_RESET :{BLACK}Reset STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4743,6 +4779,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... terl STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Tidak dapat membangkitkan/membuat industri... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Tidak dapat membangun {STRING} disini... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Tidak dapat membangun industri ini disini... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Tidak mampu memprospek industri... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... terlalu dekat dengan industri lain STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... harus membangun kota terlebih dahulu STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... hanya diizinkan satu di setiap kota @@ -4757,6 +4794,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... huta STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... hanya bisa dibangun diatas garis salju STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... hanya dapat dibangun di bawah batas salju +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Rencana pendanaan mengalami kegagalan; mohon dicoba kembali +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE} Tidak ada tempat yang tepat untuk memprospek industri ini STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Tidak ada tempat yang sesuai untuk industri '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Ubah pembuatan peta untuk memperoleh peta yang lebih baik @@ -4924,6 +4963,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}terhalan STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... terhalang kantor pusat perusahaan STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Tidak dapat membeli area ini STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... anda sudah memilikinya! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... batas konstruksi objek telah tercapai # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Tidak data membuat kelompok... @@ -4996,6 +5036,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Tidak da STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... kendaraan hancur +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... tidak semua kendaraan identik + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Tak satupun kendaraan tersedia STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Tukarkan konfigurasi NewGRF anda STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Belum ada kendaraan yang tersedia saat ini @@ -5022,6 +5064,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Tidak da STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... kendaraan tidak dapat menuju ke semua stasiun STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... kendaraan tidak dapat menuju ke stasiun tersebut STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... kendaraan yang berbagi tujuan yang sama tidak dapat menuju stasiun tersebut +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... Tidak semua kendaraan memiliki urutan yang sama +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... tidak semua kendaraan akan berbagi urutan. STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Tidak dapat berbagi perintah... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Tidak dapat menghentikan pembagian daftar perintah... @@ -5029,6 +5073,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Tidak da STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... terlalu jauh dari tujuan sebelumnya STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... pesawat tidak dapat menjangkau +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Tidak dapat membuat jadwal keberangkatan kendaraan... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Kendaran hanya dapat menunggu di stasiun diff --git a/src/lang/irish.txt b/src/lang/irish.txt index 4b155192bb501..2cb09f69eeb61 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -200,6 +200,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}hp STR_UNITS_POWER_METRIC :{COMMA}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -391,10 +392,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Scoir # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Roghanna an chluiche STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Socruithe -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Socruithe AI/Scripteanna cluiche STR_SETTINGS_MENU_NEWGRF_SETTINGS :Socruithe NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Roghanna trédhearcachta STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Taispeántar ainmneacha bailte @@ -965,36 +965,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rúipí na hInd STR_GAME_OPTIONS_CURRENCY_IDR :Rupiah na hIndinéise (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit na Malaeisia (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Tiomáin ar chlé -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Tiomáin ar dheis - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Ainmneacha na mbailte: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Roghnaigh stíl d'ainmneacha na mbailte - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Béarla (Bunaidh) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Fraincis -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Gearmáinis -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Béarla (Breise) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Meiriceá Laidineach -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Áiféiseach -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Sualainnis -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Ollainnis -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Fionlainnis -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polainnis -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slováicis -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Ioruais -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungárach -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Ostarach -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rómánach -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Seiceach -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Eilvéiseach -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danmhargach -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turcach -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Iodálach -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalónach - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Uathshábháil STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Roghnaigh eatramh idir uathshábhálacha an chluiche @@ -1026,21 +996,8 @@ STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Cuir tic sa bhosca seo chun v-shioncronú (v-sync) a úsáid ar an scáileán. Má athraítear an socrú seo, ní chuirfear i bhfeidhm é ach tar éis an cluiche a atosú. Ní oibríonn seo ach amháin má tá luasghéarú crua-earraí cumasaithe -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Méid an chomhéadain -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Roghnaigh méid na heiliminte comhéadain a úsáidfear -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(uath-aimsiú) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Gnáth -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Méid dúbailte -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Méid 4x -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Méid na clófhoirne -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Roghnaigh méid na clófhoirne don chomhéadan a úsáidfear - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(uath-aimsiú) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Gnáthmhéid -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Méid dúbailte -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :4x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafaicí @@ -1092,8 +1049,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Réamha STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Punt (£) i d'airgeadra STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Athraigh paraiméadar d'airgeadra saincheaptha -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Uaslíon na n-iomaitheoirí: {ORANGE}{COMMA} - STR_NONE :Ceann ar bith STR_FUNDING_ONLY :Maoiniú amháin STR_MINIMAL :Íosmhéid @@ -1143,6 +1098,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Tírdhreach measartha +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Tírdhreach fo-artach +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Tírdhreach fo-theochriosach +STR_CLIMATE_TOYLAND_LANDSCAPE :Tírdhreach thír na mbréagán + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :An-réidh STR_TERRAIN_TYPE_FLAT :Réidh @@ -1221,6 +1182,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Ar dheis STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Iasacht tosaigh uasta: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Uasmhéid is féidir le cuideachta a chur ar iasacht (gan boilsciú a chur san áireamh) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Ráta úis: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Ráta úis ar iasachtaí; rialaíonn sé seo boilsciú freisin, má tá sé cumasaithe @@ -1499,6 +1461,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Feabhsaithe STR_CONFIG_SETTING_ROAD_SIDE :Feithiclí bóthair: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Roghnaigh taobh na tiomána +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Tiomáin ar chlé +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Tiomáin ar dheis + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rothlú an mhapa airde: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Tuathal @@ -2022,7 +1988,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Aisiompú uatho STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Ceadaigh do thraenacha aisiompú ag comhartha, más rud é go raibh siad ag fanacht ann píosa fada ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Molta) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Molta) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Athraigh luach an tsocraithe @@ -2065,7 +2031,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Tábla n STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Socruithe STR_INTRO_NEWGRF_SETTINGS :{BLACK}Socruithe NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Seiceáil Inneachar Ar Líne -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Socruithe AI/Script Cluiche STR_INTRO_QUIT :{BLACK}Scoir STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Tosaigh cluiche nua. Scipeáltar cumrú an léarscáil le Ctrl+Cliceáil @@ -2085,7 +2050,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Taispeá STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Socruithe taispeána STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Taispeáin socruithe NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Seiceáil le haghaidh inneachar nua agus nuashonruithe le híoslódáil -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Taispeáin socruithe AI/Script cluiche STR_INTRO_TOOLTIP_QUIT :{BLACK}Téigh amach as 'OpenTTD' STR_INTRO_BASESET :{BLACK}Tá {NUM} sprít in easnamh sa bhuntacar grafaicí. Seiceáil an bhfuil nuashonruithe ar fáil don bhuntacar. @@ -2117,12 +2081,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Athraig STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Athraigh an bhliain reatha STR_CHEAT_SETUP_PROD :{LTBLUE}Cumasaigh luachanna táirgeachta a athrú: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Tírdhreach measartha -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Tírdhreach fo-artach -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Tírdhreach fo-theochriosach -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Tírdhreach thír na mbréagán - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Scéim Dathanna @@ -2355,7 +2313,6 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Cuideachta nua STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Cruthaigh cuideachta nua agus téigh isteach ann STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Seo tusa STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Is é seo óstach an chluiche -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} {P ch ch ch gc c}liant / {NUM} {P ch ch ch gc c}uideachta # Matches ConnectionType ###length 5 @@ -2602,6 +2559,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}ar maos STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}thar acmhainn +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Aibhsigh an limistéar clúdaigh STR_STATION_BUILD_COVERAGE_OFF :{BLACK}As @@ -2691,8 +2650,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Méadaig STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Roghnaigh Droichead Iarnróid STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Roghnaigh Droichead Bóthair STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Droichead a roghnú - cliceáil ar an droichead is rogha leat chun é a thógáil -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Crochta, Cruach STR_BRIDGE_NAME_GIRDER_STEEL :Cearchaill, Cruach STR_BRIDGE_NAME_CANTILEVER_STEEL :Starrmhaide, Cruach @@ -3121,6 +3078,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Méid na STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Roghnaigh an méid de na léarscáile i tíleanna. Beidh líon na tíleanna ar fáil a bheith beagán níos lú STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Líon na mbailte: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Ainmneacha na mbailte: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Roghnaigh stíl d'ainmneacha na mbailte STR_MAPGEN_DATE :{BLACK}Dáta: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Líon na dtionscal: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}An beann is airde: @@ -3134,14 +3093,36 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Clúdach STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Méadaigh clúdach an fhásaigh deich faoin gcéad STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Laghdaigh clúdach an fhásaigh deich faoin gcéad STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Talamh a chruthú: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Cineál tír-raoin: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Leibhéal na farraige: +STR_MAPGEN_SEA_LEVEL :{BLACK}Leibhéal na farraige: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Aibhneacha: STR_MAPGEN_SMOOTHNESS :{BLACK}Míne: STR_MAPGEN_VARIETY :{BLACK}Éagsúlacht: STR_MAPGEN_GENERATE :{WHITE}Cruthaigh +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Béarla (Bunaidh) +STR_MAPGEN_TOWN_NAME_FRENCH :Fraincis +STR_MAPGEN_TOWN_NAME_GERMAN :Gearmáinis +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Béarla (Breise) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Meiriceá Laidineach +STR_MAPGEN_TOWN_NAME_SILLY :Áiféiseach +STR_MAPGEN_TOWN_NAME_SWEDISH :Sualainnis +STR_MAPGEN_TOWN_NAME_DUTCH :Ollainnis +STR_MAPGEN_TOWN_NAME_FINNISH :Fionlainnis +STR_MAPGEN_TOWN_NAME_POLISH :Polainnis +STR_MAPGEN_TOWN_NAME_SLOVAK :Slováicis +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Ioruais +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungárach +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Ostarach +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rómánach +STR_MAPGEN_TOWN_NAME_CZECH :Seiceach +STR_MAPGEN_TOWN_NAME_SWISS :Eilvéiseach +STR_MAPGEN_TOWN_NAME_DANISH :Danmhargach +STR_MAPGEN_TOWN_NAME_TURKISH :Turcach +STR_MAPGEN_TOWN_NAME_ITALIAN :Iodálach +STR_MAPGEN_TOWN_NAME_CATALAN :Catalónach + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Taobhanna na léarscáile: STR_MAPGEN_NORTHWEST :{BLACK}Iarthuaisceart @@ -3286,6 +3267,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Sprite r STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Téigh ar aghaigh chuig an gnáth-sprite roimhe, ag scipeáil thar aon bhréag-sprite nó sprite athdathaithe/clófhoirne agus ag timfhilleadh ag an tús STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Léiriú den sprite atá roghnaithe faoi láthair. Déantar neamhaird den ailíniú agus an sprite seo á tharraingt STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Bog an sprid timpeall, ag athrú an seach-chur X agus Y. Ctrl+Cliceáil chun an sprid a bhogadh ocht n-aonad ag an am céanna + +###length 2 + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Athshocraigh coibhneasta STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Athshocraigh na seach-chuir choibhneasta reatha STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Seach-chur X: {NUM}, Seach-chur Y: {NUM} (Dearbh-shuíomh) @@ -3300,8 +3285,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Rabhadh: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Earráid: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Marfach: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Tharla earráid mharfach NewGRF:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Tharla earráid NewGRF:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :Ní oibreoidh {1:STRING} leis an leagan de TTDPatch a thuairiscigh OpenTTD. STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING}: Is don leagan {STRING} de TTD é STR_NEWGRF_ERROR_UNSET_SWITCH :Tá {1:STRING} deartha le húsáid le {STRING} @@ -3841,6 +3824,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Iarracht STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Raon: {GOLD}{COMMA} tíl STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Cineál aerárthaigh: {GOLD}{STRING} +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Liosta chun feithicil traenach a roghnú - cliceáil ar fheithicil le faisnéis a fháil STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Liosta chun feithicil bóthair a roghnú - cliceáil ar fheithicil le faisnéis a fháil @@ -4501,12 +4486,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Thuairte STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Níl an fhuinneog Dífhabhtú AI ar fáil ach don fhreastalaí amháin # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Cumrú AI STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}An Script Cluiche a lódálfar sa chéad chluiche eile STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Na AInna a lódálfar sa chéad chluiche eile STR_AI_CONFIG_HUMAN_PLAYER :Imreoir Daonna STR_AI_CONFIG_RANDOM_AI :AI Randamach STR_AI_CONFIG_NONE :(ceann ar bith) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Uaslíon na n-iomaitheoirí: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Bog Suas STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Bog an AI roghnaithe suas an liosta @@ -4516,8 +4501,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Bog an A STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script Cluiche STR_AI_CONFIG_AI :{SILVER}AInna -STR_AI_CONFIG_CHANGE :{BLACK}Roghnaigh {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :AI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script Cluiche STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Lódáil script eile @@ -4547,10 +4530,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Seat sc STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Seat scáileáin den mhapa airde STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Seat scáileáin den mhion-léarscáil -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}Paraiméadair {STRING} +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script an Chluiche STR_AI_SETTINGS_CLOSE :{BLACK}Dún STR_AI_SETTINGS_RESET :{BLACK}Athshocraigh STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4967,6 +4948,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Ní féi STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... tá an fheithicil scriosta + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Ní bheidh aon fheithicil ar fáil ar chor ar bith STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Athraigh do chumraíocht NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Níl aon fheithicil ar fáil fós @@ -5000,6 +4982,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Ní féi STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... rófhada ón gceann scríbe roimhe seo STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... níl raon fada go leor ag an aerárthach +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Ní féidir amchlár a thabhairt d'fheithicil... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Ní féidir le feithiclí fanacht ach ag stáisiúin. diff --git a/src/lang/italian.txt b/src/lang/italian.txt index d5880c7fd66a9..f8ef6cc384335 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -202,6 +202,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -228,8 +238,8 @@ STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Filtro: -STR_LIST_FILTER_OSKTITLE :{BLACK}Inserire il filtro -STR_LIST_FILTER_TOOLTIP :{BLACK}Inserire una parola da utilizzare per filtrare la lista +STR_LIST_FILTER_OSKTITLE :{BLACK}Immettere una o più parole chiave per filtrare dall'elenco +STR_LIST_FILTER_TOOLTIP :{BLACK}Immettere una o più parole chiave per filtrare dall'elenco STR_TOOLTIP_GROUP_ORDER :{BLACK}Seleziona il criterio di raggruppamento STR_TOOLTIP_SORT_ORDER :{BLACK}Seleziona l'ordinamento (decrescente/crescente) @@ -378,9 +388,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Generazi STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Generazione industrie STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Costruzione strade STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Costruzione tranvie -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Pianta alberi. MAIUSC alterna fra costruzione e stima dei costi +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Piantare alberi. Ctrl seleziona l'area in diagonale. "Maiuscolo" alterna la costruzione/visualizzazione della stima dei costi. STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Posiziona cartello -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Posiziona oggetto. MAIUSC alterna fra costruzione e stima dei costi +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Posizionare l'oggetto. Ctrl seleziona l'area in diagonale. Maiuscole alterna la costruzione/visualizzazione della stima dei costi. # Scenario editor file menu ###length 7 @@ -393,10 +403,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Esci # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Opzioni gioco STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Impostazioni -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Impostazioni IA e Script +STR_SETTINGS_MENU_AI_SETTINGS :Impostazioni IA +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Impostazioni script di gioco STR_SETTINGS_MENU_NEWGRF_SETTINGS :Impostazioni NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opzioni trasparenza STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Mostra nomi città @@ -967,36 +978,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rupia indiana ( STR_GAME_OPTIONS_CURRENCY_IDR :Rupia indonesiana (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit malaysiano (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Guida a sinistra -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Guida a destra - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nomi città: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Seleziona lo stile per i nomi delle città - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Inglesi (originali) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francesi -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Tedeschi -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Inglesi (aggiuntivi) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latino-americani -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Sciocchi -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Svedesi -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Olandesi -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandesi -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polacchi -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovacchi -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norvegesi -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungheresi -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austriaci -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumeni -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Cechi -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Svizzeri -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danesi -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turchi -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiani -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalani - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Salvataggi automatici STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Seleziona l'intervallo fra i salvataggi automatici della partita @@ -1029,21 +1010,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Selezion STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Driver attuale: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Dimensione interfaccia -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Seleziona la dimensione deglie elementi dell'interfaccia grafica +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Dimensione dell'interfaccia +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Trascinare il cursore per impostare le dimensioni dell'interfaccia. Tenere premuto Ctrl per una regolazione permanente +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Rileva automaticamente le dimensioni +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Seleziona questa casella per rilevare automaticamente le dimensioni dell'interfaccia -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(rileva automaticamente) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normale -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Doppia -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quadrupla +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Scala smussature +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Seleziona questa casella per ridimensionare le smussature in base alle dimensioni dell'interfaccia -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Dimensione caratteri -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Seleziona la dimensione dei caratteri dell'interfaccia - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(rileva automaticamente) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normale -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Doppia -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quadrupla +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafica @@ -1095,8 +1074,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Antepri STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}L'equivalente di 10.000 Sterline (£) nella valuta STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Cambia i parametri della valuta personalizzata -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Numero massimo di avversari: {ORANGE}{COMMA} - STR_NONE :Nessuno STR_FUNDING_ONLY :Solo finanziate STR_MINIMAL :Minimo @@ -1158,6 +1135,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Paesaggio "temperato" +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Paesaggio "subartico" +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Paesaggio "subtropicale" +STR_CLIMATE_TOYLAND_LANDSCAPE :Paesaggio 'città dei giocattoli' + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Molto pianeggiante STR_TERRAIN_TYPE_FLAT :Pianeggiante @@ -1258,6 +1241,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Destra STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Prestito massimo iniziale: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Ammontare massimo di denaro che una compagnia può chiedere in prestito (senza tenere conto dell'inflazione). +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Nessun prestito {RED}Richiede script di gioco per fornire i fondi iniziali STR_CONFIG_SETTING_INTEREST_RATE :Tasso d'interesse: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Tasso d'interesse sul prestito; controlla anche l'abilitazione dell'inflazione. @@ -1484,6 +1470,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Larghezza delle STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Mostra il nome dei NewGRF nella finestra di costruzione dei veicoli: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Viene aggiunta una riga di testo alla finestra di costruzione dei veicoli, che specifica da quale NewGRF proviene il veicolo selezionato. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Mostrare i carichi che i veicoli possono trasportare nella finestra dell'elenco veicoli. {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Se abilitato, il carico trasportabile dal veicolo apparirà sopra di esso nell'elenco dei veicoli della compagnia. STR_CONFIG_SETTING_LANDSCAPE :Paesaggio: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :I paesaggi definiscono scenari predefiniti di gioco. Differiscono per i carichi disponibili e per i requisiti di crescita delle città. Tuttavia NewGRF e Script offrono possibilità di controllo più fine su questi aspetti. @@ -1538,6 +1526,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Migliorato STR_CONFIG_SETTING_ROAD_SIDE :Automezzi: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Seleziona il lato di guida. +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Guida a sinistra +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Guida a destra + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotazione heightmap: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Antioraria @@ -1973,9 +1965,9 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tempo impiegato STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modalità di distribuzione dei passeggeri: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :In modalità "Simmetrica" il numero di passeggeri che viaggiano da una stazione A ad una stazione B è approssimativamente lo stesso di quelli che viaggiano da B ad A. In modalità "Asimmetrica" è consentito il viaggio di un numero di passeggeri arbitrario in entrambe le direzioni. In modalità "Manuale" non viene effettuata alcuna distribuzione automatica dei passeggeri. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Modalità di distribuzione della posta: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :In modalità "Simmetrica" la quantità di posta spedita da una stazione A ad una stazione B è approssimativamente la stessa di quella spedita da B ad A. In modalità "Asimmetrica" è consentita la spedizione di quantità di posta arbitrarie in entrambe le direzioni. In modalità "Manuale" non viene effettuata alcuna distribuzione automatica della posta. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :In modalità "Simmetrica" la quantità di posta spedita da una stazione A ad una stazione B è approssimativamente la stessa di quella spedita da B ad A. In modalità "Asimmetrica" è possibile spedire quantità di posta arbitrarie in entrambe le direzioni. In modalità "Manuale" non viene effettuata alcuna distribuzione automatica della posta. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Modalità di distribuzione dei carichi della classe ARMOURED: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La classe di carico ARMOURED comprende i Valori nel clima temperato, i Diamanti nel clima subtropicale e l'Oro nel clima subartico. I NewGRF possono modificare questa impostazione. In modalità "Simmetrica" la quantità di carico inviata da una stazione A ad una stazione B è approssimativamente la stessa di quella inviata da B ad A. In modalità "Asimmetrica" è consentito l'invio di quantità di carico arbitrarie in entrambe le direzioni. In modalità "Manuale" non viene effettuata alcuna distribuzione automatica dei carichi interessati. Si raccomanda di impostare su "Asimmetrica" o "Manuale" per le partite nel clima subartico, in quanto le banche non restituiscono Oro alle miniere. Per i climi temperato e subtropicale è possibile scegliere "Simmetrica" poiché le banche restituiscono un carico di valori equivalente a quello ricevuto dalla banca di origine. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La classe di carico ARMOURED comprende i Valori nel clima temperato, i Diamanti nel clima subtropicale e l'Oro nel clima subartico. I NewGRF possono modificare questa impostazione. In modalità "Simmetrica" la quantità di carico inviata da una stazione A ad una stazione B è approssimativamente la stessa di quella inviata da B ad A. In modalità "Asimmetrica" quantità arbitrarie di quel carico possono essere inviate in entrambe le direzioni. In modalità "Manuale" non viene effettuata alcuna distribuzione automatica dei carichi interessati. Si raccomanda di impostare su "Asimmetrica" o "Manuale" per le partite nel clima subartico e subtropicale, in quanto le banche non restituiscono Oro alle miniere. Per il clima temperato è possibile impostare "Simmetrica" poiché le banche restituiscono un carico di valori equivalente a quello ricevuto dalla banca di origine. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modalità di distribuzione dei carichi delle altre classi: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :In modalità "Asimmetrica" è consentito l'invio di quantità di carico arbitrarie in entrambe le direzioni. In modalità "Manuale" non viene effettuata alcuna distribuzione automatica dei carichi interessati. ###length 3 @@ -2072,7 +2064,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Inversione auto STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Consente ai treni di invertire la marcia dopo aver atteso a lungo a un segnale. ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(raccomandato) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(raccomandato) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Cambia impostazione @@ -2115,7 +2107,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Punteggi STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Impostazioni STR_INTRO_NEWGRF_SETTINGS :{BLACK}Impostazioni NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Contenuti online -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Impostazioni IA e Script +STR_INTRO_AI_SETTINGS :{BLACK}Impostazioni IA +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Impostazioni script di gioco STR_INTRO_QUIT :{BLACK}Esci STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Inizia una nuova partita. CTRL salta la configurazione della mappa. @@ -2135,7 +2128,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Mostra l STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Mostra le impostazioni STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Mostra le impostazioni NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Controlla la disponibilità di contenuti nuovi o aggiornati da scaricare -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Mostra le impostazioni delle IA e degli Script +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Mostra impostazioni IA +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Visualizza le impostazioni dello script di gioco STR_INTRO_TOOLTIP_QUIT :{BLACK}Esci da OpenTTD STR_INTRO_BASESET :{BLACK}Nel pacchetto grafico di base attualmente selezionato mancano {NUM} sprite. È consigliabile controllare gli aggiornamenti del pacchetto. @@ -2167,12 +2161,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Cambia STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Cambia l'anno corrente STR_CHEAT_SETUP_PROD :{LTBLUE}Permetti la modifica dei valori di produzione: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Paesaggio "temperato" -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Paesaggio "subartico" -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Paesaggio "subtropicale" -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Paesaggio 'città dei giocattoli' - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Schema colori @@ -2405,7 +2393,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nuova compagni STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Crea una nuova compagnia e controllala STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Questo sei tu STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Questo è l'host del gioco -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} / {NUM} compan{P y ies} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} client{P "" s} - {NUM}/{NUM} compagni{P a e} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Il numero di client attualmente connessi, il numero di compagnie e il numero massimo di compagnie consentito dall'amministratore del server. # Matches ConnectionType ###length 5 @@ -2532,13 +2521,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :in attesa di ag STR_NETWORK_MESSAGE_CLIENT_LEAVING :abbandono della partita STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} è entrato nella partita -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} è entrato nella partita (Client #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} ha iniziato a controllare la compagnia #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} è entrato nella partita (Client #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} è entrato a far parte della compagnia #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} è diventato spettatore -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} ha avviato una nuova compagnia (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} ha abbandonato la partita ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} ha fondato una nuova compagnia (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} ha abbandonato la partita ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} ha cambiato il loro nome in {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} ha dato {2:CURRENCY_LONG} a {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} ha dato {2:CURRENCY_LONG} a {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Il server ha chiuso la sessione STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Il server si sta riavviando...{}Attendere prego... STR_NETWORK_MESSAGE_KICKED :*** {STRING} è stato espulso. Motivo: ({STRING}) @@ -2654,6 +2643,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}satura STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}sovraccarica +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} da trasportare al mese da {STATION} a {STATION} ({COMMA}% di capacità){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} da trasportare indietro ({COMMA}% di capacità) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}tempo medio di percorrenza: {NUM}{NBSP}giorn{P "o" i} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Evidenzia area coperta STR_STATION_BUILD_COVERAGE_OFF :{BLACK}No @@ -2662,6 +2656,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Non evid STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Evidenzia l'area di copertura del sito proposto STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Accetta: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Fornisce: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Costi di manutenzione: {GOLD}{CURRENCY_SHORT}/anno # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Unisci stazione @@ -2748,8 +2743,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Aumenta STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Seleziona ponte ferroviario STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Seleziona ponte stradale STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Selezione ponte - fare clic sul ponte desiderato per costruirlo -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Sospeso, Acciaio STR_BRIDGE_NAME_GIRDER_STEEL :A travatura, Acciaio STR_BRIDGE_NAME_CANTILEVER_STEEL :A mensola, Acciaio @@ -2853,11 +2850,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Modellaz STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Abbassa un angolo di terreno. Trascinando, l'area selezionata viene livellata alla nuova quota del primo angolo. CTRL seleziona l'area diagonalmente. MAIUSC alterna fra costruzione e stima dei costi STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Alza un angolo di terreno. Trascinando, l'area selezionata viene livellata alla nuova quota del primo angolo. CTRL seleziona l'area diagonalmente. MAIUSC alterna fra costruzione e stima dei costi STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Livella un'area di terreno alla quota del primo angolo selezionato. CTRL seleziona l'area diagonalmente. MAIUSC alterna fra costruzione e stima dei costi -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Acquista terreno per usi futuri. MAIUSC alterna fra costruzione e stima dei costi +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Acquista terreno per usi futuri. Ctrl seleziona l'area in diagonale. MAIUSC alterna la costruzione/visualizzazione della stima dei costi. # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Selezione oggetto -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Seleziona l'oggetto da costruire. MAIUSC alterna fra costruzione e stima dei costi +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Seleziona l'oggetto da costruire. Ctrl seleziona l'area in diagonale. MAIUSC alterna la costruzione/visualizzazione della stima dei costi STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Seleziona la classe dell'oggetto da costruire STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Anteprima dell'oggetto STR_OBJECT_BUILD_SIZE :{BLACK}Dimensione: {GOLD}{NUM} x {NUM} caselle @@ -2869,7 +2866,7 @@ STR_OBJECT_CLASS_TRNS :Trasmettitori STR_PLANT_TREE_CAPTION :{WHITE}Alberi STR_PLANT_TREE_TOOLTIP :{BLACK}Seleziona il tipo di albero da piantare. Se nella casella sono già presenti alberi ne aggiunge altri di vari tipi, indipendentemente dal tipo selezionato STR_TREES_RANDOM_TYPE :{BLACK}Alberi casuali -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Pianta alberi di specie a caso. MAIUSC alterna fra costruzione e stima dei costi +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Pianta alberi di diversi tipi. Ctrl seleziona l'area in diagonale. "Maiuscole" alterna la costruzione/la visualizzazione della stima dei costi. STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Alberi casuali STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Pianta alberi casualmente nel paesaggio STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normale @@ -2901,6 +2898,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Città c STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Fonda una città in una posizione casuale STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Alcune città casuali STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Copre la mappa con città posizionate casualmente +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Espandi tutte le città +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Fa crescere leggermente tutte le città STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nome città: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Inserire il nome della città @@ -3179,6 +3178,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Area map STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Seleziona l'area della mappa espressa in caselle. Il numero effettivo di caselle disponibili sarà leggermente inferiore STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Numero città: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nomi città: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Seleziona lo stile per i nomi delle città STR_MAPGEN_DATE :{BLACK}Data: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Numero industrie: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Picco massimo: @@ -3192,13 +3193,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Aree des STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Aumenta la copertura del deserto del dieci percento STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Diminuisci la copertura del deserto del dieci percento STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Generatore: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tipo di terreno: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Livello di mare: +STR_MAPGEN_SEA_LEVEL :{BLACK}Livello di mare: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Fiumi: STR_MAPGEN_SMOOTHNESS :{BLACK}Levigatezza: STR_MAPGEN_VARIETY :{BLACK}Varietà del terreno: STR_MAPGEN_GENERATE :{WHITE}Genera +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Impostazioni NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Mostra impostazioni NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Impostazioni IA +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Mostra impostazioni IA +STR_MAPGEN_GS_SETTINGS :{BLACK}Impostazioni script di gioco +STR_MAPGEN_GS_SETTINGS_TOOLTIP :BLACK}Visualizza le impostazioni dello script di gioco + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Inglesi (originali) +STR_MAPGEN_TOWN_NAME_FRENCH :Francesi +STR_MAPGEN_TOWN_NAME_GERMAN :Tedeschi +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Inglesi (aggiuntivi) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latino-americani +STR_MAPGEN_TOWN_NAME_SILLY :Sciocchi +STR_MAPGEN_TOWN_NAME_SWEDISH :Svedesi +STR_MAPGEN_TOWN_NAME_DUTCH :Olandesi +STR_MAPGEN_TOWN_NAME_FINNISH :Finlandesi +STR_MAPGEN_TOWN_NAME_POLISH :Polacchi +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovacchi +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norvegesi +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungheresi +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austriaci +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumeni +STR_MAPGEN_TOWN_NAME_CZECH :Cechi +STR_MAPGEN_TOWN_NAME_SWISS :Svizzeri +STR_MAPGEN_TOWN_NAME_DANISH :Danesi +STR_MAPGEN_TOWN_NAME_TURKISH :Turchi +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiani +STR_MAPGEN_TOWN_NAME_CATALAN :Catalani # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Bordi della mappa: @@ -3344,6 +3373,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Preceden STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Procede al precedente sprite normale, saltanto qualsiasi sprite speciale, di ricoloramento o carattere e tornando all'ultimo se viene raggiunto il primo della lista STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Rappresentazione dello sprite corrente. L'allineamento viene ignorato in questa casella. STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Sposta lo sprite, cambiando gli spiazzamenti X e Y. CTRL+clic sposta lo sprite di otto unità alla volta + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Spiazzamento del centro +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centrato + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Mirino + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Reimposta posizione relativa STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Reimposta gli spiazzamenti relativi attuali STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Posizione X: {NUM}, Y: {NUM} (assoluto) @@ -3358,18 +3394,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Attenzione: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Errore: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Errore irreversibile: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Si è verificato un errore irreversibile nel NewGRF:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Si è verificato un errore in un NewGRF:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}La NewGRF "{STRING}" ha restituito un errore irreversibile:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}La NewGRF "{STRING}" ha restituito un errore:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} non funziona con la versione di TTDPatch riferita da OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} è per la versione {STRING} di TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} è progettato per essere usato con {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Parametro non valido per {1:STRING}: parametro {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} deve essere caricato prima di {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} deve essere caricato dopo {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} richiede OpenTTD versione {STRING} o superiore +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} è per la versione {2:STRING} di TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} è progettato per essere usato con {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Parametro non valido per {1:STRING}: parametro {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} deve essere caricato prima di {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} deve essere caricato dopo {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} richiede la versione {2:STRING} o superiore di OpenTTD STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :il file GRF che era progettato per tradurre STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Troppi NewGRF caricati -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Caricare {1:STRING} come NewGRF statico insieme a {STRING} può causare errori di sincronizzazione +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Caricare {1:STRING} come NewGRF statico insieme a {2:STRING} può causare errori di sincronizzazione STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Sprite inatteso (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Proprietà {4:HEX} sconosciuta per l'azione 0 (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Tentativo di utilizzare un ID non valido (sprite {3:NUM}) @@ -3501,14 +3537,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Acquista esclus STR_LOCAL_AUTHORITY_ACTION_BRIBE :Corrompi l'autorità locale ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Inizia una piccola campagna pubblicitaria, per attirare più passeggeri e merci ai servizi di trasporto della compagnia.{}Fornisce un aumento temporaneo della valutazione delle stazioni in un piccolo raggio dal centro della città.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Inizia una campagna pubblicitaria moderata, per attirare più passeggeri e merci ai servizi di trasporto della compagnia.{}Fornisce un aumento temporaneo della valutazione delle stazioni in un moderato raggio dal centro della città.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Inizia una grande campagna pubblicitaria locale, per attirare più passeggeri e merci ai servizi di trasporto della compagnia.{}Fornisce un aumento temporaneo della valutazione delle stazioni in un grande raggio dal centro della città.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Finanzia la ricostruzione della rete stradale cittadina.{}Causa un considerevole disagio al traffico stradale per 6 mesi.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Costruisci una statua in onore della compagnia.{}Fornisce un aumento permanente della valutazione delle stazioni in questa città.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Finanzia la costruzione di nuovi edifici nella città.{}Fornisce un aumento temporaneo della crescita della città.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Acquista un anno di diritti di trasporto esclusivi in città. L'autorità cittadina non permetterà a passeggeri e merci di usare le stazioni dei tuoi avversari.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Corrompi l'autorità locale per aumentare la tua valutazione, con il rischio di una severa multa se scoperto.{}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniziate una piccola campagna pubblicitaria locale per attirare più passeggeri e merci sui vostri servizi di trasporto..{}Fornisce un incremento temporane alla valutazione delle stazioni in un piccolo raggio intorno al centro città..{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Avvia una campagna pubblicitaria a livello locale per attirare un maggior numero di passeggeri e merci sui vostri servizi di trasporto..{}Fornisce un incremento temporaneo alla valutazione delle stazioni in un raggio medio intorno al centro città..{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Avvia una vasta campagna pubblicitaria locale, per attirare più passeggeri e merci sui vostri servizi di trasporto.{}Fornisce un incremento temporaneo alla valutazione delle stazioni in un ampio raggio intorno al centro città..{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Finanziare la ricostruzione della rete stradale urbana.{}Provoca notevoli disagi al traffico stradale per un periodo fino a 6 mesi.{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Costruite una statua in onore della vostra compagnia.{}Fornisce un aumento permanente della valutazione della stazione in questa città..{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Finanziare la costruzione di nuovi edifici in città.{}Fornisce un incremento temporaneo alla crescita di questa città.{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Acquistate 1 anno di diritti esclusivi di trasporto in città..{}Le autorità cittadine non permetteranno a passeggeri e merci di utilizzare le stazioni dei vostri concorrenti..{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Corrompere l'autorità locale per aumentare la valutazione, con il rischio di una severa sanzione se si viene scoperti.{}{POP_COLOUR}Costo: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}Obiettivi della {COMPANY} @@ -3678,18 +3714,21 @@ STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Treni STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}Automezzi STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Aeromobili STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Navi -STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Interessi sul prestito +STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Int. sul prestito STR_FINANCES_SECTION_OTHER :{GOLD}Altro +STR_FINANCES_TOTAL_CAPTION :{WHITE}Totale STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Profitto netto +STR_FINANCES_PROFIT :{WHITE}Profitto STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Saldo bancario STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Capitale netto STR_FINANCES_LOAN_TITLE :{WHITE}Prestito STR_FINANCES_INTEREST_RATE :{WHITE}Interesse sul prestito: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Prestito massimo: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Chiedi in prestito {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Aumenta l'ammontare del prestito, CTRL+clic chiede in prestito il più possibile STR_FINANCES_REPAY_BUTTON :{BLACK}Ripaga {CURRENCY_LONG} @@ -3790,7 +3829,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produce: STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Richiede: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} in attesa{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Cambia produzione (multiplo di 8, fino a 2040) @@ -3820,6 +3859,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Invia is STR_VEHICLE_LIST_REPLACE_VEHICLES :Rimpiazza veicoli STR_VEHICLE_LIST_SEND_FOR_SERVICING :Manutenzione STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Profitto quest'anno: {CURRENCY_LONG} (anno scorso: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Manda al deposito STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Manda al deposito @@ -3862,7 +3903,7 @@ STR_GROUP_REMOVE_ALL_VEHICLES :Rimuovi tutti i STR_GROUP_RENAME_CAPTION :{BLACK}Rinomina un gruppo -STR_GROUP_PROFIT_THIS_YEAR :Profitto di quest'anno: +STR_GROUP_PROFIT_THIS_YEAR :Profitto anno corrente: STR_GROUP_PROFIT_LAST_YEAR :Profitto dell'anno scorso: STR_GROUP_OCCUPANCY :Utilizzo corrente: STR_GROUP_OCCUPANCY_VALUE :{NUM}% @@ -3904,13 +3945,18 @@ STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacit STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagoni motorizzati: {GOLD}+{POWER}{BLACK} Peso: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Riadattabile per: {GOLD}{STRING} STR_PURCHASE_INFO_ALL_TYPES :Tutti i tipi di carico -STR_PURCHASE_INFO_NONE :Niente +STR_PURCHASE_INFO_NONE :Nessun carico STR_PURCHASE_INFO_ENGINES_ONLY :Solo locomotive STR_PURCHASE_INFO_ALL_BUT :Tutto tranne {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Sforzo di trazione massimo: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Autonomia: {GOLD}{COMMA} casell{P a e} STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipo di aeromobile: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Tutti i tipi di carico +STR_CARGO_TYPE_FILTER_FREIGHT :Merci +STR_CARGO_TYPE_FILTER_NONE :Nessun carico + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Elenco di selezione dei veicoli ferroviari - fare clic su un veicolo per informazioni. CTRL+clic mostra/nasconde il tipo di veicolo STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Elenco selezione automezzi - fare clic su un veicolo per informazioni. CTRL+clic mostra/nasconde il tipo di automezzo @@ -4079,7 +4125,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :{G=m}aeromobile STR_ENGINE_PREVIEW_SHIP :{G=f}nave STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Costo: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocità: {VELOCITY} Potenza: {POWER}{}Costo di esercizio: {CURRENCY_LONG}/anno{}Capacità: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Costo: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocità: {VELOCITY} Potenza: {POWER} S.T. max.: {6:FORCE}{}Costo di esercizio: {4:CURRENCY_LONG}/anno{}Capacità: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Costo: {0:CURRENCY_LONG} Peso: {1:WEIGHT_SHORT}{}Velocità: {2:VELOCITY} Potenza: {3:POWER} S.T. Max.: {6:FORCE}{}Costo di esercizio: {4:CURRENCY_LONG}/anno{}Capacità: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Costo: {CURRENCY_LONG} Velocità max.: {VELOCITY}{}Capacità: {CARGO_LONG}{}Costo di esercizio: {CURRENCY_LONG}/anno STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Costo: {CURRENCY_LONG} Velocità max.: {VELOCITY}{}Tipo aeromobile: {STRING}{}Capacità: {CARGO_LONG}, {CARGO_LONG}{}Costo di esercizio: {CURRENCY_LONG}/anno STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Costo: {CURRENCY_LONG} Velocità max.: {VELOCITY}{}Tipo aeromobile: {STRING}{}Capacità: {CARGO_LONG}{}Costo di esercizio: {CURRENCY_LONG}/anno @@ -4237,13 +4283,14 @@ STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}elocità STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potenza: {LTBLUE}{POWER}{BLACK} Velocità max.: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potenza: {LTBLUE}{POWER}{BLACK} Velocità max.: {LTBLUE}{VELOCITY} {BLACK}S.T. max.: {LTBLUE}{FORCE} -STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profitto quest'anno: {LTBLUE}{CURRENCY_LONG} (anno scorso: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profitto anno corrente: {LTBLUE}{CURRENCY_LONG} (anno scorso: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Profitti anno corrente: {LTBLUE}{CURRENCY_LONG} (anno scorso: {CURRENCY_LONG}) {BLACK}Prestazione minima: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Affidabilità: {LTBLUE}{COMMA}% {BLACK}Guasti dall'ultima manutenzione: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Costruito nel: {LTBLUE}{NUM}{BLACK} Valore: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacità: {LTBLUE}Nessuna{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacità: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacità: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacità: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacità: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacità: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Crediti di trasferimento: {LTBLUE}{CURRENCY_LONG} @@ -4512,22 +4559,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Data ini STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Seleziona una data come punto di partenza della tabella oraria. Ctrl+click distribuisce tutti i veicoli che condividono questo ordine in modo uniforme dalla data indicata in base al loro ordine relativo, se l'ordine è completamente programmato. STR_TIMETABLE_CHANGE_TIME :{BLACK}Cambia tempo -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Cambia la quantità di tempo che dovrebbe essere impiegata per l'ordine selezionato +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Cambia la quantità di tempo che dovrebbe essere impiegata per l'ordine selezionato. CTRL+clic imposta il tempo di tutti gli ordini STR_TIMETABLE_CLEAR_TIME :{BLACK}Elimina tempo -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Elimina l'impostazione della quantità di tempo per l'ordine selezionato +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Elimina l'impostazione della quantità di tempo per l'ordine selezionato. CTRL+clic la rimuove da tutti gli ordini STR_TIMETABLE_CHANGE_SPEED :{BLACK}Cambia limite di velocità -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Cambia l'impostazione del limite di velocità per l'ordine selezionato +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Cambia l'impostazione del limite di velocità per l'ordine selezionato. CTRL+clic lo imposta per tutti gli ordini STR_TIMETABLE_CLEAR_SPEED :{BLACK}Elimina limite di velocità -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Elimina l'impostazione del limite di velocità per l'ordine selezionato +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Elimina l'impostazione del limite di velocità per l'ordine selezionato. CTRL+clic rimuove la velocità da tutti gli ordini STR_TIMETABLE_RESET_LATENESS :{BLACK}Azzera ritardo -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Azzera il contatore del ritardo, in modo che il veicolo sia considerato in orario +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Azzera il contatore dei ritardi, in modo che il veicolo sia puntuale. Ctrl+clic azzera l'intero gruppo, in modo che l'ultimo veicolo sia puntuale e tutti gli altri siano in anticipo. STR_TIMETABLE_AUTOFILL :{BLACK}Auto -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Riempie automaticamente la tabella oraria con i tempi del prossimo viaggio (CTRL+clic per cercare di mantenere i tempi di attesa) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Riempie automaticamente la tabella oraria con i tempi del prossimo viaggio. CTRL+clic per cercare di mantenere i tempi di attesa STR_TIMETABLE_EXPECTED :{BLACK}Orari attesi STR_TIMETABLE_SCHEDULED :{BLACK}Orari programmati @@ -4571,12 +4618,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Uno degl STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}La finestra di debug IA/Script è disponibile soltanto per il server # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Configurazione IA e Script +STR_AI_CONFIG_CAPTION_AI :{WHITE}Configurazione IA +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Configurazione script di gioco STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Lista degli Script che saranno caricati nella prossima partita STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Lista delle IA che saranno caricate nella prossima partita STR_AI_CONFIG_HUMAN_PLAYER :Giocatore umano STR_AI_CONFIG_RANDOM_AI :IA casuale STR_AI_CONFIG_NONE :(nessuno) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Numero massimo di avversari: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Sposta su STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Sposta l'IA selezionata più in alto nell'elenco @@ -4584,12 +4633,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Sposta g STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Sposta l'IA selezionata più in basso nell'elenco STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametri STR_AI_CONFIG_AI :{SILVER}IA -STR_AI_CONFIG_CHANGE :{BLACK}Seleziona {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :IA -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script +STR_AI_CONFIG_CHANGE_AI :{BLACK}Seleziona IA +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Seleziona lo script di gioco STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carica un altro script STR_AI_CONFIG_CONFIGURE :{BLACK}Configura STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configura i parametri dello script @@ -4617,10 +4665,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Screensh STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Screenshot della heightmap STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Screenshot della minimappa -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}Parametri {STRING} -STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script +# Script Parameters +STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametri +STR_AI_SETTINGS_CAPTION_AI :IA +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script di gioco STR_AI_SETTINGS_CLOSE :{BLACK}Chiudi STR_AI_SETTINGS_RESET :{BLACK}Reimposta STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4784,6 +4832,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... trop STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Impossibile generare industrie... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Impossibile costruire {STRING} qui... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Impossibile costruire l'industria qui... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Non si può eseguire la prospezione... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... troppo vicina ad un'altra industria STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... bisogna fondare una città prima STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... ne è ammessa solo una per città @@ -4798,6 +4847,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... una STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... può essere costruita solo al di sopra della linea delle nevi perenni STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... può essere costruita solo al di sotto della linea delle nevi perenni +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Nonostante il finanziamento la prospezione è fallita per sfortunate circostanze; riprova +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Non c'erano luoghi adatti per la prospezione di questa industria STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Nessun luogo adatto per le industrie '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Modificare i parametri di generazione delle mappa in modo da ottenerne una migliore @@ -4965,6 +5016,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Oggetto STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... sede della compagnia di mezzo STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Impossibile acquistare quest'area di terreno... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... già posseduto! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... limite di costruzione dell'oggetto raggiunto # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Impossibile creare il gruppo... @@ -5037,6 +5089,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Impossib STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... il veicolo è distrutto +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... non tutti i veicoli sono identici + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Non sarà disponibile alcun veicolo STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Cambiare i NewGRF configurati STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Non sono ancora disponibili veicoli @@ -5063,6 +5117,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Impossib STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... il veicolo non può utilizzare tutte le stazioni STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... il veicolo non può utilizzare questa stazione STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... un veicolo che condivide l'ordine non può utilizzare questa stazione +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... non tutti i veicoli hanno gli stessi ordini +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... non tutti i veicoli condividono gli ordini STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Impossibile condividere la lista degli ordini... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Impossibile terminare la condivisione degli ordini... @@ -5070,6 +5126,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Impossib STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... troppo lontano dalla destinazione precedente STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... l'aeromobile non ha sufficiente autonomia +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Non c'è una stazione ferroviaria +STR_ERROR_NO_BUS_STATION :{WHITE}Non c'è una stazione degli autobus +STR_ERROR_NO_TRUCK_STATION :{WHITE}Non c'è una stazione per i camion +STR_ERROR_NO_DOCK :{WHITE}Non c'è un molo +STR_ERROR_NO_AIRPORT :{WHITE}Non c'è un aeroporto/eliporto +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Non ci sono fermate con un tipo di strada compatibile +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Non ci sono fermate con un tipo di tram compatibile +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Non esistono fermate adatte agli autoarticolati.{}Gli autoarticolati necessitano di una fermata passante e non di una fermata a baia. +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}L'aereo non può atterrare in questo eliporto +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}L'elicottero non può atterrare in questo aeroporto +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Non c'è un waypoint ferroviario +STR_ERROR_NO_BUOY :{WHITE}Non c'è nessuna boa + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Impossibile dare un orario al veicolo... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}I veicoli possono attendere solo alle stazioni diff --git a/src/lang/japanese.txt b/src/lang/japanese.txt index 2dd59078af856..f7fe18bb47df3 100644 --- a/src/lang/japanese.txt +++ b/src/lang/japanese.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}英馬 STR_UNITS_POWER_METRIC :{COMMA}仏馬力 STR_UNITS_POWER_SI :{COMMA}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t. STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -225,9 +235,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}m STR_UNITS_HEIGHT_SI :{COMMA}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}フィルタリング: -STR_LIST_FILTER_OSKTITLE :{BLACK}フィルター文字列を入力 -STR_LIST_FILTER_TOOLTIP :{BLACK}フィルタリングするキーワードを入力します +STR_LIST_FILTER_TITLE :{BLACK}フィルター: +STR_LIST_FILTER_OSKTITLE :{BLACK}フィルタリングするキーワードを入力 +STR_LIST_FILTER_TOOLTIP :{BLACK}フィルタリングするキーワードを複数入力できます STR_TOOLTIP_GROUP_ORDER :{BLACK}グループの整列法を選択 STR_TOOLTIP_SORT_ORDER :{BLACK}並べ替えの順序を選択します (昇順 / 降順) @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR :――――― STR_SCENEDIT_FILE_MENU_QUIT :OpenTTDを終了 # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :ゲームオプション設定 STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :設定 -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/ゲームスクリプト設定 +STR_SETTINGS_MENU_AI_SETTINGS :AI設定 +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :ゲームスクリプト設定 STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRFの設定 STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :透過表示設定 STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :街名を表示 @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :インド・ル STR_GAME_OPTIONS_CURRENCY_IDR :インドネシア・ルピア(IDR) STR_GAME_OPTIONS_CURRENCY_MYR :マレーシア・リンギット(MYR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}街名のスタイルを選択します - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :イギリス -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :フランス -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :ドイツ -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :イギリス(追加) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :ラテンアメリカ -STR_GAME_OPTIONS_TOWN_NAME_SILLY :無邪気の国 -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :スウェーデン -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :オランダ -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :フィンランド -STR_GAME_OPTIONS_TOWN_NAME_POLISH :ポーランド -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :スロバキア -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :ノルウェー -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :ハンガリー -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :オーストリア -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :ルーマニア -STR_GAME_OPTIONS_TOWN_NAME_CZECH :チェコ -STR_GAME_OPTIONS_TOWN_NAME_SWISS :スイス -STR_GAME_OPTIONS_TOWN_NAME_DANISH :デンマーク -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :トルコ -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :イタリア -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :カタラン - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}オートセーブ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}自動保存の間隔を選択します @@ -1025,22 +1006,21 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE} この STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK} 垂直同期 STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}ここをチェックして垂直同期を有効にします。設定はゲームを再起動した後に適用されます。ハードウェアアクセラレーションが有効な環境でしか機能しません。 +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}現在のドライバー:{STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}インターフェイスのサイズ -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}インターフェイス上の単位サイズを指定します +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}インターフェイスのサイズ +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}スライダーをドラッグでインターフェースの大きさを調整できます。Ctrl押しながらで微調整できます。 +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}サイズを自動調整 +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}ここをチェックしてインタフェースのサイズを自動調整します。 -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(自動検出) -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倍 +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}ベベルのスケール +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}ここをチェックするとベベルはインタフェースのサイズに比例します -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}フォントサイズ -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}使用するインターフェースのフォントサイズを選択します - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(自動検出) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :ノーマル -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :ダブルサイズ -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :4倍 +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}グラフィクス @@ -1092,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}プレ STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}}£10,000(英ポンド)に対する為替レートを設定します STR_CURRENCY_CHANGE_PARAMETER :{BLACK}カスタム通貨の設定を変更 -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}最大競争会社数: {ORANGE}{COMMA} - STR_NONE :なし STR_FUNDING_ONLY :出資のみ STR_MINIMAL :最小 @@ -1143,6 +1121,12 @@ STR_SUBSIDY_X2 :×2 STR_SUBSIDY_X3 :×3 STR_SUBSIDY_X4 :×4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :温帯 +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :亜寒帯 +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :亜熱帯 +STR_CLIMATE_TOYLAND_LANDSCAPE :おもちゃの国 + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :特に平地 STR_TERRAIN_TYPE_FLAT :平地 @@ -1153,15 +1137,16 @@ STR_TERRAIN_TYPE_CUSTOM :カスタム高 STR_TERRAIN_TYPE_CUSTOM_VALUE :カスタム高度 ({NUM}) ###length 4 +STR_CITY_APPROVAL_LENIENT :特に寛容 STR_CITY_APPROVAL_TOLERANT :寛容 STR_CITY_APPROVAL_HOSTILE :対立 -STR_CITY_APPROVAL_PERMISSIVE :寛大 +STR_CITY_APPROVAL_PERMISSIVE :自由放任(再編に対する制限なし) STR_WARNING_NO_SUITABLE_AI :{WHITE}適切なAIがありません...{}AIは「オンライン項目を確認」からダウンロード可能です # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}設定 -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}フィルター設定: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}フィルター: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}すべて開く STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}すべて折りたたむ STR_CONFIG_SETTING_RESET_ALL :{BLACK}すべての値をリセット @@ -1221,6 +1206,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :右 STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :初期の借入最大額: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :初期の借入限度額を設定します (インフレは考慮されません) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :借入金なし {RED}ゲームスクリプトで資金を受給する必要があります STR_CONFIG_SETTING_INTEREST_RATE :金利: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :借入利率を設定します (インフレ設定を有効にしたときのインフレ率にも影響します) @@ -1256,8 +1244,8 @@ 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_HELPTEXT :会社が街域で引き起こした騒音(主に空港)や環境破壊がどの程度、街での評価や同じ地域での更なる建設行為に影響するかを設定します +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)"で地形生成後に適切な値を設定させるようにします。 @@ -1447,6 +1435,8 @@ 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_SHOW_CARGO_IN_LISTS :リスト内に輸送機器の輸送可能貨物を表示 {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :有効にすると車両リスト内で車両の積載可能な貨物が上に表示されます STR_CONFIG_SETTING_LANDSCAPE :地形: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :地形は様々な貨物と街の成長要件に関する基礎的なゲームプレイシナリオを定義します。NewGRFとゲームスクリプトによってより効果的なコントロールが可能になります。 @@ -1501,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :改良版 STR_CONFIG_SETTING_ROAD_SIDE :車両: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :左側/右側通行を設定します +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :左側通行 +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :右側通行 + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :ハイトマップの回転方向: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :反時計回り @@ -1527,7 +1521,13 @@ 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_LINKGRAPH_COLOURS :貨物流通オーバーレイの配色:{STRING} +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_HELPTEXT :貨物の流れのオーバーレイに使用される配色を設定します。 ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :緑から赤(オリジナル) +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :緑から青 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :灰色から赤 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :グレイスケール STR_CONFIG_SETTING_SCROLLMODE :ビューポートのスクロール挙動: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :マップのスクロール挙動 @@ -2029,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :信号待ちで STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :列車が信号で長く待たされた場合、進路を反転することを許可します ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF{BLUE}(おすすめ) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF{BLUE}(おすすめ) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}設定を変更します @@ -2072,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK}ハイ STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}設定 STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRFの設定 STR_INTRO_ONLINE_CONTENT :{BLACK}オンラインコンテンツの確認 -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI/ゲームスクリプトの設定 +STR_INTRO_AI_SETTINGS :{BLACK}AI設定 +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}ゲームスクリプト設定 STR_INTRO_QUIT :{BLACK}終了 STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}新規ゲームを開始します。Ctrl+クリックで地形生成設定をスキップします @@ -2092,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}ハイ STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}設定を表示 STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRFの有効/無効化、各パラメータの設定ができます STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}公式オンラインコンテンツのデータベースからデータの確認・追加・更新ができます -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}AI/ゲームスクリプトの設定を行います +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}AI設定を表示 +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}ゲームスクリプト設定を表示 STR_INTRO_TOOLTIP_QUIT :{BLACK}OpenTTD を終了します STR_INTRO_BASESET :現在選択されているグラフィックのベースセットは {NUM} つのスプライトが欠けています。ベースセットの更新を確認してみてください。 @@ -2124,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}日付 STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}現在日時を変更 STR_CHEAT_SETUP_PROD :{LTBLUE}生産量変更: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :温帯 -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :亜寒帯 -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :亜熱帯 -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :おもちゃの国 - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - 配色 @@ -2362,7 +2358,8 @@ 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_CLIENT_COMPANY_COUNT :{BLACK}{NUM} 個のクライアント / {NUM} 個の企業 +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM}個のクライアント - {NUM}/{NUM}個の企業 +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}現在の接続しているクライアント数、会社数とサーバー管理者によって設定された最大会社数 # Matches ConnectionType ###length 5 @@ -2489,13 +2486,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :リンクグラ STR_NETWORK_MESSAGE_CLIENT_LEAVING :退出 STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} が参加してきました -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} がゲームに参加してきました (クライアント #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} が 会社 #{2:NUM} の経営に参画してきました +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} がゲームに参加してきました (クライアント #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} が 会社 #{2:NUM} の経営に参画してきました 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_CLIENT_COMPANY_NEW :*** {0:STRING} が新会社 (#{2:NUM}) を設立しました +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} が退出しました({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} は名前を {STRING} に変更しました -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} が {1:STRING} に {2:CURRENCY_LONG} を送金してくれました +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} が {1:STRING} に {2:CURRENCY_LONG} を送金してくれました STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}サーバがセッションを終了しました STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}このサーバーは再起動中です…{}しばらくお待ちください… STR_NETWORK_MESSAGE_KICKED :*** {STRING}がキックされました。理由: ({STRING}) @@ -2609,6 +2606,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}適正 STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}供給過多 +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{1:STATION}から{2:STATION}までの輸送需要 {0:CARGO_LONG}/月 (輸送力{3:COMMA}%){4:STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}復路の輸送需要 {CARGO_LONG}/月 (輸送力{COMMA}%) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}平均移動時間: {NUM}{NBSP}日 + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}集荷範囲のハイライト STR_STATION_BUILD_COVERAGE_OFF :{BLACK}切 @@ -2617,6 +2619,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}停留 STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}停留施設の旅客・貨物集荷範囲をハイライトします STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}受入貨物: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}供給貨物: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}維持費: {GOLD}{CURRENCY_SHORT}/年 # Join station window STR_JOIN_STATION_CAPTION :{WHITE}停留施設を統合 @@ -2699,8 +2702,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}ドラ STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}鉄道橋建設 STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}道路橋建設 STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}建設したい橋の種類をクリックしてください -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING}、{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING}{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING}{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING}{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :吊橋(S造) STR_BRIDGE_NAME_GIRDER_STEEL :桁橋(S造) STR_BRIDGE_NAME_CANTILEVER_STEEL :カンチレバートラス橋(S造) @@ -2852,6 +2857,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}ラン STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}ランダムなところに街を建設します STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}多くのランダムな街 STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}地図にたくさんの街を建設します +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}すべての街を成長 +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}すべての街を少し成長させます STR_FOUND_TOWN_NAME_TITLE :{YELLOW}街名: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}街名入力 @@ -3130,6 +3137,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}地図 STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}生成する地図のサイズです。実際にはこのサイズより少し小さくなります STR_MAPGEN_BY :{BLACK}× STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}街数: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}街の名前: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}街名のスタイルを選択します STR_MAPGEN_DATE :{BLACK}日付: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}産業数: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}最高峰: @@ -3143,13 +3152,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}砂漠 STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}砂漠の範囲を10%増やします STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}砂漠の範囲を10%減らします STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}地形作成: STR_MAPGEN_TERRAIN_TYPE :{BLACK}地形種類: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}海水位: +STR_MAPGEN_SEA_LEVEL :{BLACK}海水位: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}河川: STR_MAPGEN_SMOOTHNESS :{BLACK}地形のなだらかさ: STR_MAPGEN_VARIETY :{BLACK}地形の地域性: STR_MAPGEN_GENERATE :{WHITE}作成 +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF設定 +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}NewGRFの設定を表示 +STR_MAPGEN_AI_SETTINGS :{BLACK}AI設定 +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}AI設定を表示 +STR_MAPGEN_GS_SETTINGS :{BLACK}ゲームスクリプト設定 +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}ゲームスクリプトの設定を表示 + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :イギリス +STR_MAPGEN_TOWN_NAME_FRENCH :フランス +STR_MAPGEN_TOWN_NAME_GERMAN :ドイツ +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :イギリス(追加) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :ラテンアメリカ +STR_MAPGEN_TOWN_NAME_SILLY :無邪気の国 +STR_MAPGEN_TOWN_NAME_SWEDISH :スウェーデン +STR_MAPGEN_TOWN_NAME_DUTCH :オランダ +STR_MAPGEN_TOWN_NAME_FINNISH :フィンランド +STR_MAPGEN_TOWN_NAME_POLISH :ポーランド +STR_MAPGEN_TOWN_NAME_SLOVAK :スロバキア +STR_MAPGEN_TOWN_NAME_NORWEGIAN :ノルウェー +STR_MAPGEN_TOWN_NAME_HUNGARIAN :ハンガリー +STR_MAPGEN_TOWN_NAME_AUSTRIAN :オーストリア +STR_MAPGEN_TOWN_NAME_ROMANIAN :ルーマニア +STR_MAPGEN_TOWN_NAME_CZECH :チェコ +STR_MAPGEN_TOWN_NAME_SWISS :スイス +STR_MAPGEN_TOWN_NAME_DANISH :デンマーク +STR_MAPGEN_TOWN_NAME_TURKISH :トルコ +STR_MAPGEN_TOWN_NAME_ITALIAN :イタリア +STR_MAPGEN_TOWN_NAME_CATALAN :カタラン # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}地図端: @@ -3295,6 +3332,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}前の STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}前のノーマルスプライトに戻ります。始端と終端は連続しているものとみなし、疑似/リカラー/フォントスプライトはスキップします STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}現在選択されているスプライトの代表絵を示します。この配列はスプライトを描画するときには無視されます STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}X・Yオフセットを変更し、スプライトを移動します + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}オフセット中心 +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}スプライト中心 + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}十字 + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK} 相対値リセット STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK} 現在の相対オフセットをリセットします。 STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Xオフセット : {NUM},Yオフセット : {NUM} (絶対値) @@ -3309,15 +3353,15 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}警告: {SILVER}{STRING} 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_FATAL_POPUP :{WHITE}NewGRF '{STRING}'に致命的なエラーが発生しました:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF '{STRING}'にエラーが発生しました:{}{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}を有効にしなければなりません -STR_NEWGRF_ERROR_INVALID_PARAMETER :{1:STRING}のパラメータが不正です: パラメータ {STRING}({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING}は{STRING}の読み込み前にのみ読み込めます -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING}は{STRING}の読み込み後にのみ読み込めます -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING}にはバージョン{STRING}かそれ以降のOpenTTDが必要です +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING}はTTDのバージョン{2:STRING}にのみ対応しています +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING}を使用時には{2:STRING}を有効にしなければなりません +STR_NEWGRF_ERROR_INVALID_PARAMETER :{1:STRING}のパラメータが不正です: パラメータ {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING}は{2:STRING}の読み込み前にのみ読み込めます +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING}は{2:STRING}の読み込み後にのみ読み込めます +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING}にはOpenTTDバージョン{2:STRING}以降が必要です STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :このGRFファイルは後発翻訳版です STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :NewGRFが多すぎます STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :{2:STRING}を含む{1:STRING}を常用のNewGRFとして読み込むと、同期エラーを起こす可能性があります @@ -3612,24 +3656,38 @@ STR_FINANCES_CAPTION :{WHITE}{COMPANY STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}収益 +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}営業費 +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}資本的支出 ###length 13 STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}建設費 STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}輸送機器購入費 -STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}列車運用費 -STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}車両運用費 -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}航空機運用費 -STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}船舶運用費 -STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}借入金利息 +STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}列車 +STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}車両 +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}航空機 +STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}船舶 +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}インフラ設備 +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}列車 +STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}車両 +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}航空機 +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}船舶 +STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}借入金利子 STR_FINANCES_SECTION_OTHER :{GOLD}その他 -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} -STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_TOTAL_CAPTION :{WHITE}合計 +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} +STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}利益 STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}預金残高 +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}自己資金 STR_FINANCES_LOAN_TITLE :{WHITE}借入金 +STR_FINANCES_INTEREST_RATE :{WHITE}借入金利率: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}借入上限: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}{CURRENCY_LONG}を借入 STR_FINANCES_BORROW_TOOLTIP :{BLACK}銀行から資金を借り受けます。Ctrl+クリックで借入上限一杯まで資金を借り受けます STR_FINANCES_REPAY_BUTTON :{BLACK}{CURRENCY_LONG}を返済 @@ -3730,7 +3788,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}生産: 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 :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW} {STRING} {BLACK}:{CARGO_SHORT}待機中{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}生産量を変更 (8の倍数、最大2040) @@ -3760,6 +3818,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}この STR_VEHICLE_LIST_REPLACE_VEHICLES :輸送機器更新 STR_VEHICLE_LIST_SEND_FOR_SERVICING :回送して点検 STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}収益(今年): {CURRENCY_LONG} (収益(去年): {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :列車庫へ回送 STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :車庫へ回送 @@ -3851,6 +3911,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}最大 STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}航続距離: {GOLD}{COMMA} タイル STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}航空機の機種: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :すべての積荷 +STR_CARGO_TYPE_FILTER_FREIGHT :貨物 +STR_CARGO_TYPE_FILTER_NONE :積荷なし + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}列車リスト - 個々の情報を見るには列車をクリックします。Ctrl+クリックでその列車種の表示/非表示を切り替えます STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}車両リスト - 個々の情報を見るには車両をクリックします。Ctrl+クリックでその車両種の表示/非表示を切り替えます @@ -4178,12 +4243,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}重量: STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}重量: {LTBLUE}{WEIGHT_SHORT} {BLACK}出力: {LTBLUE}{POWER}{BLACK} 最高速度: {LTBLUE}{VELOCITY} {BLACK}最大牽引力: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}今年の収益: {LTBLUE}{CURRENCY_LONG}(昨年: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}今年の収益: {LTBLUE}{CURRENCY_LONG}(昨年: {CURRENCY_LONG}) {BLACK}最低パフォーマンス: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}信頼度: {LTBLUE}{COMMA}% {BLACK}点検後の故障数: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}購入年: {LTBLUE}{NUM}{BLACK} 車両価値: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}収容能力: {LTBLUE}なし{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}収容能力: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}収容能力: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}収容能力: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}収容能力: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}収容能力: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}転送による部分払い: {LTBLUE}{CURRENCY_LONG} @@ -4209,8 +4275,8 @@ STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} 車両価値: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}この列車の貨物最大収容量: -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}空荷 STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} (積載地: {STATION}) @@ -4511,12 +4577,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}実行 STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/ゲームスクリプトのデバッグウインドウはサーバーでのみ使用できます # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AIの設定 +STR_AI_CONFIG_CAPTION_AI :{WHITE}AI 設定 +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}ゲームスクリプトの構成 STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}このゲームスクリプトは次のゲーム開始時からロードされます -STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}}このAIは次のゲーム開始時からロードされます +STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}このAIは次のゲーム開始時からロードされます STR_AI_CONFIG_HUMAN_PLAYER :人間のプレーヤー STR_AI_CONFIG_RANDOM_AI :ランダムなAI STR_AI_CONFIG_NONE :(なし) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}最大競争会社数: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}上に移動 STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}選択したAIの順位を上げる @@ -4524,12 +4592,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}下に STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}選択したAIの順位を下げる STR_AI_CONFIG_GAMESCRIPT :{SILVER}ゲームスクリプト +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}パラメータ STR_AI_CONFIG_AI :{SILVER}AI -STR_AI_CONFIG_CHANGE :{BLACK}{STRING}を選択 -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :ゲームスクリプト +STR_AI_CONFIG_CHANGE_AI :{BLACK}AIを選択 +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}ゲームスクリプトを選択 STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}他のスクリプトをロードします STR_AI_CONFIG_CONFIGURE :{BLACK}設定 STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}スクリプトのパラメータを設定します @@ -4557,8 +4624,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}地図 STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}ハイトマップスクリーンショット STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}ミニマップのスクリーンショット -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} パラメータ +# Script Parameters +STR_AI_SETTINGS_CAPTION :{WHITE}{STRING}のパラメータ STR_AI_SETTINGS_CAPTION_AI :AI STR_AI_SETTINGS_CAPTION_GAMESCRIPT :ゲームスクリプト STR_AI_SETTINGS_CLOSE :{BLACK}閉じる @@ -4724,6 +4791,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}産業 STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}産業拠点を建設できません STR_ERROR_CAN_T_BUILD_HERE :{WHITE}ここに{STRING}を建設できません STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}この産業拠点はここには建設できません +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}調査/探鉱できませんでした… STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}他の産業に近すぎます STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}先に街を開設しなければなりません STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}街に一つしか建設できません @@ -4738,6 +4806,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}雪線 STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}降雪線より上にのみ建設できます STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}降雪線より下にのみ建設できます +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}運が悪かったため、資金調達が見込めませんでした。再試行してください +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}この産業で期待できる土地がありませんでした STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}産業「{STRING}」を建設するのに適切な土地がありません STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}よりよいマップを作成するため、生成パラメーターを変更します @@ -4905,6 +4975,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}灯台/ STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}本社ビルがあります STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}この土地を購入できません STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}すでに所有しています! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}…建設上限に達しています # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}グループを作成できません @@ -4977,6 +5048,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}点検 STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}輸送機器が破壊されます +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... 全車両が同一ではありません + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}利用できる輸送機器が全くなくなります STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}NewGRFの設定を変更してください STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}利用可能な輸送機器がありません @@ -5003,6 +5076,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}選択 STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}この輸送機器は指令されたいずれの停留施設にも辿り着けません STR_ERROR_CAN_T_ADD_ORDER :{WHITE}この輸送機器はその停留施設に辿り着けません STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}指令を共有している輸送機器がその停留施設に辿り着けません +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... すべての車両の指令が同じではありません +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... すべての車両の指令が共有されていません STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}指令リストを共有できません STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}指令リストの共有を解除できません @@ -5010,6 +5085,17 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}指令 STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}前の目的地から遠すぎます STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}航続距離が足りません +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}駅がありません +STR_ERROR_NO_BUS_STATION :{WHITE}バス停がありません +STR_ERROR_NO_TRUCK_STATION :{WHITE}荷役所がありません +STR_ERROR_NO_DOCK :{WHITE}埠頭がありません +STR_ERROR_NO_AIRPORT :{WHITE}空港・ヘリポートがありません +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}この飛行機はこのヘリポートに着陸できません +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}このヘリコプターはこの空港に着陸できません +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}中継駅がありません +STR_ERROR_NO_BUOY :{WHITE}ブイがありません + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}この輸送機器にダイヤを設定できません STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}輸送機器は停留施設でのみ待機できます diff --git a/src/lang/korean.txt b/src/lang/korean.txt index a75d044017d01..27f669957317f 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}마력 STR_UNITS_POWER_METRIC :{COMMA}마력 STR_UNITS_POWER_SI :{COMMA}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}마력/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}마력/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}마력/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}마력/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}마력/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}마력/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -226,9 +236,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}m STR_UNITS_HEIGHT_SI :{COMMA}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}검색할 문자열: -STR_LIST_FILTER_OSKTITLE :{BLACK}검색할 문자를 입력하세요 -STR_LIST_FILTER_TOOLTIP :{BLACK}검색할 키워드를 입력하세요 +STR_LIST_FILTER_TITLE :{BLACK}검색: +STR_LIST_FILTER_OSKTITLE :{BLACK}검색할 단어를 하나 이상 입력하세요 +STR_LIST_FILTER_TOOLTIP :{BLACK}검색할 단어를 하나 이상 입력하세요 STR_TOOLTIP_GROUP_ORDER :{BLACK}그룹화 순서를 선택하세요. STR_TOOLTIP_SORT_ORDER :{BLACK}정렬 방법을 선택하세요 (내림차순/오름차순) @@ -377,9 +387,9 @@ 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_PLANT_TREES :{BLACK}나무를 심습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다 +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}나무를 심습니다. CTRL 키를 누른 채로 사용하면 대각선 방향의 영역을 선택할 수 있습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다 STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}팻말을 답니다. -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}오브젝트를 설치합니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다 +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}오브젝트를 설치합니다. CTRL 키를 누르면 대각선 방향의 영역을 선택할 수 있습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다 # Scenario editor file menu ###length 7 @@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :게임 종료 # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :게임 기본 설정 STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :설정 -STR_SETTINGS_MENU_SCRIPT_SETTINGS :인공지능/게임 스크립트 설정 +STR_SETTINGS_MENU_AI_SETTINGS :인공지능 설정 +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :게임 스크립트 설정 STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF 설정 STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :투명 설정 STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :도시 이름을 표시함 @@ -498,7 +509,7 @@ STR_ABOUT_MENU_AI_DEBUG :인공지능/ STR_ABOUT_MENU_SCREENSHOT :스크린샷 찍기 STR_ABOUT_MENU_SHOW_FRAMERATE :프레임레이트 보기 STR_ABOUT_MENU_ABOUT_OPENTTD :'OpenTTD'에 대해서 -STR_ABOUT_MENU_SPRITE_ALIGNER :스프라이트 정렬도구 +STR_ABOUT_MENU_SPRITE_ALIGNER :스프라이트 정렬 도구 STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :박스 경계선 보기 전환 STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :시각적 업데이트 블록 표시 전환 @@ -805,13 +816,13 @@ STR_MESSAGE_NEWS_FORMAT :{STRING} - {S STR_NEWS_MESSAGE_CAPTION :{WHITE}메시지 STR_NEWS_CUSTOM_ITEM :{BIG_FONT}{BLACK}{STRING} -STR_NEWS_FIRST_TRAIN_ARRIVAL :{BIG_FONT}{BLACK}시민들이 축하하고 있습니다 . . .{}{STATION}에 처음으로 열차가 도착했습니다! -STR_NEWS_FIRST_BUS_ARRIVAL :{BIG_FONT}{BLACK}시민들이 축하하고 있습니다 . . .{}{STATION}에 처음으로 버스가 도착했습니다! -STR_NEWS_FIRST_TRUCK_ARRIVAL :{BIG_FONT}{BLACK}시민들이 축하하고 있습니다 . . .{}{STATION}에 처음으로 트럭이 도착했습니다! -STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL :{BIG_FONT}{BLACK}시민들이 축하하고 있습니다 . . .{}{STATION}에 처음으로 여객 전차가 도착했습니다! -STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL :{BIG_FONT}{BLACK}시민들이 축하하고 있습니다 . . .{}{STATION}에 처음으로 화물 전차가 도착했습니다! -STR_NEWS_FIRST_SHIP_ARRIVAL :{BIG_FONT}{BLACK}시민들이 축하하고 있습니다 . . .{}{STATION}에 처음으로 선박이 도착했습니다! -STR_NEWS_FIRST_AIRCRAFT_ARRIVAL :{BIG_FONT}{BLACK}시민들이 축하하고 있습니다 . . .{}{STATION}에 처음으로 항공기가 도착했습니다! +STR_NEWS_FIRST_TRAIN_ARRIVAL :{BIG_FONT}{BLACK}시민들이 기뻐합니다 . . .{}{STATION}에 처음으로 열차가 도착했습니다! +STR_NEWS_FIRST_BUS_ARRIVAL :{BIG_FONT}{BLACK}시민들이 기뻐합니다 . . .{}{STATION}에 처음으로 버스가 도착했습니다! +STR_NEWS_FIRST_TRUCK_ARRIVAL :{BIG_FONT}{BLACK}시민들이 기뻐합니다 . . .{}{STATION}에 처음으로 트럭이 도착했습니다! +STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL :{BIG_FONT}{BLACK}시민들이 기뻐합니다 . . .{}{STATION}에 처음으로 여객 전차가 도착했습니다! +STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL :{BIG_FONT}{BLACK}시민들이 기뻐합니다 . . .{}{STATION}에 처음으로 화물 전차가 도착했습니다! +STR_NEWS_FIRST_SHIP_ARRIVAL :{BIG_FONT}{BLACK}시민들이 기뻐합니다 . . .{}{STATION}에 처음으로 선박이 도착했습니다! +STR_NEWS_FIRST_AIRCRAFT_ARRIVAL :{BIG_FONT}{BLACK}시민들이 기뻐합니다 . . .{}{STATION}에 처음으로 항공기가 도착했습니다! STR_NEWS_TRAIN_CRASH :{BIG_FONT}{BLACK}열차 충돌 사고!{}충돌로 인한 폭발로 {COMMA}명의 사망자가 발생하였습니다! STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER :{BIG_FONT}{BLACK}차량 충돌!{}열차 충돌로 운전자가 사망했습니다! @@ -966,36 +977,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :인도 루피 ( STR_GAME_OPTIONS_CURRENCY_IDR :인도네시아 루피아 (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :말레이시아 링깃 (MYR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}도시 이름 스타일을 선택하세요 - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :영국 식 (기본) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :프랑스 식 -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :독일 식 -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :영국 식 (추가) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :라틴아메리카 식 -STR_GAME_OPTIONS_TOWN_NAME_SILLY :바보같은 도시 이름 -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :스웨덴 식 -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :네덜란드 식 -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :핀란드 식 -STR_GAME_OPTIONS_TOWN_NAME_POLISH :폴란드 식 -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :슬로바키아 식 -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :노르웨이 식 -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :헝가리 식 -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :오스트리아 식 -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :루마니아 식 -STR_GAME_OPTIONS_TOWN_NAME_CZECH :체코 식 -STR_GAME_OPTIONS_TOWN_NAME_SWISS :스위스 식 -STR_GAME_OPTIONS_TOWN_NAME_DANISH :덴마크 식 -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :터키 식 -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :이탈리아 식 -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :카탈로니아 식 - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}자동 저장 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}게임 자동 저장 간격을 선택 @@ -1028,21 +1009,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}화면 STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}현재 드라이버: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}인터페이스 크기 -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}인터페이스의 크기를 선택합니다. +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}인터페이스 크기 +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}인터페이스 크기를 설정하려면 슬라이더를 드래그하세요. CTRL 키를 누르고 있으면 미세 조정이 가능합니다 +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}크기 자동 탐지 +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}인터페이스 크기를 자동으로 탐지하려면 이 박스에 체크하세요 -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(자동 탐지) -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배 크기 +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}크기 조절 +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}인터페이스 크기를 슬라이더로 조절하려면 이 박스에 체크하세요 -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}글씨 크기 -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}인터페이스에서 사용할 글씨 크기를 선택하세요 - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(자동 탐지) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :기본 크기 -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :2배 크기 -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :4배 크기 +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}그래픽 @@ -1094,8 +1073,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}미리 STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 파운드(£)에 해당하는 사용자 화폐 단위입니다 STR_CURRENCY_CHANGE_PARAMETER :{BLACK}사용자 화폐 변수 변경 -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}최대 경쟁자수: {ORANGE}{COMMA} - STR_NONE :없음 STR_FUNDING_ONLY :투자만 가능 STR_MINIMAL :최소 @@ -1145,6 +1122,12 @@ STR_SUBSIDY_X2 :2배 지급 STR_SUBSIDY_X3 :3배 지급 STR_SUBSIDY_X4 :4배 지급 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :온대 기후 +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :아한대 기후 +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :아열대 기후 +STR_CLIMATE_TOYLAND_LANDSCAPE :장난감나라 + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :매우 평탄함 STR_TERRAIN_TYPE_FLAT :평탄함 @@ -1164,7 +1147,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}사용 # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}설정 -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}검색할 문자열: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}검색: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}모두 펼치기 STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}모두 접기 STR_CONFIG_SETTING_RESET_ALL :{BLACK}모든 설정 초기화 @@ -1224,6 +1207,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :오른쪽 STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :최대 초기 대출금: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :한 회사가 최대한 빌릴 수 있는 대출금의 양을 조절할 수 있습니다. (여기서 설정한 값은 인플레이션에 의한 효과를 적용하지 않은 값입니다.) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :대출 불가 {RED}초기 자금을 제공하려면 게임 스크립트가 필요합니다 STR_CONFIG_SETTING_INTEREST_RATE :대출 금리: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :대출 금리입니다. 인플레이션 설정이 켜져있는 경우 인플레이션의 영향을 받습니다. @@ -1232,7 +1218,7 @@ STR_CONFIG_SETTING_RUNNING_COSTS :유지비: {STR STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :차량과 기반시설의 유지비 수준을 설정하십시오 STR_CONFIG_SETTING_CONSTRUCTION_SPEED :건설 속도: {STRING} -STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :인공지능의 건설 행동량을 제한하여 건설 속도를 조절할 수 있습니다. +STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :인공지능의 건설 행동량을 제한하여 건설 속도를 조절할 수 있습니다 STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :차량 고장 빈도수: {STRING} STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS_HELPTEXT :점검을 제대로 받지 않은 차량이 얼마나 자주 고장나도록 할지를 조절하십시오. @@ -1270,7 +1256,7 @@ STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_AUTO :(자동) STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN :{WHITE}이 값을 지도 높이 최댓값으로 설정할 수 없습니다. 이 값보다 고도가 높은 산이 최소 한 개 이상 존재합니다. STR_CONFIG_SETTING_AUTOSLOPE :건물, 트랙 등의 하부 지형 편집 허용: {STRING} -STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :건물이나 도로/선로 등을 제거하지 않고도 하부의 지형을 편집할 수 있게 허용합니다. +STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :건물이나 도로/선로 등을 제거하지 않고도 하부의 지형을 편집할 수 있게 허용합니다 STR_CONFIG_SETTING_CATCHMENT :더 현실적인 역세권 지정: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :역과 공항의 종류에 따라 다른 크기의 역세권을 가지도록 만듭니다. @@ -1361,19 +1347,19 @@ STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT :주 게임 화 STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT :모든 화면에서 STR_CONFIG_SETTING_BRIBE :지역 당국에 뇌물을 주는 행위 허용: {STRING} -STR_CONFIG_SETTING_BRIBE_HELPTEXT :회사가 지역 도시 당국에 뇌물을 주는 것을 허용합니다. 뇌물 행위가 적발되는 경우, 회사는 해당 도시에서 6개월간 아무 행동도 할 수 없습니다. +STR_CONFIG_SETTING_BRIBE_HELPTEXT :회사가 지역 도시 당국에 뇌물을 주는 것을 허용합니다. 뇌물 행위가 적발되는 경우, 회사는 해당 도시에서 6개월간 아무 행동도 할 수 없습니다 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_ALLOW_GIVE_MONEY_HELPTEXT :멀티 플레이 모드에서 회사 사이에 돈을 보내는 것을 허용합니다 STR_CONFIG_SETTING_FREIGHT_TRAINS :화물 무게가중치 (무거운 열차를 구현할 때 사용): {STRING}배 STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :열차가 싣고 있는 화물이 열차 속력에 미치는 영향에 대해 설정합니다. 값을 높게 설정하면 화물을 수송하는데 더 큰 힘이 필요합니다. (특히 언덕을 오를 때 심해집니다) @@ -1399,7 +1385,7 @@ STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :기반시설 STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :이 설정을 켜면, 기반시설 유지비가 발생합니다. 유지비는 교통망의 규모에 비례하며 대형 회사는 소형 회사보다 많은 유지비가 들어갑니다. STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :시작시 회사 색상: {STRING} -STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :새 회사에서 사용할 색상을 선택합니다. +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :새 회사에서 사용할 색상을 선택합니다 STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :옛날 공항을 사라지지 않고 계속 만들 수 있게 함: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :이 설정을 켜면, 소형 공항을 포함한 모든 공항 종류를 도입 이후에 계속 사용할 수 있게 됩니다. @@ -1421,7 +1407,7 @@ STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :옛날 차량 STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :이 설정을 켜면, 오래된 차량 모델을 포함하여 모든 차량 모델을 도입 이후에 계속 사용할 수 있게 됩니다. STR_CONFIG_SETTING_AUTORENEW_VEHICLE :차량이 낡으면 차량을 자동으로 교체: {STRING} -STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :이 설정을 켜면, 제한 수명에 다다른 차량이 교체 조건을 만족할 경우 자동으로 차량을 교체할 수 있게 됩니다. +STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :이 설정을 켜면, 제한 수명에 다다른 차량이 교체 조건을 만족할 경우 자동으로 차량을 교체할 수 있게 됩니다 STR_CONFIG_SETTING_AUTORENEW_MONTHS :차량이 최대 수명의 {STRING}이면 자동 교체 STR_CONFIG_SETTING_AUTORENEW_MONTHS_HELPTEXT :자동 교체가 필요한 차량의 상대적인 연령을 설정합니다. @@ -1430,7 +1416,7 @@ STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_BEFORE :{COMMA}개월 STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_AFTER :{COMMA}개월 후 STR_CONFIG_SETTING_AUTORENEW_MONEY :자동 교체를 위해 최소한으로 갖고 있어야 할 자금: {STRING} -STR_CONFIG_SETTING_AUTORENEW_MONEY_HELPTEXT :차량을 자동 교체하기 위해 최소한으로 있어야 하는 자금의 양을 설정합니다. +STR_CONFIG_SETTING_AUTORENEW_MONEY_HELPTEXT :차량을 자동 교체하기 위해 최소한으로 있어야 하는 자금의 양을 설정합니다 STR_CONFIG_SETTING_ERRMSG_DURATION :오류 메시지 표시: {STRING} STR_CONFIG_SETTING_ERRMSG_DURATION_HELPTEXT :오류 메시지를 표시할 시간을 설정합니다. 일부 (중요한) 오류 메시지는 이 시간이 지나도 자동으로 사라지지 않고 수동으로 꺼야할 수도 있음을 알아두십시오. @@ -1450,6 +1436,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :그래프의 STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :차량 구입 창에 NewGRF 이름 표시: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :차량 구입 창 맨 아래 줄에, 이 차량이 어떤 NewGRF에서 추가되는 지 해당 NewGRF의 이름을 표시해줍니다. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :차량 목록 창에서 차량이 실을 수 있는 화물 표시: {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :이 설정을 켜면, 차량 목록 상단에 차량이 실을 수 있는 화물을 표시합니다 STR_CONFIG_SETTING_LANDSCAPE :지형: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :지형에 따라 화물과 도시 성장 요구 조건이 다른 게임 플레이 시나리오가 만들어집니다. NewGRF과 게임 스크립트를 통해 세밀한 조절이 가능합니다. @@ -1477,7 +1465,7 @@ 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_HELPTEXT :아열대 기후에서 사막 지역의 양을 대략적으로 조절할 수 있습니다. 사막은 산업시설 생성에도 영향을 미칩니다. 지도를 생성할 때에만 사용하는 설정입니다 STR_CONFIG_SETTING_DESERT_COVERAGE_VALUE :{NUM}% STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :지형의 거친 정도: {STRING} @@ -1504,6 +1492,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :향상됨 STR_CONFIG_SETTING_ROAD_SIDE :자동차 통행 방향: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :통행 방향을 선택합니다 +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :좌측통행 +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :우측통행 + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :높이맵 회전: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :반시계방향 @@ -1601,7 +1593,7 @@ STR_CONFIG_SETTING_AUTOSAVE :자동 저장: STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :게임을 자동으로 저장할 간격을 선택하세요 STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :저장 파일 이름으로 {STRING} 날짜 형식을 사용 -STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT :게임 저장 파일 이름에 사용할 날짜 형식을 선택합니다. +STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT :게임 저장 파일 이름에 사용할 날짜 형식을 선택합니다 ###length 3 STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_LONG :긴 (2012년 1월 1일) STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_SHORT :짧은 (2012.01.01) @@ -1619,7 +1611,7 @@ STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_LANDSCAPING :지형 편집 STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_ACTIONS :모든 행동 STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS :차량 목록에서 그룹 기능 사용: {STRING} -STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :고급화된 차량 목록의 사용 여부를 설정합니다. +STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :고급 차량 목록 사용 여부를 설정합니다 STR_CONFIG_SETTING_LOADING_INDICATORS :적재율 표시: {STRING} STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :적재나 하차하는 차량 위에 적재/하차율을 표시할지 말지를 선택합니다. @@ -1634,7 +1626,7 @@ STR_CONFIG_SETTING_QUICKGOTO :빠른 행선 STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT :경로 창을 열면 자동으로 '행선지' 버튼을 선택하여 곧바로 행선지를 지정할 수 있도록 합니다. STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE :철도 형식 기본값 설정 (게임 시작/불러온 후): {STRING} -STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :게임을 새로 시작하거나 불러온 뒤에 사용할 철도의 종류를 선택합니다. '처음 사용 가능한 것'은 가장 오래된 철도 종류를 선택하고, '최신 기술의 철도'는 가장 최신에 나온 철도 종류를 선택하며 '가장 많이 사용한 것'은 현재 가장 많이 사용한 철도 종류를 선택합니다. +STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :게임을 새로 시작하거나 불러온 뒤에 사용할 철도의 종류를 선택합니다. '처음 사용 가능한 것'은 가장 오래된 철도 종류를 선택하고, '최신 기술의 철도'는 가장 최신에 나온 철도 종류를 선택하며 '가장 많이 사용한 것'은 현재 가장 많이 사용한 철도 종류를 선택합니다 ###length 3 STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST :처음 사용 가능한 것 STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_LAST :가장 최근에 개발된 철도 @@ -1692,26 +1684,26 @@ STR_CONFIG_SETTING_MAX_SHIPS :회사당 최 STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :한 회사가 소유할 수 있는 선박의 최대 수를 제한합니다. STR_CONFIG_SETTING_AI_BUILDS_TRAINS :컴퓨터의 철도 사용을 허가하지 않음: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :이 설정을 켜면, 컴퓨터 플레이어가 철도를 사용할 수 없게 됩니다. +STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :이 설정을 켜면, 컴퓨터 플레이어가 철도를 사용할 수 없게 됩니다 STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :컴퓨터의 자동차/전차 사용을 허가하지 않음: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :이 설정을 켜면, 컴퓨터 플레이어가 자동차나 전차를 사용할 수 없게 됩니다. +STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :이 설정을 켜면, 컴퓨터 플레이어가 자동차나 전차를 사용할 수 없게 됩니다 STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :컴퓨터의 항공기 사용을 허가하지 않음: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :이 설정을 켜면, 컴퓨터 플레이어가 항공기를 사용할 수 없게 됩니다. +STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :이 설정을 켜면, 컴퓨터 플레이어가 항공기를 사용할 수 없게 됩니다 STR_CONFIG_SETTING_AI_BUILDS_SHIPS :컴퓨터의 선박 사용을 허가하지 않음: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :이 설정을 켜면, 컴퓨터 플레이어가 선박을 사용할 수 없게 됩니다. +STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :이 설정을 켜면, 컴퓨터 플레이어가 선박을 사용할 수 없게 됩니다 STR_CONFIG_SETTING_AI_PROFILE :기본 설정 난이도: {STRING} -STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :무작위 인공지능이 사용할 난이도 설정이나, 인공지능 또는 게임 스크립트를 추가할 때의 난이도 초기값을 고르십시오. +STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :무작위 인공지능이 사용할 난이도 설정이나 인공지능 또는 게임 스크립트를 추가할 때 사용할 난이도 초기값을 고르십시오 ###length 3 STR_CONFIG_SETTING_AI_PROFILE_EASY :쉬움 STR_CONFIG_SETTING_AI_PROFILE_MEDIUM :중간 STR_CONFIG_SETTING_AI_PROFILE_HARD :어려움 STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :멀티 플레이에서 컴퓨터 플레이어의 참여 허용: {STRING} -STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :멀티 플레이 게임에서 인공지능 컴퓨터 플레이어가 참여하는 것을 허용합니다. +STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :멀티 플레이 게임에서 인공지능 컴퓨터 플레이어가 참여하는 것을 허용합니다 STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :게임 스크립트가 중지되기 직전에 계산할 수 있는 최대 횟수: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :게임 스크립트가 한 단계에서 계산할 수 있는 최대 계산 횟수를 설정합니다. @@ -1741,7 +1733,7 @@ STR_CONFIG_SETTING_WAGONSPEEDLIMITS :화물차 속 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 :나의 새 역사에 처음으로 차량이 도착하면 메시지로 알려줍니다 @@ -1796,7 +1788,7 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_SUMMARY :상태 표시 STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :전체 메시지로 알림 STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :컬러로 된 뉴스가 시작되는 해: {STRING}년 -STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :신문이 컬러로 나오게 되는 연도를 설정합니다. 이 연도 이전까지는 신문이 흑백으로 나옵니다. +STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :신문이 컬러로 나오게 되는 연도를 설정합니다. 이 연도 이전까지는 신문이 흑백으로 나옵니다 STR_CONFIG_SETTING_STARTING_YEAR :시작 연도: {STRING} STR_CONFIG_SETTING_ENDING_YEAR :게임 종료 연도: {STRING} @@ -1813,7 +1805,7 @@ STR_CONFIG_SETTING_ECONOMY_TYPE_SMOOTH :부드러움 STR_CONFIG_SETTING_ECONOMY_TYPE_FROZEN :멈춤 STR_CONFIG_SETTING_ALLOW_SHARES :다른 회사의 지분을 사는 것을 허용: {STRING} -STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :이 설정을 켜면, 회사의 지분을 거래할 수 있게 됩니다. 회사의 지분을 거래하려면 해당 회사가 어느 정도 오래되어야 합니다. +STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :이 설정을 켜면, 회사의 지분을 거래할 수 있게 됩니다. 회사의 지분을 거래하려면 해당 회사가 어느 정도 오래되어야 합니다 STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :지분 거래를 허용할 최소 회사 나이: {STRING}년 STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :지분을 사고 팔기 위해 필요한 회사의 최소 나이를 설정합니다. @@ -1822,7 +1814,7 @@ STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :환승시 벌 STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :더 많은 수익을 내기 위해, 수송 관계상 중간 구간에게 주어진 수익의 비율을 설정합니다. STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :신호기를 드래그로 설치하는 경우: {STRING} -STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT :신호기를 드래그할 때, 다음 장애물(신호기, 분기점 등)을 만날 때까지 신호기가 설치될 간격을 설정합니다. +STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT :신호기를 드래그할 때, 다음 장애물(신호기, 분기점 등)을 만날 때까지 신호기가 설치될 간격을 설정합니다 STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE :{COMMA}칸 간격으로 설치 STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE :드래그할 때, 신호기 사이의 거리를 계속 고정: {STRING} STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :신호기를 CTRL+드래그 하여 설치할 때의 행동을 선택합니다. 이 설정을 끄면, 신호기가 없는 긴 폐색을 만들지 않기 위해 터널이나 다리 주변에 먼저 신호기가 설치될 것입니다. 이 설정을 켜면, 신호기는 터널/다리와 상관없이 매 n개의 칸마다 설치될 것입니다. @@ -1854,7 +1846,7 @@ 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_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개까지 지을 수 있습니다. 이 설정을 켜면, 한 도시에 지을 수 있는 공항의 수는 도시가 허용 가능한 소음 기준에 따라 달라집니다. 소음 기준은 도시 인구, 공항의 크기와 거리에 따라 다릅니다. @@ -1929,7 +1921,7 @@ STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :{COMMA}개 중 ###setting-zero-is-special 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 :다음 연결 상태를 재계산하기까지의 시간입니다. 한 번의 재계산할 때마다 그래프의 한 요소를 위한 계획을 계산합니다. 이는 이 설정의 X값에 따라 모든 그래프가 매 X일마다 갱신되는 것이 아니라는 것을 뜻합니다. 일부 요소만 재계산된다는 뜻입니다. 값이 작으면 작을 수록 CPU가 계산해야 할 횟수가 늘어납니다. 값을 크게 설정할 수록 화물 분배 상태가 새롭게 지정되는 데 더 오랜 시간이 걸립니다. @@ -1941,7 +1933,7 @@ STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"대칭"은 A STR_CONFIG_SETTING_DISTRIBUTION_MAIL :우편에 대한 분배 형식: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"대칭"은 A역에서 B역으로 가려는 우편물의 수가 B에서 A로 가려는 우편물의 수와 비슷하다는 뜻입니다. "비대칭"은 우편물이 아무 방향이나 임의의 양만큼 가게 됨을 뜻합니다. "수동"은 자동적인 우편물 분배가 일어나지 않고 기존 방식을 사용하겠음을 뜻합니다. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :귀금속 화물에 대한 분배 형식: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :귀금속 화물은 온대 기후의 귀금속, 아열대 기후의 다이아몬드 또는 아한대 기후의 금을 말합니다. NewGRF을 사용하면 달라질 수 있습니다. "대칭"은 A역에서 B역으로 가려는 화물의 수가 B에서 A로 가려는 화물의 수와 비슷하다는 뜻입니다. "비대칭"은 화물이 아무 방향이나 임의의 양만큼 가게 됨을 뜻합니다. "수동"은 자동적인 화물 분배가 일어나지 않고 기존 방식을 사용하겠음을 뜻합니다. 아한대 기후에서는 대칭으로 설정하면 은행이 금광으로 금을 보내지 않으려 하기 때문에 비대칭이나 수동으로 설정하는 것을 추천합니다. 온대 기후나 아열대 기후에서는 은행이 일부 적재한 귀금속을 원래 은행으로 보내려고 하기 때문에 대칭을 선택해도 됩니다. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :귀금속 화물은 온대 기후의 귀금속, 아열대 기후의 다이아몬드 또는 아한대 기후의 금을 말합니다. NewGRF을 사용하면 달라질 수 있습니다. "대칭"은 A역에서 B역으로 가려는 화물의 수가 B에서 A로 가려는 화물의 수와 비슷하다는 뜻입니다. "비대칭"은 화물이 아무 방향이나 임의의 양만큼 가게 됨을 뜻합니다. "수동"은 자동적인 화물 분배가 일어나지 않고 기존 방식을 사용하겠음을 뜻합니다. 아한대나 아열대 기후에서는 대칭으로 설정하면 은행이 금을 받기만 하기 때문에 비대칭이나 수동으로 설정하는 것을 추천합니다. 온대 기후에서는 은행이 귀금속을 원래 은행으로 보내려고 하기 때문에 대칭을 선택해도 됩니다. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :다른 화물에 대한 분배 형식: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"비대칭"은 화물이 아무 방향이나 임의의 양만큼 가게 됨을 뜻합니다. "수동"은 자동적인 화물 분배가 일어나지 않고 기존 방식을 사용하겠음을 뜻합니다. 특별한 이유가 없는 한, "비대칭"이나 "수동"으로 설정하십시오. ###length 3 @@ -2038,15 +2030,15 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :신호기 앞 STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :열차가 신호기 앞에서 너무 오래 기다리면 뒤로 되돌아갈 수 있도록 허용합니다. ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(권장) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(권장) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}설정값 변경 # Config errors STR_CONFIG_ERROR :{WHITE}설정 파일에서 오류 발생 STR_CONFIG_ERROR_ARRAY :{WHITE}... 배열 '{STRING}'에서 오류 발생 -STR_CONFIG_ERROR_INVALID_VALUE :{WHITE}... '{1:STRING}'에 잘못된 값('{0:STRING}')이 지정되었습니다. -STR_CONFIG_ERROR_TRAILING_CHARACTERS :{WHITE}... '{STRING}' 설정의 끝에 후행 문자가 있습니다. +STR_CONFIG_ERROR_INVALID_VALUE :{WHITE}... '{1:STRING}'에 잘못된 값('{0:STRING}')이 지정되었습니다 +STR_CONFIG_ERROR_TRAILING_CHARACTERS :{WHITE}... '{STRING}' 설정의 끝에 후행 문자가 있습니다 STR_CONFIG_ERROR_DUPLICATE_GRFID :{WHITE}... '{STRING}' NewGRF를 무시합니다: '{STRING}'{G 1 "과" "와"} GRF ID가 겹침 STR_CONFIG_ERROR_INVALID_GRF :{WHITE}... 유효하지 않은 '{STRING}' NewGRF를 무시합니다: {STRING} STR_CONFIG_ERROR_INVALID_GRF_NOT_FOUND :찾을 수 없음 @@ -2056,9 +2048,9 @@ STR_CONFIG_ERROR_INVALID_GRF_INCOMPATIBLE :현재 OpenTTD STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN :알 수 없음 STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL :{WHITE}... 압축 레벨 '{STRING}' : 유효하지 않습니다 STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM :{WHITE}... '{STRING}' 형식으로 게임을 저장할 수 없습니다. '{STRING}' 형식으로 변환합니다 -STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND :{WHITE}... 기본 그래픽 세트({STRING})가 무시되었습니다: 파일을 찾을 수 없습니다. -STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND :{WHITE}... 기본 효과음 세트({STRING})가 무시되었습니다: 파일을 찾을 수 없습니다. -STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND :{WHITE}... 기본 배경음 세트({STRING})가 무시되었습니다: 파일을 찾을 수 없습니다. +STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND :{WHITE}... 기본 그래픽 세트({STRING})가 무시되었습니다: 파일을 찾을 수 없습니다 +STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND :{WHITE}... 기본 효과음 세트({STRING})가 무시되었습니다: 파일을 찾을 수 없습니다 +STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND :{WHITE}... 기본 배경음 세트({STRING})가 무시되었습니다: 파일을 찾을 수 없습니다 STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}메모리 초과 STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}{BYTES}의 스프라이트 캐시 할당에 실패하였습니다. 스프라이트 캐시 용량이 {BYTES}로 감소합니다. 이는 OpenTTD의 성능을 저하시킬 것입니다. 메모리 요구사항을 낮추려면 32bpp를 비활성화하거나 화면 확대 설정을 기본값에 가깝게 조절하십시오. @@ -2081,12 +2073,13 @@ STR_INTRO_HIGHSCORE :{BLACK}고득 STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}설정 STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF 설정 STR_INTRO_ONLINE_CONTENT :{BLACK}온라인 콘텐츠 다운로드 -STR_INTRO_SCRIPT_SETTINGS :{BLACK}인공지능/게임 스크립트 설정 +STR_INTRO_AI_SETTINGS :{BLACK}인공지능 설정 +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}게임 스크립트 설정 STR_INTRO_QUIT :{BLACK}종료 -STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}새 게임을 시작합니다.{}CTRL+클릭하시면 지도 설정을 건너뛰고 바로 시작합니다. -STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}저장한 게임을 불러옵니다. -STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}높이맵을 지형으로 사용하여, 새로운 게임을 시작합니다. +STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}새 게임을 시작합니다.{}CTRL+클릭하시면 지도 설정을 건너뛰고 바로 시작합니다 +STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}저장한 게임을 불러옵니다 +STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}높이맵을 지형으로 사용하여, 새로운 게임을 시작합니다 STR_INTRO_TOOLTIP_PLAY_SCENARIO :{BLACK}사용자 시나리오로 새 게임을 시작합니다 STR_INTRO_TOOLTIP_SCENARIO_EDITOR :{BLACK}사용자 게임/시나리오를 만듭니다 STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}멀티 플레이 게임을 시작합니다 @@ -2096,12 +2089,13 @@ STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}아한 STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}아열대 기후 선택 STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}장난감나라 선택 -STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}게임 기본 설정 창을 보여줍니다. -STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}고득점 순위표를 보여줍니다. -STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}설정 창을 엽니다. -STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF 설정 창을 엽니다. -STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}새로 나왔거나 업데이트된 콘텐츠를 체크하여 다운로드합니다. -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}인공지능/게임 스크립트 설정창을 엽니다. +STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}게임 기본 설정 창을 보여줍니다 +STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}고득점 순위표를 보여줍니다 +STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}설정 창을 엽니다 +STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF 설정 창을 엽니다 +STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}새로 나왔거나 업데이트된 콘텐츠를 체크하여 다운로드합니다 +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}인공지능 설정 창을 엽니다 +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}게임 스크립트 설정 창을 엽니다 STR_INTRO_TOOLTIP_QUIT :{BLACK}'OpenTTD'를 종료합니다. STR_INTRO_BASESET :{BLACK}현재 선택된 기본 그래픽 세트에는 {NUM}개의 스프라이트가 빠져있습니다. 기본 세트를 업데이트하세요. @@ -2120,7 +2114,7 @@ STR_ABANDON_SCENARIO_QUERY :{YELLOW}정말 # Cheat window STR_CHEATS :{WHITE}치트 -STR_CHEATS_TOOLTIP :{BLACK}체크박스의 체크 표시는 이전에 이 치트를 사용했는지 여부를 나타냅니다. +STR_CHEATS_TOOLTIP :{BLACK}체크박스의 체크 표시는 이전에 이 치트를 사용했는지 여부를 나타냅니다 STR_CHEATS_NOTE :{BLACK}참고: 치트 사용 여부는 저장 파일에 기록될 것입니다 STR_CHEAT_MONEY :{LTBLUE}재정을 {CURRENCY_LONG} 만큼 증가 STR_CHEAT_CHANGE_COMPANY :{LTBLUE}다음 회사로 플레이: {ORANGE}{COMMA} @@ -2128,17 +2122,11 @@ STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}마법 STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}터널 교차 허용: {ORANGE}{STRING} STR_CHEAT_NO_JETCRASH :{LTBLUE}대형 항공기가 소형 공항에서 (자주) 충돌하지 않게 함: {ORANGE}{STRING} STR_CHEAT_EDIT_MAX_HL :{LTBLUE}최대 지형 고도값 수정: {ORANGE}{NUM} -STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}최대 지형 높이값을 수정합니다. +STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}최대 지형 높이값을 수정합니다 STR_CHEAT_CHANGE_DATE :{LTBLUE}날짜 변경: {ORANGE}{DATE_SHORT} STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}현재의 연도를 변경 STR_CHEAT_SETUP_PROD :{LTBLUE}1차 산업시설 생산량 조절 허용: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :온대 기후 -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :아한대 기후 -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :아열대 기후 -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :장난감나라 - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - 색상 @@ -2147,9 +2135,9 @@ STR_LIVERY_TRAIN_TOOLTIP :{BLACK}열차 STR_LIVERY_ROAD_VEHICLE_TOOLTIP :{BLACK}차량 색상 선택 STR_LIVERY_SHIP_TOOLTIP :{BLACK}선박 색상 선택 STR_LIVERY_AIRCRAFT_TOOLTIP :{BLACK}항공기 색상 선택 -STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}선택한 색상을 1차 색상으로 선택합니다. CTRL+클릭하면 모든 항목에 적용됩니다. -STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}선택한 색상을 2차 색상으로 선택합니다. CTRL+클릭하면 모든 항목에 적용됩니다. -STR_LIVERY_PANEL_TOOLTIP :{BLACK}색상 조합을 바꾸려면 선택하세요. 2개 이상 선택하려면 CTRL+클릭하세요. 네모를 클릭하여 체크하면 해당 색상 조합을 사용하게 됩니다. +STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}선택한 색상을 1차 색상으로 선택합니다. CTRL+클릭하면 모든 항목에 적용됩니다 +STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}선택한 색상을 2차 색상으로 선택합니다. CTRL+클릭하면 모든 항목에 적용됩니다 +STR_LIVERY_PANEL_TOOLTIP :{BLACK}색상 조합을 바꾸려면 선택하세요. 2개 이상 선택하려면 CTRL+클릭하세요. 네모를 클릭하여 체크하면 해당 색상 조합을 사용하게 됩니다 ###length 23 STR_LIVERY_DEFAULT :기본 색상 @@ -2371,7 +2359,8 @@ 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_CLIENT_COMPANY_COUNT :{BLACK}접속자 {NUM}명 / 회사 {NUM}개 +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}접속자 {NUM}명 / 회사 {NUM}/{NUM}개 +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}현재 접속 중인 클라이언트의 수 및 회사 수와 서버 관리자가 허용한 최대 회사 개수입니다 # Matches ConnectionType ###length 5 @@ -2498,11 +2487,11 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :연결 상태 STR_NETWORK_MESSAGE_CLIENT_LEAVING :게임 종료 STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} 님이 입장하셨습니다 -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} 님이 입장하셨습니다 ({2:NUM}번 접속자) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} 님이 {2:NUM}번 회사에 참여하셨습니다 +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} 님이 입장하셨습니다 ({2:NUM}번 접속자) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} 님이 {2:NUM}번 회사에 참여하셨습니다 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_CLIENT_COMPANY_NEW :*** {0:STRING} 님이 새로운 회사({2:NUM}번)를 창설하셨습니다 +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} 님이 퇴장하셨습니다 (사유: {2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} 님이 이름을 {STRING}(으)로 바꾸었습니다 STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} 님이 {1:STRING}에게 {2:CURRENCY_LONG}만큼의 돈을 보내셨습니다 STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}서버가 게임을 종료하였습니다 @@ -2618,6 +2607,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}포화 STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}과포화 +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{1:STATION}에서 {2:STATION}까지 매달 {0:CARGO_LONG} {G 0 "을" "를"} 수송해야 함 (수용량의 {3:COMMA}%){4:STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{0:CARGO_LONG}{G 0 "을" "를"} 다시 수송해와야 함 (수용량의 {1:COMMA}%) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}평균 운행 시간: {NUM}일 + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}역세권 표시 STR_STATION_BUILD_COVERAGE_OFF :{BLACK}끄기 @@ -2626,6 +2620,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}역세 STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}역세권을 표시합니다 STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}받음: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}공급: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}유지비: {GOLD}{CURRENCY_SHORT}/년 # Join station window STR_JOIN_STATION_CAPTION :{WHITE}같은 이름으로 정거장 만들기 @@ -2708,8 +2703,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}드래 STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}철교 선택 STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}다리 종류를 선택하세요 STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}다리 건설 - 원하는 다리 종류를 선택하세요 -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :강철 현수교 STR_BRIDGE_NAME_GIRDER_STEEL :강철 거더교 STR_BRIDGE_NAME_CANTILEVER_STEEL :강철 캔틸레버교 @@ -2813,11 +2810,11 @@ 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_PURCHASE_LAND :{BLACK}나중에 그 땅을 사용하기 위해 소유권을 구입합니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다 +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}나중에 그 땅을 사용하기 위해 소유권을 구입합니다. CTRL 키를 누르면 대각선 방향의 영역을 선택할 수 있습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다 # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}오브젝트 선택 -STR_OBJECT_BUILD_TOOLTIP :{BLACK}건설할 오브젝트를 선택합니다. +STR_OBJECT_BUILD_TOOLTIP :{BLACK}건설할 오브젝트를 선택합니다. CTRL 키를 누르면 대각선 방향의 영역을 선택할 수 있습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다 STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}건설할 오브젝트의 등급을 선택합니다 STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}오브젝트 미리보기 STR_OBJECT_BUILD_SIZE :{BLACK}크기: {GOLD}{NUM} x {NUM} 칸 @@ -2829,7 +2826,7 @@ STR_OBJECT_CLASS_TRNS :송신기 STR_PLANT_TREE_CAPTION :{WHITE}나무 STR_PLANT_TREE_TOOLTIP :{BLACK}심고싶은 나무의 종류를 선택합니다. 이미 나무가 심어져있는 경우에는 선택한 나무의 크기를 키웁니다 STR_TREES_RANDOM_TYPE :{BLACK}여러 종류의 나무 같이 심기 -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}여러 종류의 나무를 심습니다. SHIFT 키를 이용하면 예상 비용을 볼 수 있습니다 +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}여러 종류의 나무를 심습니다. CTRL 키를 누르면 대각선 방향의 영역을 선택할 수 있습니다. SHIFT 키를 이용하면 예상 비용을 볼 수 있습니다 STR_TREES_RANDOM_TREES_BUTTON :{BLACK}무작위로 나무 심기 STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}전 지역에 걸쳐 무작위로 나무를 심습니다 STR_TREES_MODE_NORMAL_BUTTON :{BLACK}일반 @@ -2861,6 +2858,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}무작 STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}무작위 위치에 도시를 건설합니다 STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}무작위로 여러 도시 건설 STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}무작위로 도시를 건설합니다 +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}모든 도시 확장 +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}모든 도시를 조금씩 확장시킵니다 STR_FOUND_TOWN_NAME_TITLE :{YELLOW}도시 이름: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}도시 이름 입력 @@ -3042,7 +3041,7 @@ STR_LAI_OBJECT_DESCRIPTION_COMPANY_OWNED_LAND :회사 소유 # About OpenTTD window STR_ABOUT_OPENTTD :{WHITE}OpenTTD에 대해서 STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Original copyright {COPYRIGHT} 1995 Chris Sawyer, All rights reserved -STR_ABOUT_VERSION :{BLACK}OpenTTD 버전 {REV} +STR_ABOUT_VERSION :{BLACK}OpenTTD {REV} 버전 STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-{STRING} OpenTTD 개발팀 # Framerate display window @@ -3125,7 +3124,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}게임 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_FILTER_TITLE :{BLACK}검색할 문자열: +STR_SAVELOAD_FILTER_TITLE :{BLACK}검색: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}파일 덮어쓰기 STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}정말로 이미 존재하는 파일에 덮어씌우시겠습니까? STR_SAVELOAD_DIRECTORY :{STRING} (폴더) @@ -3139,6 +3138,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}지도 STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}지도의 크기를 칸 수 기준으로 선택하세요. 사용 가능한 지도의 칸 수는 설정한 값보다 조금 작을 것입니다 STR_MAPGEN_BY :{BLACK}x STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}도시의 수: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}도시 이름: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}도시 이름 스타일을 선택하세요 STR_MAPGEN_DATE :{BLACK}날짜: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}산업시설 수: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}가장 높은 지점의 높이: @@ -3152,13 +3153,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}사막 STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}눈이 내린 곳의 비율을 10%p 줄입니다. STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}사막 지역의 비율을 10%p 줄입니다. STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}지형 만들기: STR_MAPGEN_TERRAIN_TYPE :{BLACK}지형 종류: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}해수면: +STR_MAPGEN_SEA_LEVEL :{BLACK}해수면: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}강: STR_MAPGEN_SMOOTHNESS :{BLACK}지표면을 깎는 방식: STR_MAPGEN_VARIETY :{BLACK}산세 험준도: STR_MAPGEN_GENERATE :{WHITE}만들기 +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF 설정 +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}NewGRF 설정 창을 엽니다 +STR_MAPGEN_AI_SETTINGS :{BLACK}인공지능 설정 +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}인공지능 설정 창을 엽니다 +STR_MAPGEN_GS_SETTINGS :{BLACK}게임 스크립트 설정 +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}게임 스크립트 설정 창을 엽니다 + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :영국 식 (기본) +STR_MAPGEN_TOWN_NAME_FRENCH :프랑스 식 +STR_MAPGEN_TOWN_NAME_GERMAN :독일 식 +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :영국 식 (추가) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :라틴아메리카 식 +STR_MAPGEN_TOWN_NAME_SILLY :바보같은 도시 이름 +STR_MAPGEN_TOWN_NAME_SWEDISH :스웨덴 식 +STR_MAPGEN_TOWN_NAME_DUTCH :네덜란드 식 +STR_MAPGEN_TOWN_NAME_FINNISH :핀란드 식 +STR_MAPGEN_TOWN_NAME_POLISH :폴란드 식 +STR_MAPGEN_TOWN_NAME_SLOVAK :슬로바키아 식 +STR_MAPGEN_TOWN_NAME_NORWEGIAN :노르웨이 식 +STR_MAPGEN_TOWN_NAME_HUNGARIAN :헝가리 식 +STR_MAPGEN_TOWN_NAME_AUSTRIAN :오스트리아 식 +STR_MAPGEN_TOWN_NAME_ROMANIAN :루마니아 식 +STR_MAPGEN_TOWN_NAME_CZECH :체코 식 +STR_MAPGEN_TOWN_NAME_SWISS :스위스 식 +STR_MAPGEN_TOWN_NAME_DANISH :덴마크 식 +STR_MAPGEN_TOWN_NAME_TURKISH :터키 식 +STR_MAPGEN_TOWN_NAME_ITALIAN :이탈리아 식 +STR_MAPGEN_TOWN_NAME_CATALAN :카탈로니아 식 # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}지도 가장자리: @@ -3217,7 +3246,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}NewGRF STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}적용한 NewGRF 파일 STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}적용하지 않은 NewGRF 파일 STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}프리셋 선택: -STR_NEWGRF_FILTER_TITLE :{ORANGE}검색할 문자열: +STR_NEWGRF_FILTER_TITLE :{ORANGE}검색: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}선택한 프리셋을 불러옵니다 STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}프리셋 저장 STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}현재 목록을 프리셋으로 저장합니다 @@ -3304,6 +3333,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}이전 STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}(유사/재색상/글씨 스프라이트를 제외한) 이전 보통 스프라이트로 이동하고, 첫 번째 스프라이트에 다다르면 마지막으로 돌아갑니다. STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}현재 선택된 스프라이트를 표현합니다. 이 스프라이트를 표현할 때, 정렬 상태는 무시하고 표현합니다. STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}X축이나 Y축 방향으로 스프라이트를 이동시킵니다. CTRL+클릭하면 한 번에 8씩 이동시킬 수 있습니다 + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}오프셋 가운데 정렬 +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}스프라이트 가운데 정렬 + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}십자선 + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}상대값 초기화 STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}현재 상대값 좌표를 초기화 STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X 좌표: {NUM}, Y 좌표: {NUM} (절댓값) @@ -3318,15 +3354,15 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}경고: {SILVER}{STRING} 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_FATAL_POPUP :{WHITE}NewGRF "{STRING}"에서 치명적인 오류가 발생했습니다:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF "{STRING}"에서 오류가 발생했습니다:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING}{G 1 "은" "는"} OpenTTD에서 보고된 TTDPatch 버전에서 작동하지 않을 것입니다 -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING}{G 1 "은" "는"} {STRING} 버전의 TTD를 위한 것입니다 -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING}{G 1 "은" "는"} {STRING}{G 1 "와" "과"} 같이 사용해야 합니다 -STR_NEWGRF_ERROR_INVALID_PARAMETER :{1:STRING}의 매개 변숫값이 유효하지 않습니다: {STRING}번 변수 ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING}{G 1 "은" "는"} 반드시 {STRING} 앞에 불러와야 합니다 -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING}{G 1 "은" "는"} 반드시 {STRING} 뒤에 불러와야 합니다 -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING}{G 1 "은" "는"} OpenTTD {STRING} 버전이나 그 이상이 필요합니다 +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING}{G 1 "은" "는"} {2:STRING} 버전의 TTD를 위한 것입니다 +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING}{G 1 "은" "는"} {2:STRING}{G 1 "와" "과"} 같이 사용해야 합니다 +STR_NEWGRF_ERROR_INVALID_PARAMETER :{1:STRING}의 매개 변숫값이 잘못되었습니다: {2:STRING}번 변수 ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING}{G 1 "은" "는"} 반드시 {2:STRING}보다 앞에 불러와야 합니다 +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING}{G 1 "은" "는"} 반드시 {2:STRING}보다 뒤에 불러와야 합니다 +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING}{G 1 "은" "는"} OpenTTD {2:STRING} 버전이나 그 이상이 필요합니다 STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF 파일이 번역을 위해 만들어졌습니다 STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :NewGRF가 너무 많습니다 STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :{2:STRING}{G 2 "을" "를"} 포함한 정적 NewGRF {1:STRING}{G 1 "을" "를"} 불러오는 것은 비동기화를 일으킬 수 있습니다 @@ -3367,7 +3403,7 @@ STR_NEWGRF_BROKEN :{WHITE}'{0:STRI STR_NEWGRF_BROKEN_POWERED_WAGON :{WHITE}차고지 안에 있지 않은 '{1:ENGINE}' 동력 차량의 상태가 바뀌었습니다 STR_NEWGRF_BROKEN_VEHICLE_LENGTH :{WHITE}'{1:ENGINE}'{G 1 "이" "가"} 차고지 안에 있지 않으면 차량 길이가 바뀝니다 STR_NEWGRF_BROKEN_CAPACITY :{WHITE}차량이 기지 안에 있지 않거나 개조가 불가능한 상태에서 '{1:ENGINE}'의 수송량이 변경되었습니다 -STR_BROKEN_VEHICLE_LENGTH :{WHITE}'{1:COMPANY}'에 속한 열차 '{0:VEHICLE}'의 길이가 잘못된 값을 가지고 있습니다. NewGRF에 의한 문제로 보입니다. 게임이 비동기화 또는 충돌을 일으킬 수 있습니다. +STR_BROKEN_VEHICLE_LENGTH :{WHITE}'{1:COMPANY}'에 속한 열차 '{0:VEHICLE}'의 길이가 잘못된 값을 가지고 있습니다. NewGRF에 의한 문제로 보입니다. 게임이 비동기화 또는 충돌을 일으킬 수 있습니다 STR_NEWGRF_BUGGY :{WHITE}NewGRF '{STRING}'에서 잘못된 정보를 제공하고 있습니다 STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}{1:ENGINE}(을)를 만들기 이전과 이후의 화물/개조 정보가 현재의 구매 목록과 다릅니다. 이 경우 자동 교체시 열차 개조에 실패할 수도 있습니다 @@ -3461,14 +3497,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :수송 권한 STR_LOCAL_AUTHORITY_ACTION_BRIBE :지역 당국에게 뇌물 주기 ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}더 많은 승객과 화물을 유치하기 위해 소규모의 광고 캠페인을 시작합니다.{}도시 중심 주위의 좁은 반경 안에 있는 역 등급을 일시적으로 올려줍니다.{}가격: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}더 많은 승객과 화물을 유치하기 위해 중간 규모의 광고 캠페인을 시작합니다.{}도시 중심 주위의 적당한 반경 안에 있는 역 등급을 일시적으로 올려줍니다.{}가격: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}더 많은 승객과 화물을 유치하기 위해 대규모의 광고 캠페인을 시작합니다.{}도시 중심 주위의 넓은 반경 안에 있는 역 등급을 일시적으로 올려줍니다.{}가격: {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}1년 간 수송 권한 독점권을 구입합니다.{}도시 당국은 오직 당신 회사의 역에만 승객과 화물을 실을 것입니다.{}가격: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}성취도를 올리기 위해 처벌을 감수하고 지역 당국에 뇌물을 줍니다.{}가격: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}더 많은 승객과 화물을 유치하기 위해 소규모의 광고 캠페인을 시작합니다.{}도시 중심 주위의 좁은 반경 안에 있는 역 등급을 일시적으로 올려줍니다.{}{POP_COLOUR}가격: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}더 많은 승객과 화물을 유치하기 위해 중간 규모의 광고 캠페인을 시작합니다.{}도시 중심 주위의 적당한 반경 안에 있는 역 등급을 일시적으로 올려줍니다.{}{POP_COLOUR}가격: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}더 많은 승객과 화물을 유치하기 위해 대규모의 광고 캠페인을 시작합니다.{}도시 중심 주위의 넓은 반경 안에 있는 역 등급을 일시적으로 올려줍니다.{}{POP_COLOUR}가격: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}도시 도로망 보수공사를 시행합니다.{}앞으로 6개월간 극심한 도로 혼잡을 일으킵니다.{}{POP_COLOUR}가격: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}당신의 회사를 대표하는 '명예의 동상'을 건설합니다.{}이 도시에 있는 역 등급을 영구적으로 올려줍니다.{}{POP_COLOUR}가격: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}도시 상업 건물의 건설에 투자합니다.{}도시의 성장을 일시적으로 빠르게 만들어줍니다.{}{POP_COLOUR}가격: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}1년 간 수송 권한 독점권을 구입합니다.{}도시 당국은 오직 당신 회사의 역에만 승객과 화물을 실을 것입니다.{}{POP_COLOUR}가격: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}성취도를 올리기 위해 처벌을 감수하고 지역 당국에 뇌물을 줍니다.{}{POP_COLOUR}가격: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} 목표 @@ -3641,15 +3677,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}선박 STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}이자 STR_FINANCES_SECTION_OTHER :{GOLD}기타 +STR_FINANCES_TOTAL_CAPTION :{WHITE}종합 STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}순이익 +STR_FINANCES_PROFIT :{WHITE}이익 STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}현 보유 금액 STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}보유 자금 STR_FINANCES_LOAN_TITLE :{WHITE}대출 STR_FINANCES_INTEREST_RATE :{WHITE}대출 금리: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}최대 대출: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}{CURRENCY_LONG} 빌리기 STR_FINANCES_BORROW_TOOLTIP :{BLACK}돈을 빌립니다. CTRL+클릭하면 빌릴 수 있는 만큼 빌립니다 STR_FINANCES_REPAY_BUTTON :{BLACK}{CURRENCY_LONG} 갚기 @@ -3750,7 +3789,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}생산 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 :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} 대기 중{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}생산량 변경 (8의 배수, 최대 2040) @@ -3780,6 +3819,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}이 목 STR_VEHICLE_LIST_REPLACE_VEHICLES :차량 교체 STR_VEHICLE_LIST_SEND_FOR_SERVICING :점검하러 보내기 STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}올해 이익: {CURRENCY_LONG} (작년: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :차량기지로 보내기 STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :차고지로 보내기 @@ -3871,6 +3912,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}최고 STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}항속거리: {GOLD}{COMMA}칸 STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}항공기 종류: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :모든 화물 종류 +STR_CARGO_TYPE_FILTER_FREIGHT :화물 +STR_CARGO_TYPE_FILTER_NONE :없음 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}열차 차량 구매 목록입니다. 차량의 정보를 보려면 클릭하세요. CTRL+클릭하면 해당 차량을 숨김/표시 처리할 수 있습니다 STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}차량 구매 목록입니다. 차량의 정보를 보려면 클릭하세요. CTRL+클릭하면 해당 차량을 숨김/표시 처리할 수 있습니다 @@ -4039,7 +4085,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :{G=f}항공기 STR_ENGINE_PREVIEW_SHIP :{G=m}선박 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_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}가격: {0:CURRENCY_LONG} 무게: {1:WEIGHT_SHORT}{}속력: {2:VELOCITY} 힘: {3: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_CAP_CAP_RUNCOST :{BLACK}가격: {CURRENCY_LONG} 최고 속력: {VELOCITY}{}항공기 종류: {STRING}{}수송량: {CARGO_LONG}, {CARGO_LONG}{}유지비: {CURRENCY_LONG}/년 STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}가격: {CURRENCY_LONG} 최고 속력: {VELOCITY}{}항공기 종류: {STRING}{}수송량: {CARGO_LONG}{}유지비: {CURRENCY_LONG}/년 @@ -4198,12 +4244,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}무게: STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}무게: {LTBLUE}{WEIGHT_SHORT} {BLACK}힘: {LTBLUE}{POWER}{BLACK} 최고 속력: {LTBLUE}{VELOCITY} {BLACK}최고 견인력: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}올해 이익: {LTBLUE}{CURRENCY_LONG} (작년: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}올해 이익: {LTBLUE}{CURRENCY_LONG} (작년: {CURRENCY_LONG}) {BLACK}최소 성능: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}신뢰도: {LTBLUE}{COMMA}% {BLACK}최근 점검 이후 고장 횟수: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}생산: {LTBLUE}{NUM}{BLACK} 가격: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}수송량: {LTBLUE}없음{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}수송량: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}수송량: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}수송량: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}수송량: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}수송량: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}환승 수익: {LTBLUE}{CURRENCY_LONG} @@ -4472,22 +4519,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}시작 STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}이 시간표의 시작 날짜를 선택하세요. CTRL+클릭하면, 시간표가 모두 작성되어 있다는 가정 하에, 주어진 경로를 기반으로 설정한 날짜부터 이 경로를 공유하는 모든 차량을 균등하게 출발시킵니다 STR_TIMETABLE_CHANGE_TIME :{BLACK}시간값 변경 -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}선택한 경로에서 소요되는 시간 값을 변경합니다 +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}선택한 경로에서 소요되는 시간 값을 변경합니다. CTRL+클릭하면 모든 경로에 그 시간 값을 설정합니다 STR_TIMETABLE_CLEAR_TIME :{BLACK}시간값 초기화 -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}선택한 경로에서 소요되는 시간 값을 초기화합니다 +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}선택한 경로에서 소요되는 시간 값을 초기화합니다. CTRL+클릭하면 모든 경로의 시간을 초기화합니다 STR_TIMETABLE_CHANGE_SPEED :{BLACK}속력 제한 -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}선택한 경로의 최대 여행 속력을 제한합니다 +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}선택한 경로의 최대 여행 속력을 제한합니다. CTRL+클릭하면 모든 경로에 그 속력 값을 설정합니다 STR_TIMETABLE_CLEAR_SPEED :{BLACK}속력 제한값 초기화 -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}선택한 경로의 최대 여행 속력 제한값을 초기화합니다 +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}선택한 경로의 최대 여행 속력 제한값을 초기화합니다. CTRL+클릭하면 모든 경로의 속력을 초기화합니다 STR_TIMETABLE_RESET_LATENESS :{BLACK}지연 시간 초기화 -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}이 차량의 지연 시간값을 초기화하여, 정시운행 상태로 바꿉니다 +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}이 차량의 지연 시간 값을 초기화하여, 정시운행 상태로 바꿉니다. CTRL+클릭하면 전체 그룹을 초기화하여 마지막 차량은 정시에, 나머지 차량은 조착하게 됩니다. STR_TIMETABLE_AUTOFILL :{BLACK}자동 시간 설정 -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}다음 운행시 자동으로 값을 얻어 시간표를 완성합니다 (역에 머무르는 시간값을 유지하려면 CTRL+클릭하십시오) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}다음 운행시 자동으로 값을 얻어 시간표를 완성합니다. 역에 머무르는 시간값을 유지하려면 CTRL+클릭하세요 STR_TIMETABLE_EXPECTED :{BLACK}예정일 기준 STR_TIMETABLE_SCHEDULED :{BLACK}예정 소요시간 기준 @@ -4522,7 +4569,7 @@ STR_AI_DEBUG_MATCH_CASE :{BLACK}대소 STR_AI_DEBUG_MATCH_CASE_TOOLTIP :{BLACK}인공지능 기록 메시지에서 중단 문구를 검색할 때 대소문자를 구분할지 여부를 선택합니다 STR_AI_DEBUG_CONTINUE :{BLACK}계속 STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}중단된 인공지능의 연산을 재개합니다 -STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}이 인공지능에서 출력된 기록 메시지를 보여줍니다. +STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}이 인공지능에서 출력된 기록 메시지를 보여줍니다 STR_AI_GAME_SCRIPT :{BLACK}게임 스크립트 STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}게임 스크립트 기록 체크 @@ -4531,12 +4578,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}작동 STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}인공지능/게임 스크립트 디버그창은 오직 서버만 사용 가능합니다 # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}인공지능 / 게임 스크립트 설정 +STR_AI_CONFIG_CAPTION_AI :{WHITE}인공지능 설정 +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}게임 스크립트 설정 STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}다음에 게임을 시작할 때 이 게임 스크립트를 불러올 것입니다 STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}다음에 게임을 시작할 때 이 인공지능을 불러올 것입니다 STR_AI_CONFIG_HUMAN_PLAYER :사용자 플레이어 STR_AI_CONFIG_RANDOM_AI :무작위 인공지능 STR_AI_CONFIG_NONE :(없음) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}최대 경쟁자수: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}위로 이동 STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}목록에서 선택한 인공지능의 순서를 한 칸 위로 옮깁니다 @@ -4544,13 +4593,12 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}아래 STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}목록에서 선택한 인공지능의 순서를 한 칸 아래로 옮깁니다 STR_AI_CONFIG_GAMESCRIPT :{SILVER}게임 스크립트 +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}매개 변수 STR_AI_CONFIG_AI :{SILVER}인공지능 -STR_AI_CONFIG_CHANGE :{BLACK}{STRING} 선택하기 -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :인공지능 -STR_AI_CONFIG_CHANGE_GAMESCRIPT :게임 스크립트 -STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}다른 스크립트 불러오기 +STR_AI_CONFIG_CHANGE_AI :{BLACK}인공지능을 선택하세요 +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}게임 스크립트 선택 +STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}다른 게임 스크립트를 불러옵니다 STR_AI_CONFIG_CONFIGURE :{BLACK}설정 STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}인공지능의 매개 변수를 설정합니다 @@ -4577,7 +4625,7 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}지도 STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}높이맵 스크린 샷 STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}미니맵 스크린 샷 -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} 매개 변수 STR_AI_SETTINGS_CAPTION_AI :인공지능 STR_AI_SETTINGS_CAPTION_GAMESCRIPT :게임 스크립트 @@ -4689,7 +4737,7 @@ 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}{G 1 "이" "가"} 있습니다. +STR_ERROR_GENERIC_OBJECT_IN_THE_WAY :{WHITE}중간에 {1:STRING}{G 1 "이" "가"} 있습니다 STR_ERROR_NOT_ALLOWED_WHILE_PAUSED :{WHITE}일시 정지 중에는 할 수 없습니다 # Local authority errors @@ -4744,6 +4792,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... 산 STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}산업시설을 생성할 수 없습니다... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}여기에 {STRING}{G 0 "을" "를"} 건설할 수 없습니다... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}여기에 산업시설을 건설할 수 없습니다... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}산업시설에 투자할 수 없습니다... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... 다른 산업시설과 너무 가깝습니다 STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... 도시를 먼저 만들어야 합니다 STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... 한 도시에 하나만 지을 수 있습니다 @@ -4758,6 +4807,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... 숲 STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... 만년설 고도 위에만 지을 수 있습니다 STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... 만년설 고도 아래에만 지을 수 있습니다 +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}운이 나빠 투자에 실패했습니다. 다시 시도해주세요. +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}이 산업시설을 투자하기에 적합한 장소가 없습니다 STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}적당한 장소가 없어 '{STRING}'{G 0 "이" "가"} 지어지지 않았습니다 STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}더 나은 지도가 생성되도록 설정 값을 변경해보십시오 @@ -4854,7 +4905,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}신호 STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}적합한 철도 선로가 없습니다 STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}선로를 먼저 제거하십시오 STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}도로가 일방통행이거나 막혔습니다 -STR_ERROR_CROSSING_DISALLOWED_RAIL :{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}여기에 선로를 건설할 수 없습니다... @@ -4925,6 +4976,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}중간 STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... 중간에 회사 본사가 있습니다 STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}이 지역을 매입할 수 없습니다... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... 이미 소유중입니다! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... 오브젝트 건설 제한에 다다랐습니다 # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}그룹을 만들 수 없습니다... @@ -4997,6 +5049,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}점검 STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... 차량이 파괴되었습니다 +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... 동일한 구성이 아닌 차량이 있습니다 + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}사용할 수 있는 차량이 모두 없어질 것입니다 STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}NewGRF 설정을 변경하십시오 STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}사용할 수 있는 차량이 하나도 없습니다 @@ -5023,6 +5077,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}선택 STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... 차량이 모든 정거장에 갈 수 없습니다 STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... 차량이 그 정거장에 갈 수 없습니다 STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... 경로를 공유하고 있는 차량이 그 정거장에 갈 수 없습니다 +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... 같은 경로를 가지고 있지 않은 차량이 하나 이상 있습니다 +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... 경로를 공유하지 않은 차량이 하나 이상 있습니다 STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}경로를 공유할 수 없습니다... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}경로 공유를 중단할 수 없습니다... @@ -5030,6 +5086,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}경로 STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... 이전 목적지에서 너무 멀리 떨어져 있습니다 STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... 항공기의 항속거리가 충분하지 않습니다. +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}철도 역이 없습니다 +STR_ERROR_NO_BUS_STATION :{WHITE}버스 정류장이 없습니다 +STR_ERROR_NO_TRUCK_STATION :{WHITE}트럭 적하장이 없습니다 +STR_ERROR_NO_DOCK :{WHITE}항구가 없습니다 +STR_ERROR_NO_AIRPORT :{WHITE}공항/헬리포트가 없습니다 +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}이 도로 종류와 호환 가능한 정류장이 없습니다 +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}이 전차 선로 종류와 호환 가능한 정류장이 없습니다 +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}굴절형 자동차가 이용할 수 있는 정류장이 없습니다.{}굴절형 자동차는 터미널식 정류장이 아니라 통과식 정류장을 사용해야 합니다 +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}이 항공기는 이 공항에 착륙할 수 없습니다 +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}이 헬리콥터는 이 공항에 착륙할 수 없습니다 +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}철도 경유지가 없습니다 +STR_ERROR_NO_BUOY :{WHITE}부표가 없습니다 + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}차량의 시간표를 정할 수 없습니다... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}차량은 정거장에서만 기다릴 수 있습니다 diff --git a/src/lang/latin.txt b/src/lang/latin.txt index dad114551ef23..a6d4dd8bcb551 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -387,6 +387,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -564,10 +565,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Exire # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Ludi optiones STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Electiones -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Optiones IA/Ludi scriptorum STR_SETTINGS_MENU_NEWGRF_SETTINGS :Optiones NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Optiones perluciditatis STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Nomina oppidorum spectabilia @@ -1121,36 +1121,6 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Lari Georgiana STR_GAME_OPTIONS_CURRENCY_IRR :Regalis Iranica (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Novus Rubelus Russicus (RUB) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Gubernantur sinistro -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Gubernantur dextro - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nomina oppidorum -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Eligere oppidorum nomina - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Anglica (Primigenia) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francogallica -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Theodisca -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Anglica (Additicia) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Americae Latinae -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Ridicula -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Suecica -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Batavica -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finnica -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polonica -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovaca -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norvegica -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungarica -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austriaca -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romanica -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Cecha -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Helvetica -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danica -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turcica -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiana -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalana - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Servare automatice STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Eligere crebritatem automatice ludum servandi @@ -1175,19 +1145,8 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :alia -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Magnitudo interfaciei -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Eligere magnitudinem interfaciei adhibendam -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Simplex -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Duplex -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quadruplex -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Magnitudo Litterarum -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Eligere magnitudinem litterarum adhibendam - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Simplex -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Duplex -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quadruplex @@ -1234,8 +1193,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Praevis STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}Copia nummi tui quae aequa est 10000 Librae Britannicae (£) STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Mutare parametrum nummi proprii -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Numerus competitorum maximus: {ORANGE}{COMMA} - STR_NONE :Nullae STR_FUNDING_ONLY :Modo conditu STR_MINIMAL :Minimus @@ -1285,6 +1242,12 @@ STR_SUBSIDY_X2 :Duplex STR_SUBSIDY_X3 :Triplex STR_SUBSIDY_X4 :Quadruplex +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Terra temperata +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Terra subarctica +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Terra subtropica +STR_CLIMATE_TOYLAND_LANDSCAPE :Terra ludicrorum + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Planissimus STR_TERRAIN_TYPE_FLAT :Planus @@ -1358,6 +1321,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Dextro STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Creditum maximum in initio: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Copia crediti maxima (sine inflatione) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Proportio faenoris: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Proportio faenoris creditorum; etiam inflationem afficit, si inflatio adest @@ -1621,6 +1585,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Melior STR_CONFIG_SETTING_ROAD_SIDE :Vehicula viaria: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Eligere latus viae gubernandi +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Gubernantur sinistro +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Gubernantur dextro + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotatio tabulae altitudinum: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Sinistrorsus @@ -2107,7 +2075,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Reversio automa STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Sinere tramina reverti apud signale, si illic valde morati sunt ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Commendatum) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Commendatum) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Mutare valorem optionis @@ -2148,7 +2116,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Album Pu STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Electiones STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Optiones STR_INTRO_ONLINE_CONTENT :{BLACK}Inspicere Inventarium Interretiale -STR_INTRO_SCRIPT_SETTINGS :{BLACK}IA/Ludi Scriptorum Optiones STR_INTRO_QUIT :{BLACK}Exire STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Incipere novum ludum. Ctrl+Preme ut configuratio tabulae omittatur @@ -2168,7 +2135,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Monstrar STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Monstrare electiones STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Monstrare optiones NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Inspicere inventarium Interretiale in quo res sicut NewGRF, scaenaria, musica, etc. sunt -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Monstrare optiones IA/Ludi scriptorum STR_INTRO_TOOLTIP_QUIT :{BLACK}Exire OpenTTD STR_INTRO_BASESET :{BLACK}Hoc fundamento graphico desunt spiritus {NUM}. Quaere novam editionem huius fundamenti. @@ -2198,12 +2164,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Mutare STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Mutare annum currentem STR_CHEAT_SETUP_PROD :{LTBLUE}Sinere mutare productiones industriarum: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Terra temperata -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Terra subarctica -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Terra subtropica -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Terra ludicrorum - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} Schema Coloris @@ -2613,6 +2573,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}satur STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}superoneratus +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Regio Acceptionis STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Celata @@ -2705,8 +2667,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Augere i STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Eligere Pontem Ferriviarium STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Eligere Pontem Viarium STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Electio pontium - preme in pontem delectum ut struatur -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Pendulus, Chalybeius STR_BRIDGE_NAME_GIRDER_STEEL :Trabum, Chalybeius STR_BRIDGE_NAME_CANTILEVER_STEEL :Prominens, Chalybeius @@ -3071,16 +3031,40 @@ STR_MAPGEN_MAPSIZE :{BLACK}Tabulae STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Eligere magnitudinem tegularum tabulae geographicae. Tegulae parabiles fere minores erunt STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Numerus oppidorum: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nomina oppidorum +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Eligere oppidorum nomina STR_MAPGEN_DATE :{BLACK}Dies: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Numerus industriarum: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Generatrum terrae: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Typus terrae: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Magnitudo maris: +STR_MAPGEN_SEA_LEVEL :{BLACK}Magnitudo maris: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Numerus fluviorum: STR_MAPGEN_SMOOTHNESS :{BLACK}Lenitas: STR_MAPGEN_VARIETY :{BLACK}Partitio Varietatis: STR_MAPGEN_GENERATE :{WHITE}Creare +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Anglica (Primigenia) +STR_MAPGEN_TOWN_NAME_FRENCH :Francogallica +STR_MAPGEN_TOWN_NAME_GERMAN :Theodisca +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Anglica (Additicia) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Americae Latinae +STR_MAPGEN_TOWN_NAME_SILLY :Ridicula +STR_MAPGEN_TOWN_NAME_SWEDISH :Suecica +STR_MAPGEN_TOWN_NAME_DUTCH :Batavica +STR_MAPGEN_TOWN_NAME_FINNISH :Finnica +STR_MAPGEN_TOWN_NAME_POLISH :Polonica +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovaca +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norvegica +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungarica +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austriaca +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romanica +STR_MAPGEN_TOWN_NAME_CZECH :Cecha +STR_MAPGEN_TOWN_NAME_SWISS :Helvetica +STR_MAPGEN_TOWN_NAME_DANISH :Danica +STR_MAPGEN_TOWN_NAME_TURKISH :Turcica +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiana +STR_MAPGEN_TOWN_NAME_CATALAN :Catalana + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Fines tabulae: STR_MAPGEN_NORTHWEST :{BLACK}Corus @@ -3221,6 +3205,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Spiritum STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Ire ad spiritum naturalem priorem et, termino contacto, ad ultimum revertere STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Imago spiritus electi. Directio neglegitur cum hic spiritus pingitur STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Movere spiritum mutatione X et Y incrementa. Ctrl+Preme ut spiritus octoni incrementa moveatur + +###length 2 + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Reponere relativas STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Reponere positiones relativas STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Positio X: {NUM}, Positio Y: {NUM} (Absolutae) @@ -3235,7 +3223,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Cautio: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Error: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Error Fatalis: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Error NewGRF fatalis:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} non operat apud editionem TTDPatch ab OpenTTD dicta STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} spectat ad editionem {STRING} TTD STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} spectat ad {STRING} @@ -3753,6 +3740,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Vis Trac STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Max. distantia volatus: {GOLD}{COMMA} tegulas STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Typus aeroplani: {GOLD}{STRING} +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Index electionis vehiculorum ferriviariorum. Preme in vehiculum ut plura indicia monstrentur. Ctrl+Preme ut typus vehiculi celetur STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Index electionis vehiculorum viariorum. Preme in vehiculum ut plura indicia monstrentur. Ctrl+Preme ut typus vehiculi celetur @@ -4393,12 +4382,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Unum cur STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Fenestra Emendationis IA/Ludi Scripti tantum servatro licet uti # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Configuratio IA/Ludi Scriptum STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Ludi Scriptum quod imponet ludo proximo STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}IA quae imponet ludo proximo STR_AI_CONFIG_HUMAN_PLAYER :Lusor humanus STR_AI_CONFIG_RANDOM_AI :IA Fortuita STR_AI_CONFIG_NONE :(nullum) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Numerus competitorum maximus: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Sursum Movere STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Movere IA electam sursum in indice @@ -4408,8 +4397,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Movere I STR_AI_CONFIG_GAMESCRIPT :{SILVER}Ludi Scriptum STR_AI_CONFIG_AI :{SILVER}AI -STR_AI_CONFIG_CHANGE :{BLACK}Eligere {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :IA STR_AI_CONFIG_CHANGE_GAMESCRIPT :Scriptum STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Legere aliud ludi scriptum @@ -4432,10 +4419,8 @@ STR_AI_LIST_CANCEL :{BLACK}Cancella STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Non scriptum mutare -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametra +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :IA -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Ludi Scripti STR_AI_SETTINGS_CLOSE :{BLACK}Claudere STR_AI_SETTINGS_RESET :{BLACK}Revertere STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4841,6 +4826,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Non lice STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vehiculum est destructum! + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Nulla vehicula omnino parabilia erunt STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Muta configurationem NewGRF tuam STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Nulla vehicula adhuc parabilia sunt @@ -4874,6 +4860,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Non lice STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... nimis procul a destinato priore STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... aeroplano non est satis distantia volatus +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Non licet vehiculo dare horarium... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Vehicula modo in stationibus possunt manere diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index 56fbc39d04323..aa91285dd442d 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -202,6 +202,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}ZS STR_UNITS_POWER_METRIC :{COMMA}{NBSP}ZS STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}zs/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}zs/l +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}zs/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}zs/l +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}zs/l +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}zs/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/l +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -227,9 +237,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filtra virkne: -STR_LIST_FILTER_OSKTITLE :{BLACK}Ievadīt filtra virkni -STR_LIST_FILTER_TOOLTIP :{BLACK}Ievadīt atslēgvārdu, lai filtrētu sarakstu +STR_LIST_FILTER_TITLE :{BLACK}Filters: +STR_LIST_FILTER_OSKTITLE :{BLACK}Ievadiet vienu vai vairākus atslēgvārdus, lai filtrētu sarakstu +STR_LIST_FILTER_TOOLTIP :{BLACK}Ievadiet vienu vai vairākus atslēgvārdus, lai filtrētu sarakstu STR_TOOLTIP_GROUP_ORDER :{BLACK}Izvēlēties grupēšanas kārtību STR_TOOLTIP_SORT_ORDER :{BLACK}Izvēlēties kārtošanas secību (dilstoša/augoša) @@ -380,7 +390,7 @@ STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Ceļu b STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Tramvaju sliežu ceļu būvniecība STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Stādīt kokus. Shift pārslēdz būvēšanu/izmaksu tāmes rādīšanu STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Novietot zīmi -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Novietot objektu. Shift pārslēdz būvēšanu/izmaksu tāmes rādīšanu +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Novietojiet objektu. Ctrl atlasa apgabalu pa diagonāli. Shift pārslēdz ēku/rāda izmaksu tāmi # Scenario editor file menu ###length 7 @@ -393,10 +403,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Iziet # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Spēles opcijas STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Iestatījumi -STR_SETTINGS_MENU_SCRIPT_SETTINGS :MI/spēles skriptu iestatījumi +STR_SETTINGS_MENU_AI_SETTINGS :AI iestatījumi +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Spēles skripta iestatījumi STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF iestatījumi STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Caurspīdības opcijas STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Rādīt pilsētu nosaukumus @@ -967,36 +978,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indijas rūpija STR_GAME_OPTIONS_CURRENCY_IDR :Indonēzijas rūpija (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaizijas Ringits (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Brauc pa kreiso pusi -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Brauc pa labo pusi - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Pilsētu nosaukumi: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Pilsētu nosaukumu stila izvēle - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Angļu (sākotnējie) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Franču -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Vācu -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Angļu (papildu) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latīņamerikāņu -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Muļķīgie -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Zviedru -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holandiešu -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Somu -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Poļu -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovāku -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norvēģu -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungāru -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austriešu -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumāņu -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Čehu -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Šveiciešu -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dāņu -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turku -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Itāļu -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalāņu - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automātiskā saglabāšana STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Izvēlēties spēles automātiskās saglabāšanas starplaikus @@ -1027,22 +1008,21 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Šis ies STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Atzīmējiet šo izvēlni, lai sinhronizētu ekrānu. Mainīts iestatījums tiks piemērots tikai pēc spēles restartēšanas. Darbojas tikai ar iespējotu aparatūras paātrinājumu +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Esošais vadītājs: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Lietotāja saskarnes lielums -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Lietotāja saskarnes elementu lieluma izvēle +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Saskarnes izmērs +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Velciet slīdni, lai iestatītu interfeisa izmēru. Turiet nospiestu taustiņu Ctrl, lai veiktu nepārtrauktu regulēšanu +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Automātiski noteikt izmēru +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Atzīmējiet šo izvēlni, lai automātiski noteiktu interfeisa izmēru -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(automātiski noteikt) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Parasts -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Divkāršs -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Četrkāršs +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Mēroga slīpumi +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Atzīmējiet šo izvēlni, lai mērogotu slīpumu pēc saskarnes lieluma -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Fonta izmērs -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Izvēlieties saskarnes fonta izmēru - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(automātiski noteikt) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normāls -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Divkāršs izmērs -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Četrkāršs izmērs +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafika @@ -1094,8 +1074,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Priekš STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 mārciņas (£) jūsu valūtā STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Mainīt pielāgotās valūtas rādītāju -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimālais sāncenšu daudzums: {ORANGE}{COMMA} - STR_NONE :Nav STR_FUNDING_ONLY :Tikai līdzekļu piešķiršana STR_MINIMAL :Minimāls @@ -1145,6 +1123,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Mērena klimata ainava +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subarktikas klimata ainava +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Subtropu klimata ainava +STR_CLIMATE_TOYLAND_LANDSCAPE :Rotaļlietu zemes ainava + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Ļoti līdzens STR_TERRAIN_TYPE_FLAT :Līdzens @@ -1155,15 +1139,16 @@ STR_TERRAIN_TYPE_CUSTOM :Pielāgots augs STR_TERRAIN_TYPE_CUSTOM_VALUE :Pielāgots augstums ({NUM}) ###length 4 +STR_CITY_APPROVAL_LENIENT :Mīksts STR_CITY_APPROVAL_TOLERANT :iecietīga STR_CITY_APPROVAL_HOSTILE :naidīga -STR_CITY_APPROVAL_PERMISSIVE :pieļaujoša +STR_CITY_APPROVAL_PERMISSIVE :Pieļaujoša (nav efekta kompānijas darbībām) STR_WARNING_NO_SUITABLE_AI :{WHITE}Nav pieejami derīgi MI...{}Jūs varat lejuplādēt dažādus MI, izmantojot sistēmu 'Tiešsaistes saturs' # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Iestatījumi -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtra virkne: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrs: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Izvērst visu STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Sakļaut visu STR_CONFIG_SETTING_RESET_ALL :{BLACK}Atiestatīt visas vērtības @@ -1223,6 +1208,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :pa labi STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maksimālais sākotnējais aizdevums: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maksimālais aizdevuma daudzums, ko uzņēmums var izsniegt (neskaitot inflāciju) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Nav aizdevuma {RED}Lai nodrošinātu sākotnējos līdzekļus, ir nepieciešams spēles skripts STR_CONFIG_SETTING_INTEREST_RATE :Procentu likme: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Aizdevumu procentu likme; ja ieslēgts, ietekmē arī inflāciju @@ -1258,8 +1246,8 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Ja ieslēgts, s STR_CONFIG_SETTING_DISASTERS :Katastrofas: {STRING} STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Pārslēgt katastrofas, kas laiku pa laikam var bloķēt vai iznīcināt transportlīdzekļus un infrastruktūru -STR_CONFIG_SETTING_CITY_APPROVAL :Pilsētu domju attieksme pret platības pārstrukturēšanu: {STRING} -STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Izvēlieties, cik lielā mērā trokšņi un vides bojājumi ietekmē uzņēmuma reitingu un turpmākās būvniecības darbības viņu teritorijā +STR_CONFIG_SETTING_CITY_APPROVAL :Vietējās pašvaldības attieksme: {STRING} +STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Izvēlieties, cik lielā mērā trokšņi un vides bojājumi ietekmē uzņēmuma reitingu un turpmākās būvniecības darbības pilsētā STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :Kartes augstuma ierobežojums: {STRING} STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_HELPTEXT :Iestatiet kartes reljefa maksimālo augstumu. Izmantojot "(auto)", laba vērtība tiks izvēlēta pēc reljefa ģenerēšanas @@ -1449,6 +1437,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Diagrammu līni STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Rādīt jauno NewGRF paplašinājumu nosaukumus uzbūvēto transportlīdzekļu logā: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Uzbūvēto transportlīdzekļu loga pievienot rindu, kurā būtu redzams, no kura NewGRF nāk izvēlētais transportlīdzeklis. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Rādīt kravas, ko transportlīdzekļi var pārvadāt saraksta logos {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Ja iespējots, transportlīdzekļa transportējamā krava parādīsies virs tās transportlīdzekļu sarakstos STR_CONFIG_SETTING_LANDSCAPE :Ainava: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Ainavas nosaka pamata spēles scenārijus ar dažādām kravām un pilsētu izaugsmes nosacījumiem. NewGRF un spēles skripti dod smalkākas kontroles iespējas @@ -1503,6 +1493,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Uzlabotais STR_CONFIG_SETTING_ROAD_SIDE :Autotransporta līdzekļi: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Izvēlieties braukšanas pusi +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Brauc pa kreiso pusi +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Brauc pa labo pusi + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Augstumu kartes pagriešana: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Pret pulksteņa rādītāja virzienu @@ -1529,7 +1523,13 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :zaļa STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :{G=f}tumši zaļa STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :{G=f}violeta +STR_CONFIG_SETTING_LINKGRAPH_COLOURS :Kravas plūsmu pārklājuma krāsas: {STRING} +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_HELPTEXT :Iestatiet kravas plūsmu pārklājumam izmantoto krāsu shēmu. ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :Zaļš uz sarkanu (orģināli) +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Zaļš uz zilu +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Pelēks uz sarkanu +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :Pelēktonis STR_CONFIG_SETTING_SCROLLMODE :Skatvietas ritināšanas uzvedība: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Uzvedība, kad ritina karti @@ -1936,7 +1936,7 @@ STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"simetriska" no STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Izplatīšanas režīms APSARGĀJAMAI preču klasei: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :APSARGĀJAMĀ kravas klase satur vērtslietas mērenajā joslā, dimantus subtropu joslā un zeltu subarktiskajā joslā. NewGRF paplašinājumi var to mainīt. "simetriska" nozīmē, ka apmēram vienāds daudzums kravas tiks nosūtīts virzienā no stacijas A uz B, cik no B uz A. "asimetriska" nozīmē, ka patvaļīgs kravas daudzums var tikt nosūtīts katrā no virzieniem. "manuāli" nozīmē, ka pastam netiks veikta automātiska izplatīšana. Šo vērtību vēlams iestatīt kā asimetrisku vai manuālu, kad spēlē subarktiskajā joslā, jo bankas nesūta zeltu atpakaļ uz zelta raktuvēm. Mērenajā un subtropu joslā var izvēlēties simetrisku, jo bankas sūtīs vērtslietas atpakaļ uz izcelsmes banku, kad saņems vērtslietu pievedumu. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Izplatīšanas modelis citām kravu klasēm: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asimetriska" nozīmē, ka patvaļīgu kravas daudzumu var nosūtīt abos virzienos."manuāli" nozīmē, ka šīm kravām netiks veikta automātiska izplatīšana. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimetrisks" nozīmē, ka jebkurā virzienā var nosūtīt patvaļīgu daudzumu kravas. "Manuāli" nozīmē, ka šīm kravām automātiska sadale nenotiks ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuāli STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimetriska @@ -2033,7 +2033,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automātiska ap STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Atļauj vilcieniem apgriezties pie signālierīcēm, ja tie te ir gaidījuši ilgu laiku ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(ieteicamais) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(ieteicamais) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Mainīt iestatījuma vērtību @@ -2076,7 +2076,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Sasniegu STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Iestatījumi STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF iestatījumi STR_INTRO_ONLINE_CONTENT :{BLACK}Pārbaudīt tiešsaistes saturu -STR_INTRO_SCRIPT_SETTINGS :{BLACK}MI/spēles skriptu iestatījumi +STR_INTRO_AI_SETTINGS :{BLACK}AI Iestatījumi +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Spēles Skripta Iestatījumi STR_INTRO_QUIT :{BLACK}Iziet STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Sākt jaunu spēli. Ctrl+klikšķis izlaiž kartes konfigurēšanu @@ -2096,7 +2097,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Rādīt STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Displeja iestatījumi STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Rādīt NewGRF iestatījumus STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Pārbaudīt vai lejupielādei nav pieejams jauns un atjaunināts saturs -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Rādīt MI un spēles skriptu iestatījumus +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Parādīt AI iestatījumus +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Displeja spēles skripta iestatījumi STR_INTRO_TOOLTIP_QUIT :{BLACK}Iziet no 'OpenTTD' STR_INTRO_BASESET :{BLACK}Pašlaik izvēlētajai bāzes grafikas kopai trūkst {NUM} sprait{P s i u}. Lūdzu, pārbaudiet, vai bāzes kopai ir atjauninājumi. @@ -2128,12 +2130,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Nomain STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Mainīt pašreizējo gadu STR_CHEAT_SETUP_PROD :{LTBLUE}Ieslēgt ražojumu vērtības maiņu: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Mērena klimata ainava -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subarktikas klimata ainava -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Subtropu klimata ainava -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Rotaļlietu zemes ainava - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - krāsu shēma @@ -2366,7 +2362,6 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Jauna kompāni STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Izveidot jaunu kompāniju un pievienoties tai STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Tas esat jūs STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Šis ir spēles īpašnieks -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P s а u} / {NUM} kompānij{P a u as} # Matches ConnectionType ###length 5 @@ -2493,13 +2488,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :gaida uz saišu STR_NETWORK_MESSAGE_CLIENT_LEAVING :aizeju STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} ir pievienojies spēlei -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} ir pievienojies spēlei (Client #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} ir pievienojies uzņēmumam #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} ir pievienojies spēlei (Klients #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} ir pievienojies uzņēmumam Nr. {2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} ir pievienojies novērotājiem -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} ir nodibinājis jaunu uzņēmumu (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} ir pametis spēli ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} ir nodibinājis jaunu uzņēmumu (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} ir pametis spēli ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} ir mainījis nosaukumu uz {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} iedeva {2:CURRENCY_LONG} iekš {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} piešķīra {2:CURRENCY_LONG} uz {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Serveris beidza sesiju STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Serveris pārstartējas...{}Lūdzu uzgaidiet... STR_NETWORK_MESSAGE_KICKED :*** {STRING} tika izmests. Iemesls: ({STRING}) @@ -2613,6 +2608,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}piesātināts STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}pārslogots +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG}, kas jāpārvadā mēnesī no {STATION} uz {STATION} ({COMMA}% no parvadājuma){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} jātransportē atpakaļ ({COMMA}% no pārvadājuma) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Vidējais ceļojuma laiks: {NUM}{NBSP}dienas + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Pārklājuma iezīmēšana STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Nav @@ -2621,6 +2621,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Neiezīm STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Iezīmēt jaunceļamā objekta pārklājumu STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Pieņem: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Piegādā: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Uzturēšanas izmaksas: {GOLD}{CURRENCY_SHORT}/gadā # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Pievienot staciju @@ -2703,8 +2704,9 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Palielin STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Izvēlēties dzelzceļa tiltu STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Izvēlēties tiltu STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Tiltu izvēle - klikšķināt uz vēlamo tiltu, lai to uzbūvētu -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Vanšu, tērauda STR_BRIDGE_NAME_GIRDER_STEEL :Siju, tērauda STR_BRIDGE_NAME_CANTILEVER_STEEL :Izgriežamais, tērauda @@ -2808,11 +2810,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Ainavas STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Pazemināt zemes stūri. Vilkšana pazemina pirmo izvēlēto stūri un nolīdzina izvēlēto laukumu uz stūra jauno augstumu. Ctrl iezīmē laukumu diagonāli. Shift pārslēdz būvēšanu/izmaksu novērtējuma rādīšanu STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Pacelt zemes stūri. Vilkšana paceļ pirmo izvēlēto stūri un nolīdzina izvēlēto laukumu uz stūra jauno augstumu. Ctrl iezīmē laukumu diagonāli. Shift pārslēdz būvēšanu/izmaksu novērtējuma rādīšanu STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Izlīdzināt zemes laukumu pirmā izvēlētā stūra augstumā. Ctrl iezīmē laukumu diagonāli. Shift pārslēdz būvēšanu/izmaksu novērtējuma rādīšanu -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Pirkt zemi vēlākai lietošanai. Shift pārslēdz būvēšanu/izmaksu novērtējuma rādīšanu +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Iegādājieties zemi turpmākai lietošanai. Ctrl atlasa apgabalu pa diagonāli. Shift pārslēdz ēku/rāda izmaksu tāmi # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Objektu izvēle -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Izvēlēties objektu būvniecībai. Shift pārslēdz būvniecību/izmaksu attēlošanu +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Izvēlēlaties buvējamo objektu. Ctrl atlasa apgabalu pa diagonāli. Shift pārslēdz ēku/rāda izmaksu tāmi STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Izvēlēties būvējamā objekta klasi STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Objekta priekšskatījums STR_OBJECT_BUILD_SIZE :{BLACK}Izmērs: {GOLD}{NUM} x {NUM} lauciņi @@ -2856,6 +2858,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Nejauša STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Dibināt pilsētu nejaušā vietā STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Daudz nejauši izveidotu pilsētu STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Pārklāt karti ar nejauši izvietotām pilsētām +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Palielināt visas pilsētas +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Likt visām pilsētām nedaudz palielināties STR_FOUND_TOWN_NAME_TITLE :{YELLOW} Pilsētas nosaukums: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Ievadīt pilsētas nosaukumu @@ -3121,7 +3125,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Spēles STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Nav pieejamas informācijas STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtra virkne: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtrs: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Pārrakstīt datni STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Vai tiešām vēlaties pārrakstīt esošās datnes? STR_SAVELOAD_DIRECTORY :{STRING} (Vietne) @@ -3135,6 +3139,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kartes i STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Izvēlieties kartes izmēru, izteikts lauciņos. Pieejamo lauciņu skaits var būt nedaudz mazāks STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Pilsētu daudzums: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Pilsētu nosaukumi: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Pilsētu nosaukumu stila izvēle STR_MAPGEN_DATE :{BLACK}Datums: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Ražotņu daudzums: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Augstākā virsotne: @@ -3148,13 +3154,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Tuksneš STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Palielināt tuksneša pārklājumu par desmit procentiem STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Samazināt tuksneša pārklājumu par desmit procentiem STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Zemes radītājs: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Apvidus reljefs: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Jūras līmenis: +STR_MAPGEN_SEA_LEVEL :{BLACK}Jūras līmenis: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Upes: STR_MAPGEN_SMOOTHNESS :{BLACK}Gludums: STR_MAPGEN_VARIETY :{BLACK}Dažādības sadalījums: STR_MAPGEN_GENERATE :{WHITE}Radīt +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF Iestatījumi +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Rādīt NewGRF iestatījumus +STR_MAPGEN_AI_SETTINGS :{BLACK}AI iestatījumi +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Parādīt AI iestatījumus +STR_MAPGEN_GS_SETTINGS :{BLACK}Spēles skripta iestatījumi +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Rādīt spēles skripta iestatījumus + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Angļu (sākotnējie) +STR_MAPGEN_TOWN_NAME_FRENCH :Franču +STR_MAPGEN_TOWN_NAME_GERMAN :Vācu +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Angļu (papildu) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latīņamerikāņu +STR_MAPGEN_TOWN_NAME_SILLY :Muļķīgie +STR_MAPGEN_TOWN_NAME_SWEDISH :Zviedru +STR_MAPGEN_TOWN_NAME_DUTCH :Holandiešu +STR_MAPGEN_TOWN_NAME_FINNISH :Somu +STR_MAPGEN_TOWN_NAME_POLISH :Poļu +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovāku +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norvēģu +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungāru +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austriešu +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumāņu +STR_MAPGEN_TOWN_NAME_CZECH :Čehu +STR_MAPGEN_TOWN_NAME_SWISS :Šveiciešu +STR_MAPGEN_TOWN_NAME_DANISH :Dāņu +STR_MAPGEN_TOWN_NAME_TURKISH :Turku +STR_MAPGEN_TOWN_NAME_ITALIAN :Itāļu +STR_MAPGEN_TOWN_NAME_CATALAN :Katalāņu # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kartes malas: @@ -3213,7 +3247,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}NewGRF d STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Aktīvie NewGRF faili STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Neaktīvie NewGRF faili STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Izvēlēties paraugu: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtra virkne: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtrs: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Ielādēt atlasīto iepriekšiestatījumu STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Saglabāt iepriekšiestatījumu STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Saglabāt šo sarakstu kā iepriekšiestatījumu @@ -3300,6 +3334,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Iepriek STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Iet pie iepriekšējā parastā gariņa, izlaižot visus pseido/pārkrāsotos/fonta gariņus STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Atlasītā gariņa attēlojums. To attēlojot, izkārtojums netiek ievērots STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Pārvietot gariņu, lai mainītu X un Y vērtības. Ctrl+klikšķis, lai vienā piegājienā pārvietotu gariņu par astoņām vienībām + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Nobīde centrēta +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Spraits centrēts + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Krustpunkts + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Atiestatīt relatīvi STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Pāriestatīt paršreizējo relatīvo nobīdi STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X nobīde: {NUM}, Y nobīde: {NUM} (absolūta) @@ -3314,20 +3355,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Brīdinājums: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Kļūda: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatāls: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Notikusi fatāla NewGRF kļūda:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Radusies NewGRF kļūda:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} nedarbosies kopā ar TTDPatch versiju (par ko ziņoja OpenTTD). -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} ir TTD {STRING} versijai -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} ir paredzēts lietošanai kopā ar {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Nepareizs parametrs priekš {1:STRING}: parametrs {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} jābūt ielādētam pirms {STRING}. +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} ir paredzēts TTD versijai {2:STRING} +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} ir paredzēts lietošanai ar {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Nederīgs parametrs {1:STRING}: parametrs {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} ir jāielādē pirms {2:STRING} STR_NEWGRF_ERROR_LOAD_BEFORE.kas :{1:STRING} jābūt ielādētai pirms {STRING}. -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} jābūt ielādētam pēc {STRING}. +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} jābūt ielādētam pēc {2:STRING} STR_NEWGRF_ERROR_LOAD_AFTER.kas :{1:STRING} jābūt ielādētai pēc {STRING}. -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} ir vajadzīga Open TTD versija {STRING} vai labāka +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :Lietotnei {1:STRING} ir nepieciešama OpenTTD versija {2:STRING} vai jaunāka STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF fails radīts tulkošanai STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Ir ielādēti pārāk daudzi NewGRF -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Ielādē {1:STRING} kā statisks NewGRF {STRING} var radīt desinhronizāciju +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Ielādējot {1:STRING} kā statisku NewGRF ar {2:STRING}, var rasties desinhronizācija STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Neparedzēts gariņš (gariņš {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Nezināma Action 0 īpašība {4:HEX} (gariņš {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Mēģinājums izmantot nederīgu ID (gariņš {3:NUM}) @@ -3460,14 +3499,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Pirkt pārvadā STR_LOCAL_AUTHORITY_ACTION_BRIBE :Dot kukuli pašvaldībai ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Sāciet nelielu vietējo reklāmas kampaņu, lai jūsu transporta pakalpojumiem piesaistītu vairāk pasažieru un kravas.{} Nodrošina īslaicīgu uzlabojumu staciju vērtējumam nelielā rādiusā ap pilsētas centru.{} Izmaksas: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Sāciet vidējā mēroga vietējās reklāmas kampaņu, lai jūsu transporta pakalpojumiem piesaistītu vairāk pasažieru un kravas.{} Nodrošina īslaicīgu stacijas reitinga paaugstinājumu vidējā rādiusā ap pilsētas centru.{} Izmaksas: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Sāciet plašu vietējās reklāmas kampaņu, lai jūsu transporta pakalpojumiem piesaistītu vairāk pasažieru un kravas.{} Nodrošina īslaicīgu staciju reitinga palielinājumu lielā rādiusā ap pilsētas centru.{} Izmaksas: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Finansējiet pilsētas ceļu tīkla rekonstrukciju.{} Līdz 6 mēnešiem rada ievērojamus ceļu satiksmes traucējumus.{} Izmaksas: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Uzceliet statuju par godu savam uzņēmumam.{} Nodrošina pastāvīgu paaugstinājumu staciju vērtējumam šajā pilsētā.{} Izmaksas: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Finansējiet jaunu ēku celtniecību pilsētā.{} Nodrošina īslaicīgu pilsētas izaugsmi šajā pilsētā.{} Izmaksas: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Pirkt 1 gada izņēmuma tiesības uz pārvadājumiem pilsētā.{}Pašvaldība neatļaus pasažieru un kravu pārvešanai izmantot jūsu sāncenšu stacijas.{}Izmaksas: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Piekukuļot vietējo pašvaldību lai paceltu reitingu, riskējot saņemt lielu sodu.{}Izmaksas: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Sāciet nelielu vietējo reklāmas kampaņu, lai piesaistītu vairāk pasažieru un kravas saviem transporta pakalpojumiem.{}Nodrošina īslaicīgu staciju vērtējuma palielinājumu nelielā rādiusā ap pilsētas centru.{}{POP_COLOUR}Izmaksas: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Veiciet vidējo reklāmas kampaņu lai palielinātu pasažieru un kravu parvadājumu savās stacijās.{}Tas īslaicīgi palielinās to staciju vērtējumu, kuras atrodas netālu no pilsētas centra.{}{POP_COLOUR}Izmaksas: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Sāciet lielu vietējo reklāmas kampaņu lai piesaistītu vairāk pasažieru un kravas saviem transporta pakalpojumiem.{}Nodrošina īslaicīgu staciju vērtējuma palielinājumu lielā rādiusā ap pilsētas centru.{}{POP_COLOUR}Izmaksas: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Finansējiet pilsētas ceļu tīkla rekonstrukciju.{}Līdz 6 mēnešiem rada ievērojamus ceļu satiksmes traucējumus.{}{POP_COLOUR}Izmaksas: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Uzceliet statuju par godu savam uzņēmumam.{}Nodrošina pastāvīgu staciju vērtējuma palielinājumu šajā pilsētā.{}{POP_COLOUR}Izmaksas: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Finansējiet jaunu ēku celtniecību pilsētā.{}Nodrošina īslaicīgu stimulu pilsētas izaugsmei šajā pilsētā.{}{POP_COLOUR}Izmaksas: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Iegādājieties 1 gada ekskluzīvas transporta tiesības pilsētā.{}Pašvaldība neļaus pasažieriem un kravai izmantot jūsu konkurentu stacijas.{}{POP_COLOUR}Izmaksas: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Piekukuļojiet vietējo pašvaldību, lai paaugstinātu savu vērtējumu, riskējot saņemt bargu sodu.{}{POP_COLOUR}Izmaksas: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} mērķi @@ -3622,24 +3661,38 @@ STR_FINANCES_CAPTION :{WHITE}{COMPANY STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}Ieņēmumi +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Ekspluatācijas izdevumi +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Kapitāla Izdevumi ###length 13 STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Būvniecība STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Jauni transportlīdzekļi -STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Vilcienu kārtējās izmaksas -STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Autotransporta kārtējās izmaksas -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Lidaparātu kārtējās izmaksas -STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Kuģu kārtējās izmaksas +STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Vilcieni +STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Autotransportlīdzekļi +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Lidaparāts +STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Kuģi +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Infrastruktūra +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Vilcieni +STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}Autotransportlīdzekļi +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Lidaparāts +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Kuģi STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Aizdevuma procents STR_FINANCES_SECTION_OTHER :{GOLD}Citi -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} -STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_TOTAL_CAPTION :{WHITE}Kopā +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} +STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Peļņa STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Bankas bilance +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Pašu līdzekļi STR_FINANCES_LOAN_TITLE :{WHITE}Aizdevums +STR_FINANCES_INTEREST_RATE :{WHITE}Aizdevuma procenti: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maksimālais aizdevums: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Aizņemties {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Palielināt aizdevuma apmēru. Ctrl+klikšķis lai aizņemtos cik daudz vien iespējams STR_FINANCES_REPAY_BUTTON :{BLACK}Atmaksāt {CURRENCY_LONG} @@ -3741,7 +3794,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Ražo: { STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Pieprasa: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} gaida{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Mainīt ražošanu (dalāmais ar 8, līdz pat 2040) @@ -3771,6 +3824,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Sūtīt STR_VEHICLE_LIST_REPLACE_VEHICLES :Nomainīt transportlīdzekļus STR_VEHICLE_LIST_SEND_FOR_SERVICING :Sūtīt uz apkopi STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Peļņa šogad: {CURRENCY_LONG} (pērn: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Sūtīt uz depo STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Sūtīt uz depo @@ -3862,6 +3917,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Maksimā STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Apgabas: {GOLD}{COMMA} lauciņi STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Lidaparāta veids: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Visi kravu veidi +STR_CARGO_TYPE_FILTER_FREIGHT :Krava +STR_CARGO_TYPE_FILTER_NONE :Nav + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Vilciena vagonu atlasīšanas saraksts - klikšķināt uz transportlīdzekļa, lai iegūtu informāciju STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Autotransporta atlasīšanas saraksts - klikšķināt uz transportlīdzekļa, lai iegūtu informāciju @@ -4030,7 +4090,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :lidaparāts STR_ENGINE_PREVIEW_SHIP :kuģis STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cena: {CURRENCY_LONG} Svars: {WEIGHT_SHORT}{}Ātrums: {VELOCITY} Jauda: {POWER}{}Kārtējās izmaksas: {CURRENCY_LONG} gadā{}Ietilpība: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cena: {CURRENCY_LONG} Svars: {WEIGHT_SHORT}{}Ātrums: {VELOCITY} Jauda: {POWER} Maks. spēks: {6:FORCE}{}Kārtējās izmaksas: {4:CURRENCY_LONG} gadā{}Ietilpība: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Maksa: {0:CURRENCY_LONG} Svars: {1:WEIGHT_SHORT}{}Ātrums: {2:VELOCITY} Jauda: {3:POWER} Maks. T.E.: {6:FORCE}{}Darbības izmaksas: {4:CURRENCY_LONG}/gadā{}ietilpība: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Ietilpība: {CARGO_LONG}{}Kārtējās izmaksas: {CURRENCY_LONG} gadā STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Lidaparāta veids: {STRING}{}Ietilpība: {CARGO_LONG}, {CARGO_LONG}{}Izmaksas: {CURRENCY_LONG} gadā STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Lidaparāta veids: {STRING}{}Ietilpība: {CARGO_LONG}{}Izmaksas: {CURRENCY_LONG}/gadā @@ -4189,12 +4249,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Svars: { STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Svars: {LTBLUE}{WEIGHT_SHORT} {BLACK}Jauda: {LTBLUE}{POWER}{BLACK} Maks. ātrums: {LTBLUE}{VELOCITY} {BLACK}Maks. spēks: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Peļņa šogad: {LTBLUE}{CURRENCY_LONG} (pagājušajā gadā: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Peļņa šogad: {LTBLUE}{CURRENCY_LONG} (pagājušajā gadā: {CURRENCY_LONG}) {BLACK}Min. veiktspēja: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Drošums: {LTBLUE}{COMMA}% {BLACK}Ķibeles kopš pēdējās apkopes: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Uzbūvēts: {LTBLUE}{NUM}{BLACK} Vērtība: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Ietilpība: {LTBLUE}Nav{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Ietilpība: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Ietilpība: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Ietilpība: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Ietilpība: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Ietilpība: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Pārvadājumu ieņēmumi: {LTBLUE}{CURRENCY_LONG} @@ -4220,8 +4281,8 @@ STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Vērtība: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Kopējā kravas ietilpība: -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Tukšs STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} no {STATION} @@ -4460,25 +4521,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Šis sar STR_TIMETABLE_STATUS_START_AT :{BLACK}Šis saraksts sāksies {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Sākuma datums -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Izvēlieties šī kustības saraksta sākuma datumu. Ctrl+klikšķis iestata šī saraksta sākuma datumu un vienmērīgi izplata to starp visiem transporta līdzekļiem, kuri seko šim rīkojumam, ja kustības saraksts ir pilnībā aizpildīts +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Izvēlieties datumu kā šī kustību saraksta sākuma punktu. Ctrl+Click vienmērīgi sadala visus transportlīdzekļus, kas koplieto šo pasūtījumu no norādītā datuma, pamatojoties uz to plānoto pasūtījumu, ja pasūtījums pilnībā izmanto kustību sarakstu STR_TIMETABLE_CHANGE_TIME :{BLACK}Mainīt laiku -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Mainīt iezīmētajam maršrutam nepieciešamo laiku +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Mainiet laiku, kas nepieciešams iezīmētajam pasūtījumam. Ctrl+Click iestata laiku visiem pasūtījumiem STR_TIMETABLE_CLEAR_TIME :{BLACK}Notīrīt laiku -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Dzēst laiku atlasītajam rīkojumam +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Dzēst iezīmētā pasūtījuma laiku. Ctrl+klikšķis notīra laiku visiem pasūtījumiem STR_TIMETABLE_CHANGE_SPEED :{BLACK}Mainīt ātruma ierobežojumu -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Mainīt maksimālo braukšanas ātrumu atlasītajā rīkojumā +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Mainiet izceltā pasūtījuma maksimālo braukšanas ātrumu. Ctrl+Click iestata ātrumu visiem pasūtījumiem STR_TIMETABLE_CLEAR_SPEED :{BLACK}Nodzēst ātruma ierobežojumu -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Nodzēst maksimālo braukšanas ātrumu atlasītajā rīkojumā +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Dzēst iezīmētā pasūtījuma maksimālo braukšanas ātrumu. Ctrl+klikšķis notīra ātrumu visiem pasūtījumiem STR_TIMETABLE_RESET_LATENESS :{BLACK}Atiestatīt kavējuma skaitītāju STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Atslēgt skaitītāju, lai transportlīdzeklis būtu laikā STR_TIMETABLE_AUTOFILL :{BLACK}Automātiska aizpildīšana -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Aizpildīt sarakstu automātiski ar vērtībām no nākošā ceļojuma (Ctrl+klikšķis lai mēģinātu paturēt gaidīšanas laikus) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Automātiski aizpildiet kustības grafiku ar vērtībām no nākamā brauciena. Ctrl+noklikšķiniet, lai mēģinātu saglabāt gaidīšanas laiku STR_TIMETABLE_EXPECTED :{BLACK}Paredzēts STR_TIMETABLE_SCHEDULED :{BLACK}Ieplānots @@ -4522,12 +4583,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Viens no STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}MI/spēles skriptu atkļūdošanas logs ir pieejams tikai serverim # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}MI/spēles skriptu konfigurācija +STR_AI_CONFIG_CAPTION_AI :{WHITE}AI Konfigurācija +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Spēles skripta konfigurācija STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Spēles skripts, kas tiks ielādēts nākamajā spēlē STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}MI, kas tiks ielādēts nākamajā spēlē STR_AI_CONFIG_HUMAN_PLAYER :Spēlētājs (cilvēks) STR_AI_CONFIG_RANDOM_AI :Nejaušs MI STR_AI_CONFIG_NONE :(nav) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maksimālais sāncenšu daudzums: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Pacelt uz augšu STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Pacelt izvēlētos MI sarakstā uz augšu @@ -4535,12 +4598,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Nolaist STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Nolaist izvēlētos MI sarakstā uz leju STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spēles skripti +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametri STR_AI_CONFIG_AI :{SILVER}MI -STR_AI_CONFIG_CHANGE :{BLACK}Izvēlēties {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :MI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Spēles skripts +STR_AI_CONFIG_CHANGE_AI :{BLACK}Izvēlēties MI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Atlasiet spēles skriptu STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Ielādēt citu skriptu STR_AI_CONFIG_CONFIGURE :{BLACK}Konfigurēt STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Konfigurēt skripta parametrus @@ -4568,10 +4630,9 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Visas ka STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Augstumkartes ekrānuzņēmums STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minikartes ekrānuzņēmums -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} parametri -STR_AI_SETTINGS_CAPTION_AI :MI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spēles skripts +# Script Parameters +STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Iestatījumi +STR_AI_SETTINGS_CAPTION_AI :{WHITE}MI Parametri STR_AI_SETTINGS_CLOSE :{BLACK}Aizvērt STR_AI_SETTINGS_RESET :{BLACK}Atiestatīt STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4735,6 +4796,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... pār STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nevar radīt ražotnes... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Šeit nevar būvēt {STRING}... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Šeit nevar būvēt šī veida ražotni... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Nozari nevar izredzēt... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... pārāk tuvu citai ražotnei STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... vispirms ir jāuzceļ pilsētu STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... pilsētā atļauts tikai viens(a) @@ -4749,6 +4811,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... mež STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... var būvēt tikai sniegotajos apgabalos STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... var būvēt tikai bezsniega apgabalos +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Neizdevās iegūt finansējumu dēļ neveiksmes; mēģiniet vēlreiz +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Šai nozarei nav piemērotu vietu, kur attīstīties STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Neatradās piemērotas vietas '{STRING}' tipa industrijām STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Mainīt kartes ģenerēšanas parametrus, lai iegūtu labāku karti @@ -4916,6 +4980,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Traucēj STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... traucē uzņēmuma birojs STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Nevar nopirkt šo zemes platību... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... tā jums jau pieder! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... sasniegts objektu būvniecības limits # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Nevar izveidot grupu... @@ -4988,6 +5053,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Nevar ma STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... transportlīdzeklis ir iznīcināts +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... ne visi transportlīdzekļi ir identiski + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Vispār nebūs pieejami transporta līdzekļi STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Mainiet jūsu NewGRF konfogurāciju STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Transportlīdzekļi vēl nav pieejami @@ -5014,6 +5081,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Izvēlē STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... transportlīdzeklis netiek uz visām stacijām STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... transportlīdzeklis netiek uz šo staciju STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... transportlīdzeklis, kam kopīgs šis rīkojums, nespēj doties uz norādīto staciju +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}...ne visiem transportlīdzekļiem ir vienādi pasūtījumi +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... ne visi transportlīdzekļi koplieto pasūtījumus STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Nevar koplietot rīkojumu sarakstu... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Nevar pārtraukt koplietot rīkojumus... @@ -5021,6 +5090,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Nevar ko STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... pārāk tālu no iepriekšējā galamērķa STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... lidaparātam ir nepietiekams apgabals +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Nevar panākt transportalīdzekļa iekļaušanos sarakstā STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Transportlīdzekļus var gaidīt tikai stacijās diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index d21eea3772577..bc0d4c9a8ecf2 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -395,6 +395,13 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}AG STR_UNITS_POWER_METRIC :{COMMA}{NBSP}AG STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}ag/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}ag/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}ag/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}ag/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -521,6 +528,7 @@ STR_GROUP_BY_NONE :(tuščia) STR_GROUP_BY_SHARED_ORDERS :Bendrinamas užduotis # Order button in shared orders vehicle list +STR_GOTO_ORDER_VIEW_TOOLTIP :{BLACK}Atidarykite užsakymo rodinį # Tooltips for the main toolbar ###length 31 @@ -584,10 +592,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Išeiti # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Pagrindinės nuostatos STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Išplėstinės nuostatos -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Dirbtinio intelekto nuostatos +STR_SETTINGS_MENU_AI_SETTINGS :DI nustatymai +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Žaidimo scenarijaus nustatymai STR_SETTINGS_MENU_NEWGRF_SETTINGS :Plėtinių nuostatos STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Skaidrumo nuostatos STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Miestų pavadinimai @@ -1167,36 +1176,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indijos rupijos STR_GAME_OPTIONS_CURRENCY_IDR :Indonezijos rupijos (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaizijos ringitai (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Kairiąja puse -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Dešiniąja puse - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Miestų pavadinimai: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Pasirink miestų pavadinimų tipą - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Anglų (Oginalus) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Prancūzų -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Vokiečių -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Anglų (Papildomas) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Lotynų-Amerikos -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Kvaili -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Švedų -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Olandų -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Suomių -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Lenkų -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovakų -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norvegų -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Vengrų -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austrų -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumunų -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Čekų -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Šveicarų -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danų -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turkiški -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italų -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalonų - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatinis išsaugojimas STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Pasirink, kaip dažnai išsaugoti žaidimą @@ -1225,23 +1204,18 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP :{BLACK}Pažymė STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Kad pakeitimai įsigaliotų, reikia paleisti OpenTTD iš naujo STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}Vertikalioji sinchronizacija (VSync) +STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Pažymėkite šį langelį, norėdami v-sync ekraną. Pakeistas nustatymas bus pritaikytas tik paleidus žaidimą iš naujo. Veikia tik įjungus aparatūros pagreitį +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Dabartinis vairuotojas: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Sąsajos elementų dydis -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Pasirinkite vartotojo sąsajos elementų santykinį dydį +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Automatinis dydžio nustatymas +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Pažymėkite šį langelį, kad automatiškai aptiktumėte sąsajos dydį -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(aptikti automatiškai) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normalus -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dvigubas -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Keturgubas +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Skalės nuožulniai +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Pažymėkite šį langelį, jei norite keisti kampus pagal sąsajos dydį -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Šrifto dydis -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Pasirinkite vartotojo sąsajos šrifto dydį - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(aptikti automatiškai) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normalus -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dvigubas -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Keturgubas +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafika @@ -1293,8 +1267,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Perži STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 svarų (£) jūsų valiuta STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Keisti pasirinktos valiutos nustatymus -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Didžiausias priešininkų skaičius: {ORANGE}{COMMA} - STR_NONE :Nėra STR_FUNDING_ONLY :Tik finansavimas STR_MINIMAL :Mažiausias @@ -1344,6 +1316,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Normalus klimatas +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arktinis klimatas +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropinis klimatas +STR_CLIMATE_TOYLAND_LANDSCAPE :'Žaislinis' klimatas + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Tik lygumos STR_TERRAIN_TYPE_FLAT :Lygumos @@ -1354,6 +1332,7 @@ STR_TERRAIN_TYPE_CUSTOM :Pasirinktinis STR_TERRAIN_TYPE_CUSTOM_VALUE :Pasirinktinis ({NUM}) ###length 4 +STR_CITY_APPROVAL_LENIENT :Atlaidus STR_CITY_APPROVAL_TOLERANT :Tolerantiškas STR_CITY_APPROVAL_HOSTILE :Priešiškas STR_CITY_APPROVAL_PERMISSIVE :Atlaidus @@ -1373,6 +1352,7 @@ STR_CONFIG_SETTING_TYPE_GAME_MENU :žaidimo (įra STR_CONFIG_SETTING_TYPE_GAME_INGAME :žaidimo (įrašoma kiekvieną kartą išsaugant žaidimą. Galioja tik šiuo metu aktyviai kompanijai ir tik aktyviam žaidimui) STR_CONFIG_SETTING_TYPE_COMPANY_MENU :kompanijos (įrašoma pradedant naują žaidimą) STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :kompanijos (įrašoma kiekvieną kartą išsaugant žaidimą. Galioja tik šiuo metu aktyviai kompanijai) +STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT :{WHITE}Šis veiksmas iš naujo nustatys visus žaidimo nustatymus į numatytąsias vertes.{}Ar tikrai norite tęsti? STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}Kategorija: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Tipas: @@ -1419,6 +1399,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Dešinėje STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Didžiausia pradinė paskola: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Didžiausia paskola, kokią kompanija gali gauti iš banko (neatsižvelgiant į infliaciją) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Palūkanų norma: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Paskolos palūkanų norma. Taip pat įtakoja infliaciją (jei ji įgalinta) @@ -1645,6 +1626,7 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Grafikų linij STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Rodyti plėtinio pavadinimą perkant naują trasnporto priemonę: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Perkant naują transporto priemonę, lange atsiras papildoma eilutė, nurodanti, kuriam plėtiniui priklauso pažymėta transporto priemonė. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Jei įjungta, transporto priemonės gabenamas krovinys bus rodomas virš jo transporto priemonių sąrašuose STR_CONFIG_SETTING_LANDSCAPE :Kraštovaizdis: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Skirtingi kraštovaizdžio tipai pasižymi skirtingomis tiek gamtinėmis (medžių, kalvų, jūrų, upių kiekis), tiek pramoninėmis (pramonės įmonės, miestų augimo greitis, transporto priemonės) savybėmis @@ -1699,6 +1681,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Naujasis STR_CONFIG_SETTING_ROAD_SIDE :Automobilių eismas: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Eismo pusė +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Kairiąja puse +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Dešiniąja puse + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Aukščių žemėlapio pasukimas: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Prieš laikrodžio rodyklę @@ -1725,7 +1711,10 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Žalia STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Tamsiai žalia STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violetinė +STR_CONFIG_SETTING_LINKGRAPH_COLOURS :Krovinio srauto perdangos spalvos: {STRING} ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Žalia mėlyna +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Nuo pilkos iki raudonos STR_CONFIG_SETTING_SCROLLMODE :Peržiūros lango slinkties veiksena: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Peržiūros lango slinkties veiksena @@ -1941,6 +1930,7 @@ STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER_HELPTEXT :Rodyti naujienr STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS :Avarijos / nelaimės: {STRING} STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT :Rodyti naujienraštį atsitikus incidentui ar katastrofai +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER :Konkurentų transporto priemonių avarijos: {STRING} STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION :Kompanijos informacija: {STRING} STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT :Rodyti naujienraštį įsikūrus naujai kompanijai (arba esamai susidūrus su sunkumais) @@ -2239,7 +2229,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Apsisukimas pri STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Leisti traukiniams apsisukti ir bandyti važiuoti priešinga kryptimi, jei ties šviesoforu jiems tenka laukti pernelyg ilgai ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Rekomenduojama) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Rekomenduojama) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Keisti reikšmes @@ -2282,7 +2272,7 @@ STR_INTRO_HIGHSCORE :{BLACK}Nugalėt STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Išplėstinės nuostatos STR_INTRO_NEWGRF_SETTINGS :{BLACK}Plėtiniai STR_INTRO_ONLINE_CONTENT :{BLACK}Interneto turinys -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Dirbtinio intelekto nuostatos +STR_INTRO_AI_SETTINGS :{BLACK}DI Nustatymai STR_INTRO_QUIT :{BLACK}Išeiti STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Pradėti naują žaidimą. Spragtelėjus laikant nuspaustą Ctrl klavišą, naujas žemėlapis bus sugeneruotas nedelsiant ir nieko nebeklausiant @@ -2302,7 +2292,7 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Rodyti n STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Rodyti išplėstines nuostatas STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Rodyti parsisiųstus plėtinius ir jų nuostatas STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Tikrinti, ar nėra naujų plėtinių arba atnaujinimų jau atsisiųstiems plėtiniams -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Rodyti dirbtinio intelekto nuostatas +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Rodyti DI nustatymus STR_INTRO_TOOLTIP_QUIT :{BLACK}Išeiti iš „OpenTTD“ žaidimo STR_INTRO_BASESET :{BLACK}Šiuo metu pasirinktame grafikos rinkinyje trūksta {NUM} sprukl{P io ių ių}. Patikrinkite, ar nėra naujinių. @@ -2334,12 +2324,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Pakeist STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Pakeisti dabartinius metus STR_CHEAT_SETUP_PROD :{LTBLUE}Leisti keisti produkcijos vertes: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Normalus klimatas -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arktinis klimatas -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropinis klimatas -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :'Žaislinis' klimatas - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Kompanijos spalvos @@ -2472,10 +2456,12 @@ STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}Serveri STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}Serverio adresas: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_START_DATE :{SILVER}Žaidimo pradžia: {WHITE}{DATE_SHORT} STR_NETWORK_SERVER_LIST_CURRENT_DATE :{SILVER}Dabartinė data: {WHITE}{DATE_SHORT} +STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}Žaidimo scenarijus: {WHITE}{STRING} (v{NUM}) STR_NETWORK_SERVER_LIST_PASSWORD :{SILVER}Apsaugota slaptazodžiu! STR_NETWORK_SERVER_LIST_SERVER_OFFLINE :{SILVER}SERVERIS IŠJUNGTAS STR_NETWORK_SERVER_LIST_SERVER_FULL :{SILVER}SERVERIS PILNAS STR_NETWORK_SERVER_LIST_SERVER_BANNED :{SILVER}Serveris jus atjungė (BAN) +STR_NETWORK_SERVER_LIST_SERVER_TOO_OLD :{SILVER}SERVERIS PER SENAS STR_NETWORK_SERVER_LIST_VERSION_MISMATCH :{SILVER}VERSIJŲ NESUTAPIMAS STR_NETWORK_SERVER_LIST_GRF_MISMATCH :{SILVER}NEATITINKA PLĖTINYS @@ -2538,15 +2524,35 @@ STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Kompanij # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Žaidėjų sąrašas +STR_NETWORK_COMPANY_LIST_SPECTATE :Žiūrėti # Network client list +STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}Internetiniai žaidėjai +STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}Vardas +STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}Serverio kuriame žaidžiate pavadinimas +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Matomumas +STR_NETWORK_CLIENT_LIST_SERVER_INVITE_CODE_TOOLTIP :{BLACK}Kvietimo kodas, kurį kiti žaidėjai gali naudoti norėdami prisijungti prie šio serverio +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}Ar ir kaip jūsų serverį gali pasiekti kiti +STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Vardas STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}Įveskite žaidėjo pavadinimą +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}Šiam klientui atliktini administraciniai veiksmai +STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Siųsti žinutę visiems žiūrovams +STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nauja kompanija) +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Tai esi tu +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Tai yra žaidimo šeimininkas # Matches ConnectionType ###length 5 +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_ISOLATED :{RED}Nuotoliniai žaidėjai negali prisijungti +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_DIRECT :{BLACK}Viešas +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_STUN :{BLACK}Už NAT +STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TURN :{BLACK}Per relę STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Atjungti +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Blokuoti +STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Administratoriaus veiksmas +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Ar tikrai norite iš naujo nustatyti įmonės slaptažodį '{COMPANY}'? STR_NETWORK_ASK_RELAY_CAPTION :{WHITE}Naudotis tarpiniu perdavimu? STR_NETWORK_ASK_RELAY_TEXT :{YELLOW}Nepavyko prisijungti prie serverio '{STRING}'.{}Ar norite pabandyti jungtis per tarpinę stotelę '{STRING}'? @@ -2593,6 +2599,7 @@ STR_NETWORK_ERROR_SAVEGAMEERROR :{WHITE}Negali a STR_NETWORK_ERROR_SERVER_START :{WHITE}Negali paleisti serverio STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Protokolo klaida. Prisijungimas baigtas STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE} Įveskite žaidėjo pavadinimą lango viršuje +STR_NETWORK_ERROR_BAD_SERVER_NAME :{WHITE}Jūsų serverio pavadinimas nenustatytas. Pavadinimą galima nustatyti kelių žaidėjų lango viršuje STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}Žaidimo versija neatitinka serverio žaidimo versijos STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Blogas slaptažodis STR_NETWORK_ERROR_SERVER_FULL :{WHITE}Serveris pilnas @@ -2661,6 +2668,8 @@ STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Serveris STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Serveris persikrauna...{}Prašau palaukti... STR_NETWORK_MESSAGE_KICKED :*** {STRING} buvo išmestas. Priežastis: ({STRING}) +STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Serverio registracija nepavyko +STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Kiti žaidėjai negalės prisijungti prie jūsų serverio # Content downloading window STR_CONTENT_TITLE :{WHITE}Turinio atsisiuntimas @@ -2766,6 +2775,10 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}optimalus STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}perkrautas +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} vežti per mėnesį nuo {STATION} iki {STATION} ({COMMA}% talpos){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} gabenti atgal ({COMMA} % talpos) + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Rodyti aptarnaujamą teritoriją? STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Ne @@ -2774,6 +2787,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Nerodyti STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Rodyti stotelės aptarnaujamą teritoriją STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Priima: {GOLD}{CARGO_LIST.ka} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Tiekia: {GOLD}{CARGO_LIST.ka} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Priežiūros kaina: {GOLD}{CURRENCY_SHORT}/metams # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Sujungti stoteles @@ -2834,6 +2848,7 @@ STR_STATION_CLASS_WAYP :Keliarodžiai # Signal window STR_BUILD_SIGNAL_CAPTION :{WHITE}Signalo pasirinkimas +STR_BUILD_SIGNAL_TOGGLE_ADVANCED_SIGNAL_TOOLTIP :{BLACK}Perjungti išplėstinių signalų tipų rodymą STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Bėgių bloko semaforas{}Paprasčiausias signalo tipas, leidžiantis viename bėgių bloke tuo pačiu metu būti tik vienam traukiniui STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}Įvažiavimo semaforas{}Leidžia įvažiuoti į bėgių bloką, jei bent vienas išvažiavimo signalas leidžia išvažiuoti iš bloko. Kitu atveju traukinių eismas draudžiamas STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Išvažiavimo semaforas{}Veikia lygiai taip pat, kaip ir paprastas bėgių bloko signalas, bet yra reikalingas normaliam įvažiavimo bei kombinuotųjų semaforų darbui @@ -2855,8 +2870,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Padidint STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Pasirinkite geležinkelio tilto tipą STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Pasirinkite automobilių tilto tipą STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Tilto statyba — spragtelkite ant pageidaujamo tilto -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Kabantis plieninis STR_BRIDGE_NAME_GIRDER_STEEL :Plieno sijų STR_BRIDGE_NAME_CANTILEVER_STEEL :Gembinis plieninis @@ -3008,6 +3021,7 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Atsitikt STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Pastatyti miestą atsitiktinėje vietoje STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Daug atsitiktinių miestų STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Sukuria miestus atsitiktinėse žemėlapio vietose +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Kad visi miestai šiek tiek didėtų STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Miesto pavadinimas: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Įvesti miesto pavadinimą @@ -3286,6 +3300,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Žemėla STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Pasirinkite žemėlapio dydį langeliais. Prieinamų langelių skaičius bus šiek tiek mažesnis. STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Miestų kiekis: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Miestų pavadinimai: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Pasirink miestų pavadinimų tipą STR_MAPGEN_DATE :{BLACK}Pradžios data: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Pramonės įmonių kiekis: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Didžiausias aukštis @@ -3299,13 +3315,40 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Dykumų STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Padidinti dykumų aprėptį 10% STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Sumažinti dykumų aprėptį 10% STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Generavimo algoritmas: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Vietovės tipas: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Jūros lygis: +STR_MAPGEN_SEA_LEVEL :{BLACK}Jūros lygis: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Upių kiekis: STR_MAPGEN_SMOOTHNESS :{BLACK}Jautrumas: STR_MAPGEN_VARIETY :{BLACK}Įvairovės paskirstymas: STR_MAPGEN_GENERATE :{WHITE}Sukurti +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF Nustatymai +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Rodyti NewGRF nustatymus +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Rodyti DI nustatymus +STR_MAPGEN_GS_SETTINGS :{BLACK}Žaidimo scenarijaus nustatymai +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Rodyti žaidimo scenarijaus nustatymus + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Anglų (Oginalus) +STR_MAPGEN_TOWN_NAME_FRENCH :Prancūzų +STR_MAPGEN_TOWN_NAME_GERMAN :Vokiečių +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Anglų (Papildomas) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Lotynų-Amerikos +STR_MAPGEN_TOWN_NAME_SILLY :Kvaili +STR_MAPGEN_TOWN_NAME_SWEDISH :Švedų +STR_MAPGEN_TOWN_NAME_DUTCH :Olandų +STR_MAPGEN_TOWN_NAME_FINNISH :Suomių +STR_MAPGEN_TOWN_NAME_POLISH :Lenkų +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovakų +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norvegų +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Vengrų +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austrų +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumunų +STR_MAPGEN_TOWN_NAME_CZECH :Čekų +STR_MAPGEN_TOWN_NAME_SWISS :Šveicarų +STR_MAPGEN_TOWN_NAME_DANISH :Danų +STR_MAPGEN_TOWN_NAME_TURKISH :Turkiški +STR_MAPGEN_TOWN_NAME_ITALIAN :Italų +STR_MAPGEN_TOWN_NAME_CATALAN :Katalonų # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Žemėlapio kraštai: @@ -3451,6 +3494,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Ankstesn STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Įkelti ankstesnį spruklį STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Pasirinkto spruklio atvaizdas, nekreipiant dėmesio į lygiavimą STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Paslinkti spruklį, keičiant X ir Y poslinkius. Spragtelėjus laikant nuspaustą Ctrl klavišą, spruklys bus slenkamas po aštuonis vienetus + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Poslinkis centre +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Spruklis centre + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Kryželis + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Atkurti STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Atkurti numatytuosius santykinius poslinkius STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X poslinkis: {NUM}, Y poslinkis: {NUM} (Absoliutus) @@ -3465,7 +3515,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Įspėjimas: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Klaida: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Lemtingoji klaida: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Įvyko lemtingoji plėtinio klaida:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} neveiks su TTDPatch versija nurodyta pagal OpenTTD STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} skirtas {STRING} TTD versijai. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} yra pritaikytas naudojimui su {STRING} @@ -3767,6 +3816,7 @@ STR_FINANCES_CAPTION :{WHITE}{COMPANY STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Kapitalinės išlaidos ###length 13 @@ -3776,15 +3826,20 @@ STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Traukini STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Automobilių sąnaudos STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Lėktuvų sąnaudos STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Laivų sąnaudos +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Traukiniai +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Lėktuvas STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Paskolos palūkanos STR_FINANCES_SECTION_OTHER :{GOLD}Kita STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Pelnas STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Sąskaitos balansas STR_FINANCES_LOAN_TITLE :{WHITE}Paskola STR_FINANCES_MAX_LOAN :{WHITE}Didžiausia paskola: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Skolintis {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Skolintis daugiau. Spragtelėjus laikant nuspaustą Ctrl klavišą, bus pasiskolinta didžiausia įmanoma suma STR_FINANCES_REPAY_BUTTON :{BLACK}Grąžinti {CURRENCY_LONG} @@ -3915,6 +3970,7 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Siųsti STR_VEHICLE_LIST_REPLACE_VEHICLES :Keisti tr. priemones STR_VEHICLE_LIST_SEND_FOR_SERVICING :Siųsti techninės apžiūros STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Šių metų pelnas: {CURRENCY_LONG} (praėjusių metų: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Siųsti į depą STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Siųsti į depą @@ -4006,6 +4062,9 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Didž. t STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Nuotolis: {GOLD}{COMMA} langeliai STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipas: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Visų rūšių kroviniai + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Lokomotyvų ir vagonų sąrašas. Spragtelėjus bus parodyta platesnė informacija. Spragtelėjus laikant nuspaustą Ctrl klavišą, lokomotyvas ar vagonas bus slepiamas/rodomas sąraše STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Automobilių sąrašas. Spragtelėjus bus parodyta platesnė informacija. Spragtelėjus laikant nuspaustą Ctrl klavišą, automobilis bus slepiamas/rodomas sąraše @@ -4337,6 +4396,7 @@ STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL :{ORANGE}Vyksta STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL :{LTBLUE}Vyksta techninei apžiūrai į „{DEPOT}“, {VELOCITY} STR_VEHICLE_STATUS_CANNOT_REACH_STATION_VEL :{LTBLUE}Nepavyksta pasiekti {STATION}, {VELOCITY} +STR_VEHICLE_STATUS_CANNOT_REACH_WAYPOINT_VEL :{LTBLUE}Negalima pasiekti {WAYPOINT}, {VELOCITY} STR_VEHICLE_STATUS_CANNOT_REACH_DEPOT_VEL :{ORANGE}Nepavyksta pasiekti {DEPOT}, {VELOCITY} # Vehicle stopped/started animations @@ -4368,6 +4428,7 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Svoris: STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Svoris: {LTBLUE}{WEIGHT_SHORT} {BLACK}Galia: {LTBLUE}{POWER}{BLACK} Didž. greitis: {LTBLUE}{VELOCITY} {BLACK}Didž. traukos jėga: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Šių metų pelnas: {LTBLUE}{CURRENCY_LONG} (praėjusiųjų: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Šių metų pelnas: {LTBLUE}{CURRENCY_LONG} (praeitais metais: {CURRENCY_LONG}) {BLACK}Min. įvykdymas: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Patikimumas: {LTBLUE}{COMMA}% {BLACK}Gedimų nuo paskutinės apžiūros: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Pagamintas: {LTBLUE}{NUM}{BLACK} Vertė: {LTBLUE}{CURRENCY_LONG} @@ -4719,12 +4780,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Vienas i STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}DI / GameScript derinimo langas yra pasiekiamas tik iš serverio # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}DI / Žaidimo Nustatymai STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Žaidimo skriptas bus įkeltas sekančiame žaidime STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}DI'ai bus įkelti sekančiame žaidime STR_AI_CONFIG_HUMAN_PLAYER :Žaidėjas Žmogus STR_AI_CONFIG_RANDOM_AI :Atsitiktinis DI STR_AI_CONFIG_NONE :(tuščia) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Didžiausias priešininkų skaičius: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Perkelti aukščiau STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Perkelti pasirinktą DI aukščiau @@ -4732,10 +4793,9 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Perkelti STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Perkelti pasirinktą DI žemiau STR_AI_CONFIG_GAMESCRIPT :{SILVER}Žaidimo skriptas +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametrai STR_AI_CONFIG_AI :{SILVER}DI'ai -STR_AI_CONFIG_CHANGE :{BLACK}Pasirinkti {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :DI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Žaidimo skriptas STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Užkrauti kitą skriptą @@ -4765,10 +4825,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Viso pas STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Teminio žemėlapio kopija STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Mini žemėlapio kopija -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametrai +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :DI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Žaidimo skriptas STR_AI_SETTINGS_CLOSE :{BLACK}Uždaryti STR_AI_SETTINGS_RESET :{BLACK}Atstatyti STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4946,6 +5004,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... miš STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... gali būti statoma tik aukščiau sniego linijos STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... gali būti statoma tik žemiau sniego linijos +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Nepavyko gauti finansavimo dėl nesėkmės; Bandyk iš naujo +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Nebuvo tinkamų vietų šiai pramonei ieškoti STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Nėra tinkamos vietos '{STRING.kam}' pramonės įmonėms STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Pakeisti generavimo parametrus geresniam žemėlapiui sukurti @@ -5185,6 +5245,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Aptarnav STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... automobilis sunaikintas +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... ne visos transporto priemonės yra vienodos + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Nebus įmanoma įsigyti jokių transporto priemonių STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Pakeiskite plėtinių nuostatas STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Kol kas negalima įsigyti jokių transporto priemonių @@ -5211,6 +5273,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Negalima STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... transporto priemonė negali vykti į visas stoteles STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... automobilis negali nukakti iki tos stotelės STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... automobilis dalinantis šį grafiką negali nukakti iki tos stotelės +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... ne visos transporto priemonės turi vienodus užsakymus +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... ne visos transporto priemonės dalijasi užsakymais STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Užduočių sąrašu dalintis negalima... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Negalima nebesidalinti užduotimis... @@ -5218,6 +5282,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Užduoč STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... per toli buvusio kelionės tikslo STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... lėktuvui paskirties vieta yra per toli +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Neįmanoma sudaryti grafiko... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Transporto priemonė gali laukti tik stotelėse. diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index 60004448dcf59..41519c74d56b8 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}bh STR_UNITS_POWER_METRIC :{COMMA}{NBSP}ps STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -225,9 +235,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filter-String: -STR_LIST_FILTER_OSKTITLE :{BLACK}Filter-String -STR_LIST_FILTER_TOOLTIP :{BLACK}Filter d'Lëscht op e Wuert +STR_LIST_FILTER_TITLE :{BLACK}Filter: +STR_LIST_FILTER_OSKTITLE :{BLACK}Gëff een oder méi Wieder an fir d'Lëscht ze filteren +STR_LIST_FILTER_TOOLTIP :{BLACK}Filter d'Lëscht op een oder méi Wieder STR_TOOLTIP_GROUP_ORDER :{BLACK}Wiel Gruppéierreihefollëg STR_TOOLTIP_SORT_ORDER :{BLACK}Richtung fir ze sortéieren (ofsteigend/opsteigend) @@ -376,9 +386,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Stieders STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industrieerstellung STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Stroossebau STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Tramkonstruktioun -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Beem planzen. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Beem planzen. Ctrl wielt d'Land diagonal. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Schëld opstellen -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Objet plazéiren. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Objet plazéiren. Ctrl wiel d'Areal diagonal aus. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Eraus # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Spilloptiounen STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Astellungen -STR_SETTINGS_MENU_SCRIPT_SETTINGS :KI / Spill-Script Astellungen +STR_SETTINGS_MENU_AI_SETTINGS :KI Astellungen +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Spillscriptastellungen STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF Astellungen STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Transparenz Optiounen STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Stiednimm uweisen @@ -898,12 +909,12 @@ STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO :{WHITE}{STATION STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED :{BIG_FONT}{BLACK}Subside ofgelaaf:{}{}{STRING} vun {STRING} op {STRING} gëtt net méi subventionéiert STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE :{BIG_FONT}{BLACK}Subside entzunn:{}{}{STRING} Service vun {STRING} op {STRING} gëtt net méi subventionéiert -STR_NEWS_SERVICE_SUBSIDY_OFFERED :{BIG_FONT}{BLACK}Subside offréiert:{}{}Eischten {STRING} Service vun {STRING} op {STRING} gëtt mat engem Subside vun {NUM} Joer belount! +STR_NEWS_SERVICE_SUBSIDY_OFFERED :{BIG_FONT}{BLACK}Subside offréiert:{}{}Eischten {STRING} vun {STRING} op {STRING} gëtt mat engem Subside vun {NUM} Joer belount! ###length 4 -STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF :{BIG_FONT}{BLACK}Subside geet un {STRING}!{}{}{STRING} Service vun {STRING} op {STRING} gëtt déi nächst {NUM} Joer mat 50% Bonus bezuelt! -STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLACK}Subside geet un {STRING}!{}{}{STRING} Service vun {STRING} op {STRING} gëtt déi nächst {NUM} Joer duebel bezuelt! -STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}Subside geet un {STRING}!{}{}{STRING} Service vun {STRING} op {STRING} gëtt déi nächst {NUM} Joer dräifach bezuelt! -STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE :{BIG_FONT}{BLACK}Subside geet un {STRING}!{}{}{STRING} Service vun {STRING} op {STRING} gëtt déi nächst {NUM} Joer véierfach bezuelt! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF :{BIG_FONT}{BLACK}Subside geet un {STRING}!{}{}{STRING} vun {STRING} op {STRING} gëtt déi nächst {NUM} Joer mat 50% Bonus bezuelt! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLACK}Subside geet un {STRING}!{}{}{STRING} Vun {STRING} op {STRING} gëtt déi nächst {NUM} Joer duebel bezuelt! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}Subside geet un {STRING}!{}{}{STRING} vun {STRING} op {STRING} gëtt déi nächst {NUM} Joer dräifach bezuelt! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE :{BIG_FONT}{BLACK}Subside geet un {STRING}!{}{}{STRING} vun {STRING} op {STRING} gëtt déi nächst {NUM} Joer véierfach bezuelt! STR_NEWS_ROAD_REBUILDING :{BIG_FONT}{BLACK}Trafficchaos an {TOWN}!{}{}Stroossenneibau deen vun {STRING} finanzéiert ginn ass bréngt 6 Méint Misère fir d'Autosfuerer! STR_NEWS_EXCLUSIVE_RIGHTS_TITLE :{BIG_FONT}{BLACK}Transportmonopol! @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indiesch Rupee STR_GAME_OPTIONS_CURRENCY_IDR :Indonesesch Rupiah (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaysesche Ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Lénks fueren -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Riets fueren - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Stiednimm: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Stil vun de Stiednimm wielen - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Englesch (Original) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Franséisch -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Däitsch -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Englesch (Erweidert) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Lateinamerikanesch -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Blöd -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Schwedesch -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holländesch -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finnesch -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polnesch -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovakesch -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norwegesch -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungaresch -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Éisträichesch -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumänesch -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tschechesch -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Schwäitzer -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dänesch -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Türkesch -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italienesch -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalanesch - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Autospäicheren STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Wiel den Intervall aus fir d'Autospäicherung @@ -1025,29 +1006,28 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}D'Astell STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Wiel des Optioun fir de V-Sync unzeman. Des gëtt eréit no engem Neistart benotzt. Funktionéiert nëmmen wann Hardwarebeschleunigung un ass +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Aktuellen Driver: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Interfacegréisst -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Wiel d'Gréisst déi fir den Interface soll benotzt ginn +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Interfacegréisst +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}De Slider zéien fir d'Gréisst vum Interface ze änneren. Ctrl unhalen fir eng kontinuéierlech Ännerung +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Gréisst autom. erkennen +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Klick dës Optioun fir d'Interfacegréisst automatesch anzestellen -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(auto-Detekt.) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Duebel -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Véierfach +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Bevels skaléiren +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Klick dës Optioun fir d'Bevels mat der Gréisst vum Interface ze skaléiren -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Schrëftgréisst -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Wiel d'Interface-Schrëftgréisst aus - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(auto-Detekt.) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Duebel Gréisst -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Véierfach +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Graphik -STR_GAME_OPTIONS_REFRESH_RATE :{BLACK}Refresh rate uweisen -STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP :{BLACK}Wiel d'Refresh rate vum Bildschirm aus +STR_GAME_OPTIONS_REFRESH_RATE :{BLACK}Bildfrequenz +STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP :{BLACK}Wiel d'Frequenz vum Bildschirm aus STR_GAME_OPTIONS_REFRESH_RATE_ITEM :{NUM}Hz -STR_GAME_OPTIONS_REFRESH_RATE_WARNING :{WHITE}Refresh rates déi méi grouss wéi 60Hz sinn, kënnen d'Performance beaflossen +STR_GAME_OPTIONS_REFRESH_RATE_WARNING :{WHITE}Bildfrequenzen iwwert 60Hz kënnen d'Performance beaflossen STR_GAME_OPTIONS_BASE_GRF :{BLACK}Basis Grafikset STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Wielt de Basis Grafikset dee soll benotzt ginn @@ -1092,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Prouf: STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pond (£) an denger Währung STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Änner Währungsparameter -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maximal Unzuel vu Géigner: {ORANGE}{COMMA} - STR_NONE :Keng STR_FUNDING_ONLY :Nëmmen finanzéiren STR_MINIMAL :Minimal @@ -1143,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Gemässegt Klima Landschaft +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-Arktesch Landschaft +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-Tropesch Landschaft +STR_CLIMATE_TOYLAND_LANDSCAPE :Spillsaacheland Landschaft + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Ganz Flaach STR_TERRAIN_TYPE_FLAT :Flaach @@ -1153,15 +1137,16 @@ STR_TERRAIN_TYPE_CUSTOM :Eegen Héicht STR_TERRAIN_TYPE_CUSTOM_VALUE :Eegen Héicht ({NUM}) ###length 4 +STR_CITY_APPROVAL_LENIENT :nosichteg STR_CITY_APPROVAL_TOLERANT :Tolerant STR_CITY_APPROVAL_HOSTILE :Ofleenend -STR_CITY_APPROVAL_PERMISSIVE :Fräizügeg +STR_CITY_APPROVAL_PERMISSIVE :Fräizügeg (keng Auswierkung op Firmenactiounen) STR_WARNING_NO_SUITABLE_AI :{WHITE}Keng KI fonnt...{}KI kënnen iwwert den 'Online Content' system downgeload ginn # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Astellungen -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter-String: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Alles erweideren STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Alles reduzéiren STR_CONFIG_SETTING_RESET_ALL :{BLACK}All Wäerter zerécksetzen @@ -1221,6 +1206,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Riets STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maximalen Ufanksloun: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximalwäert den eng Firma kann léinen (ouni Inflatioun matzerechnen) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Kee Kredit {RED}Spill-Script muss am Ufank e Geldbetrag zur Verfügung ginn STR_CONFIG_SETTING_INTEREST_RATE :Zënssaz: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Zënssaz; kontrolléiert och d'Inflatioun wann ugeschalt @@ -1256,7 +1244,7 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Wann ugeschalt STR_CONFIG_SETTING_DISASTERS :Katastrophen: {STRING} STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Stell Katastrophen un oder aus déi eventuell Gefierer an Industrien blockéiren oder zerstéiren -STR_CONFIG_SETTING_CITY_APPROVAL :Dem Stadrot seng Astellung géigeniwwer dem Embau vun der Landschaft: {STRING} +STR_CONFIG_SETTING_CITY_APPROVAL :Gemengestandpunkt: {STRING} STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Wielt aus, wéivill vun der Firma verursachten Kaméidi an Emweltschiedegung sech op d'Stadbewäertung an op weider Bauaktiounen auswierkt STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :Maximal Kaartenhéicht: {STRING} @@ -1417,8 +1405,8 @@ STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT :Wann ugeschalt, STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :Gefierer lafen nie of: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :Wann ugeschalt, bleiwen all Modeller vu Gefierer éiweg verfügbar -STR_CONFIG_SETTING_AUTORENEW_VEHICLE :Gefier automatesch ernéieren wann et al gëtt: {STRING} -STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :Wann ugeschalt, gëtt e Gefier wat un säin Lafzäitenn kënnt, automatesch ausgetosch +STR_CONFIG_SETTING_AUTORENEW_VEHICLE :Gefier automatesch erneiere wann et al gëtt: {STRING} +STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :Wann ugeschalt, gëtt e Gefier wat u säi Lafzäitenn kënnt automatesch ausgetosch STR_CONFIG_SETTING_AUTORENEW_MONTHS :Automatesch erneieren wann d'Gefier maximal {STRING} Joer al ass STR_CONFIG_SETTING_AUTORENEW_MONTHS_HELPTEXT :Relativen Alter wann en Gefier an Fro kennt fir auto-erneiert ze ginn @@ -1447,6 +1435,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Breed vun de Li STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Den NewGRF Numm an der Gefier-kafen Fënster uweisen: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Weist eng Zeil an der Fënster un wou Gefier kaf ginn, aus wéi engem NewGRF dat Gefier geluede gouf. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Wueren déi d'Gefierer transportéire kënnen an der Fënster uweisen {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Wann ugeschalt, gëtt uewen an der Fenster ugewisen wéi eng Wueren d'Gefier transportéire kann STR_CONFIG_SETTING_LANDSCAPE :Landschaft: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landschaften definéiren basis Spillszenarien mat verschiddenen Wueren a Stiedwuesstumviraussetzungen. NewGRF a Gamescripter erlabe méi fein Astellungen. @@ -1501,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Verbessert STR_CONFIG_SETTING_ROAD_SIDE :Stroossegefierer: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Wiel d'Säit op där gefuer gëtt +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Lénks fueren +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Riets fueren + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Héichtenkaartrotatioun: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Géint d'Auer @@ -1520,14 +1514,20 @@ STR_CONFIG_SETTING_SERVICEATHELIPAD_HELPTEXT :Schéck Helikop STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR :Landschaft-Toolbar op Zuch/Strooss/Schëff/Fluchhafen-Toolbar linken: {STRING} STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR_HELPTEXT :Wann eng Toolbar fir Konstruktiounen opgemeet gëtt, gëtt och d'Toolbar fir d'Terrainverännerung opgemeet -STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR :Landfaarf déi op der klénger Kaart benotzt get: {STRING} +STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR :Landfaarf déi op der klénger Kaart benotzt gëtt: {STRING} STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Faarf vum Terrain vun der klenger Kaart ###length 3 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Gréng STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Donkelgréng STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Mof +STR_CONFIG_SETTING_LINKGRAPH_COLOURS :Cargo Flow Overlayfaarwen: {STRING} +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_HELPTEXT :Faarfschema den fir den Overlay vum Cargo Flow genotzt gëtt ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :Greng bis roud (original) +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Greng bis blo +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Gro bis roud +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :Grostufen STR_CONFIG_SETTING_SCROLLMODE :Usiicht-Scrollverhalen: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Verhalen beim Scrolle vun der Kaart @@ -1591,11 +1591,11 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Mécht eng Fens STR_CONFIG_SETTING_AUTOSAVE :Autospäicheren: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Setz den Interval tëschend automateschen Späicherstänn -STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :Benotz {STRING} Datumsformat fir Späichernimm +STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :Datumsformat fir Späichernimm: {STRING} STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT :Format vum Datum am Numm vum Späicherstand ###length 3 -STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_LONG :laangen (31ten Dez 2008) -STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_SHORT :kuerzen (31-12-2008) +STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_LONG :laang (31ten Dez 2008) +STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_SHORT :kuerz (31-12-2008) STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_ISO :ISO (2008-12-31) STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME :Paus d'Spill beim Start vun enger neier Partie: {STRING} @@ -1743,6 +1743,8 @@ STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER_HELPTEXT :Weis d'Zeitung STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS :Accidenter / Katastrophen: {STRING} STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT :Weis d'Zeitung wann Accidenter oder Katastrophe geschéien +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER :Accidenter vu Gefierer vum Géigner: {STRING} +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER_HELPTEXT :Eng Zeitung uweisen wann e Gefier vum Géigner en Accident hat STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION :Firmeninformatiounen: {STRING} STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT :Weis d'Zeitung wann eng nei Firma opgeet, oder wann ee riskéiert Bankrott ze goen @@ -1801,8 +1803,8 @@ STR_CONFIG_SETTING_ECONOMY_TYPE_ORIGINAL :Original STR_CONFIG_SETTING_ECONOMY_TYPE_SMOOTH :Glaat STR_CONFIG_SETTING_ECONOMY_TYPE_FROZEN :Agefruer -STR_CONFIG_SETTING_ALLOW_SHARES :Undeeler vun aaneren Firmen kafen: {STRING} -STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Wann ugeschalt, dierfen Aktien vu Firmen kaf an verkaf ginn. Aktien si just fir Firme verfügbar, déi en gewëssen Alter erreecht hunn +STR_CONFIG_SETTING_ALLOW_SHARES :Undeeler vun aaneren Firme kafen: {STRING} +STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Wann ugeschalt, dierfen Aktien vu Firme kaf an verkaf ginn. Aktien si just fir Firme verfügbar, déi en gewëssen Alter erreecht hunn STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Minimalt Firmenalter fir Aktien ze handelen: {STRING} STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Definéiert d'minimalt Alter vun enger Firma, befier anerer kënnen Undeeler un Aktien vun hier kafen. @@ -1884,7 +1886,7 @@ STR_CONFIG_SETTING_SOFT_LIMIT_VALUE :{COMMA} ###setting-zero-is-special STR_CONFIG_SETTING_SOFT_LIMIT_DISABLED :ausgeschalt -STR_CONFIG_SETTING_ZOOM_MIN :Maximalen Ranzoom Level: {STRING} +STR_CONFIG_SETTING_ZOOM_MIN :Maximale Razoom Level: {STRING} STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT :Maximal Razoomstuf fir Usiichtsfënsteren. Et gëtt méi Späicher gebraucht wann d'Stufen ze grouss ginn STR_CONFIG_SETTING_ZOOM_MAX :Maximalen Rauszoom Level: {STRING} STR_CONFIG_SETTING_ZOOM_MAX_HELPTEXT :Maximal Rauszoom-Stuf fir Usiichtsfënsteren. Méi grouss Rauszoom-Stufen kënnen Ruckeler verursaachen @@ -1920,31 +1922,31 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Keng STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Ufangs-Gréisst vu Stied multiplizéiren mat: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Duerchschnëttsgréisst vu Stied an Proportioun zu normalen Dierfer um Spillstart -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Aktualiséier d'Distributiounsgrafik all {STRING}{NBSP}D{P 0:2 ag eeg} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Zäit tëscht nofolgenden Neiberechnungen vun der Linkgrafik. All Neiberechnung rechent d'Pläng fir eng Komponent vun der Grafik. Dat heescht dass en Wert X fir dës Astellung net all X Deeg aktualiséiert gëtt. Nëmmen een Komponent gëtt aktualiséiert. Wat méi kuerz gesat, wat méi CPU Rechenzäit gebraucht gëtt. Wat se méi laang gesat gëtt, wat méi Zäit vergeet bis Wuerendistributioun op enger neier Route gestart gëtt. -STR_CONFIG_SETTING_LINKGRAPH_TIME :Benotz {STRING}{NBSP}D{P 0:2 ag eeg} fir d'Neiberechnung vum Distributiounsgraf -STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Zäit déi gebraucht gëtt fir all Neiberechnung vun enger Linkgrafikkomponent. Wann eng Neiberechnung ufenkt, gëtt en Thread erstallt dee fir dës Unzuel un Deeg leeft. Wann de Wäert ze kleng ass, kann den Thread net an der gewënschter Zäit faerdeg ginn an et kënnt zu engem Lag. Wann de Wäert méi héich gesat gëtt, brauch d'Distributioun méi lang fir erneiert ze ginn wann eng Streck ännert - -STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distributiounsmodus fir Passagéier: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symmetresch" heescht, dass ongeféier d'selwecht vill Passagéier vun A op B wéi vu B op A geschéckt ginn. "asymmetresch" heescht, dass eng arbiträr Unzuel u Wueren an d'jeweileg Richtung geschéckt ginn. "manuell" heescht dass keng automatësch Distributioun stattfënnt fir Passagéier -STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Distributiounsmodus fir Post: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"symmetresch" heescht, dass ongeféier d'selwecht vill vun A op B wéi vu B op A geschéckt ginn. "asymmetresch" heescht, dass eng arbiträr Unzuel u Wueren an d'jeweileg Richtung geschéckt ginn. "manuell" heescht dass keng automatësch Distributioun stattfënnt fir Post -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Distributiounsmodus fir d'GEPANZERT Wuereklass: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :D'GEPANZERT Wuereklass huet Wäertsaachen am geméissegte Klima, Diamanten am Sub-Tropenklima an Gold am sub-arktësche Klima. NewGRFen kënnen dat änneren. "Symmetrësch" heescht, dass ongeféier d'selwecht vill vun A op B wéi vu B op A geschéckt ginn. "asymmetrësch" heescht, dass eng arbiträr Unzuel u Wueren an d'jeweileg Richtung geschéckt ginn. "manuell" heescht dass keng automatësch Distributioun stattfënnt. Et gëtt emfuelen dëst op asymmetrësch oder manuell ze loossen wann ee sub-arktësch spillt, well Banken kee Gold zréck an d’Minen liwweren. Fir geméissegt Klima an sub-tropësch Klima kann eng Bank mat der anerer Wäertsachen zeréckschécken. -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Distributiounsmodus fir aner Wuerenklassen: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asymmetresch" heescht dass eng beléiweg Unzuel un Wueren an béid Richtungen verschéckt ginn. "manuell" heescht dass keng automatësch Distributioun stattfënnt. Meeschtens gëtt "asymmetresch" oder manuell gewielt. +STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Aktualiséier d'Verdeelungsgrafik all {STRING}{NBSP}D{P 0:2 ag eeg} +STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Zäit tëscht nofolgenden Neiberechnungen vun der Linkgrafik. All Neiberechnung rechent d'Pläng fir eng Komponent vun der Grafik. Dat heescht, dass en Wert X fir dës Astellung net all X Deeg aktualiséiert gëtt. Nëmmen een Komponent gëtt aktualiséiert. Wat méi kuerz gesat, wat méi CPU Rechenzäit gebraucht gëtt. Wat se méi laang gesat gëtt, wat méi Zäit vergeet bis Wuereverdeelung op enger neier Route gestart gëtt. +STR_CONFIG_SETTING_LINKGRAPH_TIME :Benotz {STRING}{NBSP}D{P 0:2 ag eeg} fir d'Neiberechnung vum Verdeelungsgraf +STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Zäit déi gebraucht gëtt fir all Neiberechnung vun enger Linkgrafikkomponent. Wann eng Neiberechnung ufenkt, gëtt en Thread erstallt dee fir dës Unzuel un Deeg leeft. Wann de Wäert ze kleng ass, kann den Thread net an der gewënschter Zäit faerdeg ginn an et kënnt zu engem Lag. Wann de Wäert méi héich gesat gëtt, brauch d'Verdeelung méi lang fir erneiert ze ginn wann eng Streck ännert + +STR_CONFIG_SETTING_DISTRIBUTION_PAX :Verdeelungsmodus fir Passagéier: {STRING} +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetresch" heescht, dass ongeféier d'selwecht vill Passagéier vun A op B wéi vu B op A geschéckt ginn. "Asymmetresch" heescht, dass eng arbiträr Unzuel u Wueren an d'jeweileg Richtung geschéckt ginn. "Manuell" heescht dass keng automatësch Verdeelung stattfënnt fir Passagéier +STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Verdeelungsmodus fir Post: {STRING} +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Symmetresch" heescht, dass ongeféier d'selwecht vill vun A op B wéi vu B op A geschéckt ginn. "Asymmetresch" heescht, dass eng arbiträr Unzuel u Wueren an d'jeweileg Richtung geschéckt ginn. "Manuell" heescht dass keng automatësch Verdeelung stattfënnt fir Post +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Verdeelungsmodus fir d'GEPANZERT Wuereklass: {STRING} +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :D'GEPANZERT Wuereklass huet Wäertsaachen am geméissegte Klima, Diamanten am Sub-Tropenklima an Gold am sub-arktësche Klima. NewGRFen kënnen dat änneren. "Symmetrësch" heescht, dass ongeféier d'selwecht vill vun A op B wéi vu B op A geschéckt ginn. "Asymmetrësch" heescht, dass eng arbiträr Unzuel u Wueren an d'jeweileg Richtung geschéckt ginn. "Manuell" heescht dass keng automatësch Verdeelung stattfënnt. Et gëtt emfuelen dëst op asymmetrësch oder manuell ze loossen wann ee sub-arktësch spillt, well Banken kee Gold zréck an d’Minen liwweren. Fir geméissegt Klima an sub-tropësch Klima kann eng Bank mat der anerer Wäertsachen zeréckschécken. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Verdeelungsmodus fir aner Wuereklassen: {STRING} +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asymmetresch" heescht dass eng beléiweg Unzuel un Wueren an béid Richtungen verschéckt ginn. "Manuell" heescht dass keng automatësch Verdeelung stattfënnt. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuell STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asymmetresch STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :symmetresch -STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Distributiounsgenauegkeet: {STRING} -STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Wat de Wäert méi héich ass, wat méi CPU benotzt gëtt fir d'Linkgrafik ze zeechnen. Wann ze héich gesat, kann et zu Lags kommen. Ze niddreg gesat kann d'Distributioun ongenau ginn an d'Wueren net sou verdeelt ginn wéi geduet +STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Verdeelungsgenauegkeet: {STRING} +STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Wat de Wäert méi héich ass, wat méi CPU benotzt gëtt fir d'Linkgrafik ze zeechnen. Wann ze héich gesat, kann et zu Lags kommen. Ze niddreg gesat kann d'Verdeelung ongenau ginn an d'Wueren net sou verdeelt ginn wéi geduet STR_CONFIG_SETTING_DEMAND_DISTANCE :Afloss vun der Distanz op d'Nofro: {STRING} STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Wann's de en méi héije Wäert wéi 0 wiels, huet d'Differenz tëscht 2 Statiounen A an B en Afloss dorop wéivill Wueren geschéckt ginn. Wat B méi wäit ewech vun A ass, wat manner Wueren geschéckt ginn. Wat de Wäert méi héich gesat gëtt, wat manner Wueren op eng Statioun wait ewech an méi Wueren op eng Statioun méi no geschéckt ginn. STR_CONFIG_SETTING_DEMAND_SIZE :Unzuel vun zeréckgeschéckte Wueren fir de symmetreschen Modus: {STRING} -STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Wann een dëst op manner wéi 100% setzt, gëtt déi symmetresch Distributioun méi wéi eng asymmetrësch behandelt. Manner Wueren ginn zeréckgeschéckt wann en bestëmmten Wäert op eng Statioun geschéckt gouf. Bei 0% verhält sech d'symmetresch Distributioun wéi eng asymmetresch +STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Wann een dëst op manner wéi 100% setzt, gëtt déi symmetresch Verdeelung méi wéi eng asymmetrësch behandelt. Manner Wueren ginn zeréckgeschéckt wann en bestëmmten Wäert op eng Statioun geschéckt gouf. Bei 0% verhält sech d'symmetresch Verdeelung wéi eng asymmetresch STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Sättegung vu kuerzen Weeër befier grouss Weeër benotzt ginn: {STRING} STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Oft gëtt et e puer Weeër tëscht zwou Statiounen. Cargodist siedegt fir d'éischt de kierzten, dann den zweetkierzten a.s.w. Siedegung gëtt bestemmt durch Kapazitéit an geplangten Notzung. Wann all Wee gesiedegt ass, an nach emmer eng Nofro do ass, ginn all d'Weeër iwwersiedegt, mat Präferenz déi mat grousser Kapazitéit. Gréissten Deel vun der Zäit rechent den Algorithmus d'Kapazitéit allerdéngs net richteg. Des Astellung erlabt engem en Prozentsaz ze bestëmmen fir den éischten Wee befier en zweeten Wee benotzt gëtt. Setz en enner 100% fir iwwerfëllten Statiounen ze vermeide wann d'Kapazitéit iwwerschat gouf. @@ -2027,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatescht Em STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Erlab Zich bei engem Signal emzedréinen, wann se eng laang Zäit geward hunn ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(recommandéiert) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(recommandéiert) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Astellung änneren @@ -2044,7 +2046,7 @@ STR_CONFIG_ERROR_INVALID_GRF_SYSTEM :System NewGRF STR_CONFIG_ERROR_INVALID_GRF_INCOMPATIBLE :net mat dëser Versioun vun OpenTTD kompatibel STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN :onbekannt STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL :{WHITE}... Kompressiounslevel '{STRING}' ass net gültëg. -STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM :{WHITE}... Spillstand format '{STRING}' gëtt et net. Revertéiren zu '{STRING}' +STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM :{WHITE}... Späicherstand format '{STRING}' gëtt et net. Revertéiren zu '{STRING}' STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND :{WHITE}... ignoréiren Basis Grafik Set '{STRING}': net fonnt STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND :{WHITE}... ignoréiren Basis Sound Set '{STRING}': net fonnt STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND :{WHITE}... ignoréiren Basis Musik Set '{STRING}': net fonnt @@ -2070,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Beschtel STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Astellungen STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Astellungen STR_INTRO_ONLINE_CONTENT :{BLACK}Check Online Inhalt -STR_INTRO_SCRIPT_SETTINGS :{BLACK}KI / Spill-Script Astellungen +STR_INTRO_AI_SETTINGS :{BLACK}KI Astellungen +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Spillscriptastellungen STR_INTRO_QUIT :{BLACK}Eraus STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Start en neit Spill. Ctrl+Klick iwwerspréngt Kaartenkonfiguratioun @@ -2090,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Beschtel STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Displayastellungen STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF Astellungen uweisen STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Check op neien Inhalt kann downgeload gin -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Weis KI an Spill-Script-Astellungen +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}KI-Astellungen uweisen +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Spillscriptastellungen uweisen STR_INTRO_TOOLTIP_QUIT :{BLACK}Aus 'OpenTTD' eraus goen STR_INTRO_BASESET :{BLACK}Dem grad ausgewielte Basis Grafikset fehlen {NUM} Sprite{P "" s}. W.e.g. no Updates fir dëse Set sichen. @@ -2105,12 +2109,12 @@ STR_QUIT_NO :{BLACK}Nee # Abandon game STR_ABANDON_GAME_CAPTION :{WHITE}Spill ofbriechen STR_ABANDON_GAME_QUERY :{YELLOW}Bass du sécher, dass du des Partie ofbrieche wëlls? -STR_ABANDON_SCENARIO_QUERY :{YELLOW}Sécher, dass du aus dësem Szenario eraus wëlls goen? +STR_ABANDON_SCENARIO_QUERY :{YELLOW}Bass du sécher, dass du dëse Szenario ofbrieche wëlls? # Cheat window STR_CHEATS :{WHITE}Cheater STR_CHEATS_TOOLTIP :{BLACK}Checkboxen weisen un dass du den Cheat schon eng Kéier benotzt hues -STR_CHEATS_NOTE :{BLACK}Notiz: jeglech Benotzung vun dësen Astellungen wäert am Spillstand opgeholl ginn +STR_CHEATS_NOTE :{BLACK}Notiz: jeglech Benotzung vun dësen Astellungen wäert am Späicherstand opgeholl ginn STR_CHEAT_MONEY :{LTBLUE}Suen ëm {CURRENCY_LONG} erhéijen STR_CHEAT_CHANGE_COMPANY :{LTBLUE}Als Firma {ORANGE}{COMMA} spillen STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magësche Bulldozer (Industrien ofrappen, onzerstéierbar Objeten): {ORANGE}{STRING} @@ -2122,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Datum STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Änner dat aktuellt Joer STR_CHEAT_SETUP_PROD :{LTBLUE}Erlaabt d'ännere vun de Produktiounswäerter: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Gemässegt Klima Landschaft -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-Arktesch Landschaft -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-Tropesch Landschaft -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Spillsaacheland Landschaft - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Neie Faarfschema @@ -2258,6 +2256,7 @@ STR_NETWORK_SERVER_LIST_LANDSCAPE :{SILVER}Landsch STR_NETWORK_SERVER_LIST_MAP_SIZE :{SILVER}Kaartegréisst: {WHITE}{COMMA}x{COMMA} STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}Serverversioun: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}Serveradress: {WHITE}{STRING} +STR_NETWORK_SERVER_LIST_INVITE_CODE :{SILVER}Invitatiounscode: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_START_DATE :{SILVER}Startdatum: {WHITE}{DATE_SHORT} STR_NETWORK_SERVER_LIST_CURRENT_DATE :{SILVER}Momentanen Datum: {WHITE}{DATE_SHORT} STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}Spill-Script: {WHITE}{STRING} (v{NUM}) @@ -2359,7 +2358,6 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nei Firma) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Eng nei Firma erstellen an hier bäitrieden STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Dat bass du STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Dest ass den Host vun der Partie -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} Client{P "" en} / {NUM} Firm{P a en} # Matches ConnectionType ###length 5 @@ -2481,18 +2479,18 @@ STR_NETWORK_SERVER_MESSAGE_GAME_UNPAUSED :Spill geet weid STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS :Unzuel Spiller STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS :Spiller verbannen STR_NETWORK_SERVER_MESSAGE_GAME_REASON_MANUAL :manuell -STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT :Spill-Script +STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT :Spillscript STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :warden op d'Aktualiséirung vun der Linkgrafik STR_NETWORK_MESSAGE_CLIENT_LEAVING :verloossen STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} ass dem Spill bäigetrueden -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} ass an d'Spill komm (Client #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} ass bei d'Firma #{2:NUM} gaangen +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} ass an d'Spill komm (Client #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} ass bei d'Firma #{2:NUM} gaangen STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} ass als Zuschauer do -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} huet eng nei Firma gegrënnt (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} huet d'Spill verlooss ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} huet eng nei Firma gegrënnt (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} huet d'Spill verlooss ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} huet säin Numm op {STRING} gewiesselt -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} huet {2:CURRENCY_LONG} der Firma {1:STRING} ginn +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} huet {2:CURRENCY_LONG} der Firma {1:STRING} ginn STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}De Server huet d'Sessioun zougemaach STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}De Server gëtt nei gestart...{}W.e.g. waarden... STR_NETWORK_MESSAGE_KICKED :*** {STRING} gouf gekickt. Grond: ({STRING}) @@ -2556,7 +2554,7 @@ STR_CONTENT_TYPE_SCENARIO :Szenario STR_CONTENT_TYPE_HEIGHTMAP :Héichtekaart STR_CONTENT_TYPE_BASE_SOUNDS :Basis Sounds STR_CONTENT_TYPE_BASE_MUSIC :Basis Musik -STR_CONTENT_TYPE_GAME_SCRIPT :Spill-Script +STR_CONTENT_TYPE_GAME_SCRIPT :Spillscript STR_CONTENT_TYPE_GS_LIBRARY :GS Librairie # Content downloading progress window @@ -2606,6 +2604,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}gesättegt STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}iwwerlaascht +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} muss all Mound vun {STATION} op {STATION} transportéiert ginn ({COMMA}% vun der Kapazitéit){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} gëtt zeréck transportéiert op ({COMMA}% vun der Kapazitéit) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Duerchschnëttszäit: {NUM}{NBSP}D{P ag eeg} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Reechwäit markéieren STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Aus @@ -2614,6 +2617,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Weis d'R STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Weis d'Reechwäit vun dem Gebäi un STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Akzeptéiert: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Liwwert: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Ennerhaltskäschten: {GOLD}{CURRENCY_SHORT}/Jr # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Statioun verbannen @@ -2674,13 +2678,14 @@ STR_STATION_CLASS_WAYP :Weepunkten # Signal window STR_BUILD_SIGNAL_CAPTION :{WHITE}Signalauswiel +STR_BUILD_SIGNAL_TOGGLE_ADVANCED_SIGNAL_TOOLTIP :{BLACK}Wiesselen tëschent erweiderte Signaler STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Block Signal (Diks){} Dest ass e Basis-Signal, wat nëmmen engem Zuch zur selwechter Zait erlaabt an engem Block ze sinn STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}Agangs-Signal (Diks){}Gréng soulaang een oder méi gréng Ausgangs-Signaler op dem nächsten Streckenabschnitt sinn. Anescht ass et rout. STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Ausgangs-Signal (Diks){}Verhält sech wéi en Block-Signal mee gëtt gebraucht fir déi korrekt Faarf ob Agangs- an Combo-Pre-Signaler ze setzen STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Combo-Signal (Diks){}E Combo-Signal agéiert wéi en Agangs- a wéi en Ausgangs-Signal. Dest erlaabt engem vill "Beem" vu Pre-Signaler ze bauen STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}Wee-Signal (Diks){}E Wee-Signal erlaabt méi wéi engem Zuch an en Block ze fueren zur selweschter Zäit, wann den Zuch en Wee op en sécheren Stop-Punkt kann reservéiren. Standard Wee-Signaler kënne vu béide Säiten duerchfuer ginn STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP :{BLACK}Einbahn-Wee-Signal (Diks){}E Wee-Signal erlaabt méi wéi engem Zuch an en Block ze fueren zur selweschter Zäit, wann den Zuch en Wee op en sécheren Stop-Punkt kann reservéiren. Einbahn-Wee-Signaler kënnen net de falsche Wee duerchfuer ginn -STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Block Signal (Elektresch){}Dest ass e Basis-Signal, mat dem een en Zuch an engem selwechten Block zur selwechter Zäit erlaabt +STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Block Signal (Elektresch){}Dëst ass e Basis-Signal, mat dem een en Zuch an engem selwechten Block zur selwechter Zäit erlaabt STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}Agangs-Signal (Elektresch){}Gréng soulaang een oder méi gréng Ausgangssignaler vum nächsten Streckenabschnitt kommen. Anescht ass et rout STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Ausgangs-Signal (Elektresch){}Verhält sech wéi e Block-Signal mee gëtt gebraucht fir déi korrekt Faarf vun den Agangs- an Combo Pre-Signaler ze setzen STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Combo-Signal (Elektresch){}D'Combo-Signal ass einfach en An- an Ausgangssignal. Dëst erlaabt grouss "Beem" Presignaler ze bauen @@ -2695,16 +2700,18 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Setzt Si STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Zuchbréck auswielen STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Stroossebréck auswielen STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Bréckenauswiel - Wiel deng Bréck aus -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Stolen Hängebréck STR_BRIDGE_NAME_GIRDER_STEEL :Stoldréier Bréck STR_BRIDGE_NAME_CANTILEVER_STEEL :Fräidroend Stolbréck STR_BRIDGE_NAME_SUSPENSION_CONCRETE :Betons Hängebréck STR_BRIDGE_NAME_WOODEN :Holze Bréck STR_BRIDGE_NAME_CONCRETE :Betons Bréck -STR_BRIDGE_NAME_TUBULAR_STEEL :Rouerstol Bréck -STR_BRIDGE_TUBULAR_SILICON :Rouer, Silikon +STR_BRIDGE_NAME_TUBULAR_STEEL :Stolrouer Bréck +STR_BRIDGE_TUBULAR_SILICON :Silikonrouer # Road construction toolbar @@ -2734,8 +2741,8 @@ STR_ROAD_NAME_ROAD :Strooss STR_ROAD_NAME_TRAM :Tramway # Road depot construction window -STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Ausriichtung vum Stroossendepot -STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Wielt d'Stroossendepot Ausriichtung +STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Ausriichtung vum Stroosseschapp +STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Wielt d'Ausriichtung vum Stroossenschapp STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION :{WHITE}Ausriichtung vum Tramschapp STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Tramschapp Ausriichtung wielen @@ -2800,11 +2807,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Landscha STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}En Eck vum Land erofsetzen. Zéien setzt den éischten ugewielten Eck erof an planéiert d'ugewielten Land op déi nei Eckhéicht. Ctrl wielt d'Land diagonal. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}En Eck vum Land unhiewen. Zéien wielt den éischten Eck an planéiert d'ugewielten Land ob déi nei Eckhéicht. Ctrl wielt d'Land diagonal. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Land planéiren. Ctrl wielt d'Land diagonal aus. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Kaf Land fir zukünftëg Benotzung. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Kaf Land fir zukünftëg Benotzung. Ctrl wielt d'Areal diagonal. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Objetsauswiel -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Wiel den Objet dee gebaut gëtt. Shift wiesselt tescht bauen / ongeféier Käschten uweisen +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Wiel den Objet dee gebaut gëtt. Ctrl wielt d'Areal diagonal Shift wiesselt tescht bauen / ongeféier Käschten uweisen STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Wiel d'Klass vun dem Objet dee sollt gebaut ginn STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Preview vum Objet STR_OBJECT_BUILD_SIZE :{BLACK}Gréisst: {GOLD}{NUM} x {NUM} Felder @@ -2816,7 +2823,7 @@ STR_OBJECT_CLASS_TRNS :Antennen STR_PLANT_TREE_CAPTION :{WHITE}Beem STR_PLANT_TREE_TOOLTIP :{BLACK}Wielt de Baamtyp. Wann d'Feld schons e Baam huet, ginn méi Beem vu verschiddenen Arten gesat STR_TREES_RANDOM_TYPE :{BLACK}Zoufälleg Beem -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Zoufälleg Beem planzen. Shift wiesselt tëscht bauen an ongeféier Käschten uweisen +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Zoufälleg Type vu Beem planzen. Ctrl wielt d'Land diagonal. Shift wiesselt tëscht bauen an ongeféier Käschten uweisen STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Zoufälleg Beem STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Beem zoufälleg iwwert d'Landschaft setzen STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2848,6 +2855,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Zoufalls STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Grënn d'Stad op enger zoufälleger Plaz STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Vill zoufälleg Dierfer STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}D'Kaart zoufälleg mat Dierfer fëllen +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}All Dierfer vergréisseren +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}All Dierfer e bësse wuesse loossen STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Stadnumm: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Stadnumm agin @@ -3009,7 +3018,7 @@ STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL :Stole fräidroe STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_CONCRETE :Stolbeton Zuchhängebréck STR_LAI_BRIDGE_DESCRIPTION_RAIL_WOODEN :Holzen Zuchbréck STR_LAI_BRIDGE_DESCRIPTION_RAIL_CONCRETE :Betons Zuchbréck -STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL :Rouerstol Zuchbréck +STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL :Stolrouer Zuchbréck STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_STEEL :Stolen Hängebréck STR_LAI_BRIDGE_DESCRIPTION_ROAD_GIRDER_STEEL :Stoldréier Bréck @@ -3017,7 +3026,7 @@ STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL :Fräidroend Sto STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_CONCRETE :Stolbetons Hängebréck STR_LAI_BRIDGE_DESCRIPTION_ROAD_WOODEN :Holze Bréck STR_LAI_BRIDGE_DESCRIPTION_ROAD_CONCRETE :Betons Bréck -STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL :Rouerstol Brèck +STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL :Stolrouer Bréck STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT :Aquadukt @@ -3112,7 +3121,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detailer STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Keng Informatioun do STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter-String: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Datei iwwerschreiwen STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Bass du sécher, dass du d'existéirend Datei iwwerschreiwe wëlls? STR_SAVELOAD_DIRECTORY :{STRING} (Verzeechnëss) @@ -3126,6 +3135,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kaartegr STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Wiel d'Gréisst vun der Kaart a Felder. D'Unzuel vu benotzbare Felder wäert e bësse méi kleng sinn STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Unz. Dierfer: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Stiednimm: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Stil vun de Stiednimm wielen STR_MAPGEN_DATE :{BLACK}Datum: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Unz. Industrien: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Héchste Punkt: @@ -3139,13 +3150,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Wüstenu STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Wüstenundeel em zéng Prozent eropsetzen STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Wüstenundeel em zéng Prozent erofsetzen STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Landgenerator: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terrain Typ: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Mieresspigel: +STR_MAPGEN_SEA_LEVEL :{BLACK}Mieresspigel: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Flëss: STR_MAPGEN_SMOOTHNESS :{BLACK}Mëllt: STR_MAPGEN_VARIETY :{BLACK}Vielfaltverdeelung: STR_MAPGEN_GENERATE :{WHITE}Generéiren +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF Astellungen +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}NewGRF Astellungen uweisen +STR_MAPGEN_AI_SETTINGS :{BLACK}KI Astellungen +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}KI-Astellungen uweisen +STR_MAPGEN_GS_SETTINGS :{BLACK}Spillscriptastellungen +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Spillscriptastellungen uweisen + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Englesch (Original) +STR_MAPGEN_TOWN_NAME_FRENCH :Franséisch +STR_MAPGEN_TOWN_NAME_GERMAN :Däitsch +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Englesch (Erweidert) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Lateinamerikanesch +STR_MAPGEN_TOWN_NAME_SILLY :Blöd +STR_MAPGEN_TOWN_NAME_SWEDISH :Schwedesch +STR_MAPGEN_TOWN_NAME_DUTCH :Holländesch +STR_MAPGEN_TOWN_NAME_FINNISH :Finnesch +STR_MAPGEN_TOWN_NAME_POLISH :Polnesch +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovakesch +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norwegesch +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungaresch +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Éisträichesch +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumänesch +STR_MAPGEN_TOWN_NAME_CZECH :Tschechesch +STR_MAPGEN_TOWN_NAME_SWISS :Schwäitzer +STR_MAPGEN_TOWN_NAME_DANISH :Dänesch +STR_MAPGEN_TOWN_NAME_TURKISH :Türkesch +STR_MAPGEN_TOWN_NAME_ITALIAN :Italienesch +STR_MAPGEN_TOWN_NAME_CATALAN :Katalanesch # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kaarteränner: @@ -3204,7 +3243,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Detaill STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Aktiv NewGRF Dateien STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Inaktiv NewGRF Dateien STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Preset auswielen: -STR_NEWGRF_FILTER_TITLE :{ORANGE}String filteren: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Gewielte Preset lueden STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Preset späichern STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Aktuell Lëscht als Preset späichern @@ -3291,6 +3330,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Viregt S STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Géi weider op déi nächst normal Sprite, iwwersprang all pseudo/recolour/font Sprite an sprang zréck op den Ufank no der leschter. STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representatioun vun der grad gewielter Sprite. Den Alignement gëtt ignoréiert wann d'Sprite gezun gëtt STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Beweg Sprite, X an Y offsets enneren sech. Ctrl+Klick fir de Sprite8 Eenheete matenen ze bewegen. + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Offset zentréiert +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite zentréiert + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Crosshair + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Relativ zerécksetzen STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Momentan relativ Offsets zerécksetzen STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X-Offset: {NUM}, Y-Offset: {NUM} (Absolut) @@ -3305,18 +3351,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Warnung: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Fehler: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}E fatalen NewGRF Fehler ass geschitt:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}En NewGRF Fehler ass geschitt:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Den NewGRF "{STRING}" huet e fatale Fehler gemet:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}Den NewGRF "{STRING}" huet e Fehler gemet:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} wärt net mat der TTDPatch Versioun déi vun OpenTTD erkannt gouf funktionéiren -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} ass fir {STRING} Versioun vun TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} ass designed fir mat {STRING} benotzt ze ginn -STR_NEWGRF_ERROR_INVALID_PARAMETER :Invalide Parameter fir {1:STRING}: Parameter {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} muss firun {STRING} geluede ginn -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} muss no {STRING} geluede ginn -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} brauch OpenTTD Versioun {STRING} oder méi nei +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} ass fir {2:STRING} Versioun vun TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} ass designed fir mat {2:STRING} benotzt ze ginn +STR_NEWGRF_ERROR_INVALID_PARAMETER :Invalide Parameter fir {1:STRING}: Parameter {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} muss firun {2:STRING} geluede ginn +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} muss no {2:STRING} geluede ginn +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} brauch OpenTTD Versioun {2:STRING} oder méi nei STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF Datei déi designed gouf fir ze iwwersetzen STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Zevill NewGRFen gelueden. -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :{1:STRING} als statesch NewGRF lueden mat {STRING} kann Desyncs verursaachen +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :{1:STRING} als statesch NewGRF lueden mat {2:STRING} kann Desyncs verursaachen STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Onerwaarte Sprite (Sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Onbekannten Aktioun 0 property {4:HEX} (Sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Versicht invalid ID ze benotzen (Sprite {3:NUM}) @@ -3448,14 +3494,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Exklusiv Transp STR_LOCAL_AUTHORITY_ACTION_BRIBE :D'Gemeng bestiechen ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Eng kleng Marketingaktioun starten, fir méi Passagéier a Wueren ze gewannen.{}Gëtt fir eng Zäit de Statiounen em de Stadkär eng besser Bewertung.{}Käschten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Eng mëttel Marketingaktioun starten, fir méi Passagéier a Wueren ze gewannen.{}Gëtt fir eng Zäit de Statiounen an engem mëttlere Radius em de Stadkär eng besser Bewertung.{}Käschten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Eng grouss Marketingaktioun starten, fir méi Passagéier a Wueren ze gewannen.{}Gëtt fir eng Zäit de Statiounen an engem méi grousse Radius em de Stadkär eng besser Bewertung.{}Käschten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Stroossenneibau an der Stad finanzéieren.{}Stéiert den Traffic op de Stroossen fir déi nächst 6 Méint.{} Käschten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Eng Statu zur Éier vun der Firma bauen.{}Gëtt de Statiounen an dëser Stad permanent eng besser Bewertung.{}Käschten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}De Bau vun neie Kommerzgebaier finanzéieren.{}Gëtt fir eng Zäit dem Stadwuesstum e Schub.{} Käschten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Kaaft fir 1 Joer exklusiv Transportrechter an dëser Stad.{}D'Gemeng erlaabt den Transport vu Passagéier a Wueren nëmmen denger Firma.{}Käschten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}D'Gemeng bestiechen fir d'Bewäertung ze erhéijen, mam Risiko fir eng grouss Bestrofung, falls der erwëscht gitt.{} Käschten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Eng kleng Marketingaktioun starten, fir méi Passagéier a Wueren unzezéien.{}Gëtt fir eng Zäit de Statiounen em de Stadkär eng besser Bewertung.{}{POP_COLOUR}Käschten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Eng mëttel Marketingaktioun starten, fir méi Passagéier a Wueren unzezéien.{}Gëtt fir eng Zäit de Statiounen an engem mëttlere Radius em de Stadkär eng besser Bewertung.{}{POP_COLOUR}Käschten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Eng grouss Marketingaktioun starten, fir méi Passagéier a Wueren ze unzezéien.{}Gëtt fir eng Zäit de Statiounen an engem méi grousse Radius em de Stadkär eng besser Bewertung.{}{POP_COLOUR}Käschten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Stroossenneibau an der Stad finanzéieren.{}Stéiert den Traffic op de Stroossen fir déi nächst 6 Méint.{}{POP_COLOUR}Käschten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Eng Statu zur Éier vun der Firma bauen.{}Gëtt de Statiounen an dëser Stad permanent eng besser Bewertung.{}{POP_COLOUR}Käschten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}De Bau vun neie Kommerzgebaier finanzéieren.{}Gëtt fir eng Zäit dem Stadwuesstum e Schub.{}{POP_COLOUR}Käschten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Kaaft fir 1 Joer exklusiv Transportrechter an dëser Stad.{}D'Gemeng erlaabt den Transport vu Passagéier a Wueren nëmmen denger Firma.{}{POP_COLOUR}Käschten: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}D'Gemeng bestiechen fir d'Bewäertung ze erhéijen, mam Risiko fir eng grouss Bestrofung, falls der erwëscht gitt.{}{POP_COLOUR} Käschten: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Ziler @@ -3608,24 +3654,38 @@ STR_FINANCES_CAPTION :{WHITE}{COMPANY STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}Akommes +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Betribskäschten +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Kapitalausgaben ###length 13 STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Konstruktioun STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Nei Gefierer -STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Zuch Betribskäschten -STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Stroossegefierer Betribskäschten -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Fliger Betribskäschten -STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Schëff Betribskäschten +STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Zich +STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Stroossegefierer +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Fliger +STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Schëffer +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Infrastruktur +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Zich +STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}Stroossegefierer +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Fliger +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Schëffer STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Zënssaz STR_FINANCES_SECTION_OTHER :{GOLD}Aaner -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} -STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} +STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Profit STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Kontostand +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Eege Mëttel STR_FINANCES_LOAN_TITLE :{WHITE}Kredit +STR_FINANCES_INTEREST_RATE :{WHITE}Zënssaz: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maximale Kredit: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}{CURRENCY_LONG} léinen STR_FINANCES_BORROW_TOOLTIP :{BLACK}Erhéicht de Kredit. Ctrl+Klick léint de Maximum STR_FINANCES_REPAY_BUTTON :{BLACK}{CURRENCY_LONG} zeréckbezuelen @@ -3710,7 +3770,7 @@ STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUST STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industrienimm - klick op en Numm fir d'Usiicht do drop ze zentréieren. Ctrl+Klick erstellt eng nei Usiicht op d'Industrie STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Akzeptéiert Wuer: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Produzéiert Wuer: {SILVER}{STRING} -STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :All Wuerentypen +STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :All Wuerentyp STR_INDUSTRY_DIRECTORY_FILTER_NONE :Keng # Industry view @@ -3726,7 +3786,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produzé STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Brauch: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} um waarden{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}D'Produktioun änneren (Multipel vun 8, bis op 2040) @@ -3756,6 +3816,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Schéckt STR_VEHICLE_LIST_REPLACE_VEHICLES :Gefierer ersetzen STR_VEHICLE_LIST_SEND_FOR_SERVICING :An d'Revisioun schécken STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Profit dëst Joer: {CURRENCY_LONG} (lescht Joer: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :An de Schapp schécken STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :An den Depot schécken @@ -3787,8 +3849,8 @@ STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Gruppen STR_GROUP_CREATE_TOOLTIP :{BLACK}Klick fir eng Grupp ze maachen STR_GROUP_DELETE_TOOLTIP :{BLACK}Déi ungewielte Grupp läschen STR_GROUP_RENAME_TOOLTIP :{BLACK}Déi ungewielte Grupp ëmbenennen -STR_GROUP_LIVERY_TOOLTIP :{BLACK}Wiessel d'Faarwschema vun dem ausgewielte Grupp -STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Klick fir déi Grupp vum globalen "Autoersetzen" auszeschléissen. Ctrl+klick protegéiert och Ennergruppen +STR_GROUP_LIVERY_TOOLTIP :{BLACK}Wiessel d'Faarwschema vun der ausgewielter Grupp +STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Klick fir déi Grupp vum globalen "Autoersetzen" auszeschléissen. Ctrl+Klick protegéiert och Ennergruppen STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Grupp läschen STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Bassde sécher, dass du des Grupp an all Ennergruppen läsche wëlls? @@ -3847,6 +3909,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Zé STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Distanz: {GOLD}{COMMA} Felder STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Fliger Typ: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :All Wuerentyp +STR_CARGO_TYPE_FILTER_FREIGHT :Fracht +STR_CARGO_TYPE_FILTER_NONE :Keng + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Zuchlëscht - klick op en Zuch fir Informatiounen. Ctrl+Klick fir tëscht dem Verstoppen hin an hier ze sprangen STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Stroossegefierlëscht - klick op en Gefier fir Informatiounen. Ctrl+Klick fir tëscht dem Verstoppen hin an hier ze sprangen @@ -3867,7 +3934,7 @@ STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Fligeren ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Keeft den ungewielten Zuch. Shift+Klick weist ongeféier Käschten ouni Kaf -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Keeft dat ugewielte Stroossegefier. Shift+Klick weist ongeféier Käschten ouni Kaf +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Keeft dat ugewielte Stroossegefier. Shift+Klick weist ongeféier Käschten ouni Kaf un STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Keeft dat ugewielte Schëff. Shift+Klick weist ongeféier Käschten ouni Kaf STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Keeft den ungewielte Fliger. Shift+Klick weist ongeféier Käschten ouni Kaf @@ -4015,7 +4082,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :Fliger STR_ENGINE_PREVIEW_SHIP :Schëff STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Käschten: {CURRENCY_LONG} Gewiicht: {WEIGHT_SHORT}{}Geschwindegkeet: {VELOCITY} Kraaft: {POWER}{}Betribskäschten {CURRENCY_LONG}/Jr{}Kapazitéit: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Käschten: {CURRENCY_LONG} Gewicht: {WEIGHT_SHORT}{}Geschw.: {VELOCITY} Kraaft: {POWER} Max. T.E.: {6:FORCE}{}Betribskäschten: {4:CURRENCY_LONG}/Jr{}Kapazitéit: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Käschten: {0:CURRENCY_LONG} Gewicht: {1:WEIGHT_SHORT}{}Geschw.: {2:VELOCITY} Kraaft: {3:POWER} Max. T.E.: {6:FORCE}{}Betribskäschten: {4:CURRENCY_LONG}/Jr{}Kapazitéit: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Käschten: {CURRENCY_LONG} Max. Geschwindegkeet: {VELOCITY}{}Kapazitéit: {CARGO_LONG}{}Betribskäschten: {CURRENCY_LONG}/Jr STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Käschten: {CURRENCY_LONG} Max. Geschw.: {VELOCITY}{}Fliger Typ: {STRING}{}Kapazitéit: {CARGO_LONG}, {CARGO_LONG}{}Betribskäschten: {CURRENCY_LONG}/Jr STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Käschten: {CURRENCY_LONG} Max. Geschw.: {VELOCITY}{}Fliger Typ: {STRING}{}Kapazitéit: {CARGO_LONG}{}Betribskäschten: {CURRENCY_LONG}/Jr @@ -4174,12 +4241,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Gewiicht STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Gewiicht: {LTBLUE}{WEIGHT_SHORT} {BLACK}Kraaft: {LTBLUE}{POWER}{BLACK} Max. Geschwindegkeet: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit dëst Joer: {LTBLUE}{CURRENCY_LONG} (lescht Joer: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Profit dëst Joer: {LTBLUE}{CURRENCY_LONG} (lescht Joer: {CURRENCY_LONG}) {BLACK}Min. Performance: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Zouverlässegkeet: {LTBLUE}{COMMA}% {BLACK}Pannen säit leschter Revisioun: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Gebaut: {LTBLUE}{NUM}{BLACK} Wäert: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Kapazitéit: {LTBLUE}Keng{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapazitéit: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapazitéit: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapazitéit: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapazitéit: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Kapazitéit: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transferts-Suen: {LTBLUE}{CURRENCY_LONG} @@ -4205,8 +4273,8 @@ STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Wäert: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Total Kapazitéit fir dësen Zuch: -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Eidel STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} vun {STATION} @@ -4445,25 +4513,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Dësen Z STR_TIMETABLE_STATUS_START_AT :{BLACK}Dësen Zäitplang start um {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Start Datum -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Wiel en Datum als Startpunkt fir dësen Zäitplang. Ctrl+Klick setzt de Startpunkt vun dësem Zäitplang an verdeelt et en gläichméisseg op all Gefierer déi dësen Optrag hunn, wann den Optrag komplett mat engem Zäitplang versinn ass +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Wiel en Datum als Startpunkt fir dësen Zäitplang. Ctrl+Klick verdeelt all Gefierer mat dësem Optrag gläichméisseg vum Startpunkt op hierem relativen Optrag aus, wann den Optrag komplett mat engem Zäitplang versinn ass STR_TIMETABLE_CHANGE_TIME :{BLACK}Zäit wiesselen -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Änner Zäit déi den ugewielten Optrag brauche soll +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Änner Zäit déi den ugewielten Optrag brauche soll. Ctrl+Klick ännert d'Zäit fir all Opträg STR_TIMETABLE_CLEAR_TIME :{BLACK}Zäit läschen -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Läsch Zäit fir de gewielten Optrag +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Läsch Zäit fir de gewielten Optrag. Ctrl+Klick läscht d'Zäite fir all opträg STR_TIMETABLE_CHANGE_SPEED :{BLACK}Änner de Geschwindegkeetslimit -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Änner d'maximal Reesgeschwindëgkeet fir de gewielten Optrag +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Änner d'maximal Reesgeschwindëgkeet fir de gewielten Optrag. Ctrl+Klick ännert d'Geschwindegkeet fir all Opträg STR_TIMETABLE_CLEAR_SPEED :{BLACK}Geschwindegkeetslimit läschen -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Maximal Reesgeschwindegkeet vum gewielten Optrag läschen +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Maximal Reesgeschwindegkeet vum gewielten Optrag läschen. Ctrl+Klick läscht d'Geschwindegkeet fir all Opträg STR_TIMETABLE_RESET_LATENESS :{BLACK}Verspeidungszieler zerécksetzen -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Setzt de Verspéidungszieler zréck, sou dass d'Gefier mat Zäit ukënnt +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Setzt de Verspéidungszieler zréck, sou dass d'Gefier mat Zäit ukënnt. Ctrl+klick setzt déi ganz Grupp zeréck, sou das dat lescht Gefiert pünktlech ass an all déi aner méi fréi. STR_TIMETABLE_AUTOFILL :{BLACK}Autofëllen -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fëll den Zäitplang automatesch mat de Wäerter vum nächsten Trajet (Ctrl+Klick fir Wardzäiten probéiren bäizehalen) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fëll den Zäitplang automatesch mat de Wäerter vum nächsten Trajet Ctrl+Klick fir Wardzäiten probéiren bäizehalen STR_TIMETABLE_EXPECTED :{BLACK}Erwaard STR_TIMETABLE_SCHEDULED :{BLACK}Geplangt @@ -4499,20 +4567,22 @@ STR_AI_DEBUG_MATCH_CASE_TOOLTIP :{BLACK}Wiessel STR_AI_DEBUG_CONTINUE :{BLACK}Weider STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}Entpaus an fuer weider mat der KI STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}Debug-output fir dës KI uweisen -STR_AI_GAME_SCRIPT :{BLACK}Spill-Script -STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Check de Spill-Scipt-Log +STR_AI_GAME_SCRIPT :{BLACK}Spillscript +STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Check de Spillscipt-Log STR_ERROR_AI_NO_AI_FOUND :Keng passend KI fonnt fir ze lueden.{}Dës KI ass en Dummy an wäert näischt maachen.{}KI'en kënnen iwwert den 'Online Content' System downgeload ginn. STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}En Script ass ofgestierzt. W.e.g mellt dës dem Autor mat engem Screenshot vun der KI/Spill-Script Debugfënster STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}KI / Spill-Script Debugfënster ass nëmmen fir Serveren verfügbar # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}KI /Spill-Script Konfiguratioun +STR_AI_CONFIG_CAPTION_AI :{WHITE}KI Konfiguratioun +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Spill-Script-Konfiguratioun STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}D'Spill-Script dat am nächsten Spill geluede gëtt STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}D'KIën déi am nächsten Spill geluede ginn STR_AI_CONFIG_HUMAN_PLAYER :Mënschleche Spiller STR_AI_CONFIG_RANDOM_AI :Zoufälleg KI STR_AI_CONFIG_NONE :(keng) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maximal Unzuel vu Géigner: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Eropsetzen STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Gewielte KI an der Lëscht no uewen setzen @@ -4520,12 +4590,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Erofsetz STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Gewielte KI an der Lëscht no ënne setzen STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spill-Script +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parameter STR_AI_CONFIG_AI :{SILVER}KIën -STR_AI_CONFIG_CHANGE :{BLACK}Wiel {STRING} aus -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :KI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Spill-Script +STR_AI_CONFIG_CHANGE_AI :{BLACK}Wiel d'KI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Spill-Script auswielen STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Lued en aneren Script STR_AI_CONFIG_CONFIGURE :{BLACK}Konfiguréieren STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}All Parameter vun dem Script konfiguréieren @@ -4553,7 +4622,7 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Screensh STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Héichtekaartscreenshot STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minimap-Screenshot -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameter STR_AI_SETTINGS_CAPTION_AI :KI STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spill-Script @@ -4607,7 +4676,7 @@ STR_ERROR_GAME_SAVE_FAILED :{WHITE}Fehler b STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Kann d'Datei net läschen STR_ERROR_GAME_LOAD_FAILED :{WHITE}Fehler beim Lueden{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Interne Fehler: {STRING} -STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Futtissen Spillstand - {STRING} +STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Futtissen Späicherstand - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Spillstand ass mat enger méi neier Versioun gemaach STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE :Datei net liesbar STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE :Datei net beschreiwbar @@ -4720,6 +4789,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... zevi STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Kann keng Industrien bauen... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Kann {STRING} net hei bauen... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Kann deen Industrietyp hei net bauen... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Kann Industrie net förderen STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... ze no bei enger anerer Fabrik STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... muss fir d'éischt eng Stad bauen STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... nëmmen 1 pro Stad erlaabt @@ -4734,6 +4804,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... Bës STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... kann nëmmen iwwert der Schnéilinn gebaut ginn STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... kann nëmmen ënnert der Schnéilinn gebaut ginn +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Wéinst Pech huet d'Finanzéiren vun der Förderung net geklappt; probéier nach eng Kéier +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Et gouf keng passend Plaz fonnt fir dës Industrie ze förderen STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Et gouf keng brauchbar Plaz fir '{STRING}' Industrien fonnt STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Änner d'Parameter fir d'Kaartegeneratioun fir eng besser Kaart ze erstellen @@ -4901,6 +4973,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objet am STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... Firmen Haaptgebai am Wee STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Kann dat Land net kafen... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... schon am Besëtz! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... Limit fir d'Baue vun Objeten erreecht # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Kann d'Grupp net erstellen... @@ -4973,6 +5046,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}De Servi STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... Gefier ass zerstéiert +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... net all Gefierer sinn identesch + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Keng Gefierer verfügbar STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Änner d'NewGRF Konfiguratioun STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Nach keng Gefierer verfügbar @@ -4999,6 +5074,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Kann net STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... Gefier kann net op all Statioun goen STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... Gefier kann net op déi Statioun goen STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... en Gefier dat dësen Optrag deelt kann net op déi Statioun goen +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... net all Gefierer hunn déi selwescht Opträg +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... net all Gefierer deelen Opträg STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Kann d'Optragslëscht net deelen... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Kann d'Deelen vun der Optragslëscht net stoppen... @@ -5006,6 +5083,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Kann d'O STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... ze wäit ewech vu leschter Destinatioun STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... Fliger huet net genuch Distanz +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kann dem Gefier keen Zäitplang ginn... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Gefierer kënnen nëmmen op Statiounen halen. diff --git a/src/lang/macedonian.txt b/src/lang/macedonian.txt index 81170c64f3365..43d929a57d2be 100644 --- a/src/lang/macedonian.txt +++ b/src/lang/macedonian.txt @@ -197,6 +197,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}кс STR_UNITS_POWER_METRIC :{COMMA}кс STR_UNITS_POWER_SI :{COMMA}kW + STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -352,9 +353,8 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Напушти # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :игра опции -STR_SETTINGS_MENU_SCRIPT_SETTINGS :АИ / игри поставувања STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF подесувања STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :транспарентност опции STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Место имиња прикажани @@ -792,11 +792,6 @@ STR_GAME_OPTIONS_CAPTION :{WHITE}Опци ###length 42 -###length 2 - - -###length 21 - # Autosave dropdown ###length 5 @@ -817,7 +812,6 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_1_MONTH :Секој ме - # Custom currency window @@ -825,7 +819,6 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_1_MONTH :Секој ме - STR_NUM_CUSTOM_NUMBER :Прилагодено ({NUM}) @@ -841,6 +834,8 @@ STR_SEA_LEVEL_CUSTOM_PERCENTAGE :Прилаго ###length 4 +###length 4 + ###length 7 ###length 4 @@ -864,6 +859,7 @@ STR_CONFIG_SETTING_REALISTIC :Реален ###length 3 +###setting-zero-is-special @@ -959,6 +955,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Дебелин ###length 2 +###length 2 + @@ -1160,11 +1158,9 @@ STR_INTRO_SCENARIO_EDITOR :{BLACK}Сцен STR_INTRO_MULTIPLAYER :{BLACK}Повеќе играчи STR_INTRO_GAME_OPTIONS :{BLACK}Опции на Играта -STR_INTRO_SCRIPT_SETTINGS :{BLACK}АИ / Играта Подесувања -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Покажи АИ и игра поставувања # Quit window @@ -1178,8 +1174,6 @@ STR_ABANDON_GAME_QUERY :{YELLOW}Дал # Cheat window -###length 4 - # Livery window @@ -1272,6 +1266,8 @@ STR_CONTENT_TYPE_GS_LIBRARY :ГШ библи # Linkgraph legend window and linkgraph legend in smallmap +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Прифаќа: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Залихи: {GOLD}{CARGO_LIST} @@ -1446,6 +1442,8 @@ STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}Нов STR_MAPGEN_MAPSIZE :{BLACK}Големина на мапа: STR_MAPGEN_BY :{BLACK}* +###length 21 + # Strings for map borders at game generation @@ -1496,6 +1494,10 @@ STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT :Објекто # Sprite aligner window +###length 2 + + + # NewGRF (self) generated warnings/errors STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING} @@ -1692,6 +1694,8 @@ STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Нов авио STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Опсег: {GOLD}{COMMA} плочки +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Листа за селекција од авиони - кликни на авионот за информации @@ -1946,7 +1950,6 @@ STR_AI_CONFIG_NONE :(никој) STR_AI_CONFIG_GAMESCRIPT :{SILVER}GameScript STR_AI_CONFIG_AI :{SILVER}ЗИС -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :АИ STR_AI_CONFIG_CHANGE_GAMESCRIPT :GameScript @@ -1957,9 +1960,8 @@ STR_AI_LIST_CAPTION_GAMESCRIPT :GameScripts -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :АИ -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :GameScript STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} STR_AI_SETTINGS_START_DELAY :Број на денови за да започнете оваа Пи по претходниот (се дава или зема): {ORANGE}{STRING} @@ -2116,6 +2118,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Не м STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... возилото е уништено + # Specific vehicle errors @@ -2126,6 +2129,8 @@ STR_ERROR_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Авио STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... премногу далеку од претходните дестинација STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... воздухопловот не е доволно опсег +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors # Sign related errors diff --git a/src/lang/malay.txt b/src/lang/malay.txt index 06abb0f908373..d433ddbb82b9e 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -197,6 +197,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}kk STR_UNITS_POWER_METRIC :{COMMA}kk STR_UNITS_POWER_SI :{COMMA}kW + STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -357,10 +358,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Keluar # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Pilihan permainan STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Tetapan -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Al/Tetapan skrip permainan STR_SETTINGS_MENU_NEWGRF_SETTINGS :Tetapan NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Pilihan Ketelusan STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Paparkan nama bandar @@ -899,36 +899,6 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :South African R STR_GAME_OPTIONS_CURRENCY_CUSTOM :Sesuaikan... STR_GAME_OPTIONS_CURRENCY_GEL :Georgian Lari (GEL) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Memandu di sebelah kiri -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Memandu di sebelah kanan - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nama bandar -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Pilih tema untuk nama bandar - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Inggeris (Asal) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Peranchis -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Jerman -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Inggeris (Tambahan) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Amerika Latin -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Mengarut -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Swedish -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Dutch -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finnish -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polish -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovak -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norwegian -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungarian -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austrian -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romanian -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Czech -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Swiss -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danish -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turkish -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italian -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalan - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Simpanan automatik STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Pilih tempoh untuk simpanan permainan automatik @@ -953,12 +923,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :lain -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Saiz Antaramuka -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Sila pilih saiz elemen antara muka untuk digunakan - -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Biasa -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Saiz berganda -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Saiz kuad @@ -1007,8 +971,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Previu: STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}Mata wang anda berbanding 10000 Pound (£) STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Tukar parameter matawang pilihan diri -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Jumlah maksimum pesaing: {ORANGE}{COMMA} - STR_NONE :Tiada STR_FUNDING_ONLY :Melalui pembiayaan sahaja STR_MINIMAL :Minimum @@ -1058,6 +1020,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Lanskap temperate +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Lanskap subartik +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Lanskap subtropik +STR_CLIMATE_TOYLAND_LANDSCAPE :Lanskap alam permainan + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Sangat Rata STR_TERRAIN_TYPE_FLAT :Rata @@ -1120,6 +1088,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Kanan STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maksimum pinjaman permulaan: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Rantaian industri +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Kadar faedah: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Kadar faedah pinjaman; juga mengawal inflasi, jika dibolehkan @@ -1341,6 +1310,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Diperbaiki STR_CONFIG_SETTING_ROAD_SIDE :Kenderaan: {STRING} +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Memandu di sebelah kiri +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Memandu di sebelah kanan + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Putaran heightmap: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Lawan jam @@ -1658,7 +1631,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Berundur secara STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Benarkan keretapi berundur di lampu isyarat, jika ia menuggu lama ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Disyorkan) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Disyorkan) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Tukar nilai tetapan @@ -1697,7 +1670,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Carta ma STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Tetapan STR_INTRO_NEWGRF_SETTINGS :{BLACK}Tetapan NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Periksa Kandungan Atas Talian -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Al/Tetapan Skrip Permainan STR_INTRO_QUIT :{BLACK}Keluar STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Mulakan permainan baru. Ctrl+Klik akan melangkaui konfigurasi peta @@ -1717,7 +1689,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Paparan STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Pamerkan pilihan STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Paparkan tetapan NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Periksa kandungan baru atau yang telah dikemaskini untuk dimuat turun -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Paparan Al/Tetapan Skrip Permainan STR_INTRO_TOOLTIP_QUIT :{BLACK}Keluar 'OpenTTD' STR_INTRO_TRANSLATION :{BLACK}Terjemahan ini kekurangan {NUM} string. Sila bantu menjadikan OpenTTD lebih baik dengan mendaftar sebagai penterjemah. Lihat readme.txt untuk maklumat. @@ -1746,12 +1717,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Tukar t STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Tukar tahun semasa STR_CHEAT_SETUP_PROD :{LTBLUE}Bolehkan pengubahsuaian nilai-nilai pengeluaran: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Lanskap temperate -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Lanskap subartik -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Lanskap subtropik -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Lanskap alam permainan - # Livery window STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Tunjukkan skim warna am @@ -2140,6 +2105,8 @@ STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Ghaibkan # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}tepu +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Serlahan kawasan liputan STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Tiada @@ -2228,8 +2195,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Tinggika STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Pilih Jambatan Keretapi STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Pilih Jambatan Jalanraya STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Pilihan jambatan - klik di jambatan pilihan anda untuk membinanya -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Tergantung, Keluli STR_BRIDGE_NAME_GIRDER_STEEL :Berpalang, Keluli STR_BRIDGE_NAME_CANTILEVER_STEEL :Kantilever, keluli @@ -2581,16 +2546,40 @@ STR_MAPGEN_MAPSIZE :{BLACK}Saiz pet STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Pilih saiz peta dalam petak. Nombor petak bersesuaian akan lebih kecil sedikit STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Jumlah bandar: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nama bandar +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Pilih tema untuk nama bandar STR_MAPGEN_DATE :{BLACK}Tarikh: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Jumlah industri: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Janaan tanah: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Jenis rupa bumi: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Paras laut: +STR_MAPGEN_SEA_LEVEL :{BLACK}Paras laut: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Sungai: STR_MAPGEN_SMOOTHNESS :{BLACK}Kelicinan: STR_MAPGEN_VARIETY :{BLACK}Pembahagian variasi: STR_MAPGEN_GENERATE :{WHITE}Janakan +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Inggeris (Asal) +STR_MAPGEN_TOWN_NAME_FRENCH :Peranchis +STR_MAPGEN_TOWN_NAME_GERMAN :Jerman +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Inggeris (Tambahan) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Amerika Latin +STR_MAPGEN_TOWN_NAME_SILLY :Mengarut +STR_MAPGEN_TOWN_NAME_SWEDISH :Swedish +STR_MAPGEN_TOWN_NAME_DUTCH :Dutch +STR_MAPGEN_TOWN_NAME_FINNISH :Finnish +STR_MAPGEN_TOWN_NAME_POLISH :Polish +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovak +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norwegian +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungarian +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austrian +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romanian +STR_MAPGEN_TOWN_NAME_CZECH :Czech +STR_MAPGEN_TOWN_NAME_SWISS :Swiss +STR_MAPGEN_TOWN_NAME_DANISH :Danish +STR_MAPGEN_TOWN_NAME_TURKISH :Turkish +STR_MAPGEN_TOWN_NAME_ITALIAN :Italian +STR_MAPGEN_TOWN_NAME_CATALAN :Catalan + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Hujung peta: STR_MAPGEN_NORTHWEST :{BLACK}Barat laut @@ -2721,6 +2710,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Peperi s STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Teruskan ke peperi dahulu yang biasa, melangkau sebarang peperi pseudo/warna kembali/fon dan memusing balik semula STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Perwakilan peperi yang terpilih. Penjajaran tidak diendahkan apabila sedang melukiskan peperi. STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Alihkan "sprite" ke lokasi lain lantas mengubah ofset X dan Y. "Ctrl+Click" untuk ubah lokasi "sprite" lapan unit pada satu-satu masa + +###length 2 + + STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Pilih peperi STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Pilih peperi di mana-mana sahaja dari skrin @@ -2731,7 +2724,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Amaran: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Kesilapan: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Bahaya: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Kesilapan NewGRF yang bahaya telah berlaku:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} tidak akan berfungsi dengan versi TTDPatch seperti yang dilaporkan oleh OpenTTD. STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} adalah untuk TTD versi {STRING}. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} direkabentuk untuk digunakan bersama {STRING} @@ -3188,6 +3180,8 @@ STR_PURCHASE_INFO_ALL_BUT :Semua kecuali { STR_PURCHASE_INFO_MAX_TE :{BLACK}Usaha Penarikan Maks.: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Jarak: {GOLD}{COMMA} petak +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Senarai pilihan keretapi - Klik atas kenderaan untuk maklumat STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Senarai pilihan kenderaan jalanraya - klik atas kenderaan untuk maklumat @@ -3796,12 +3790,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Salah sa STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Tetingkap Kepintaran Tiruan / SkripPermainan Nyahpepijat hanya tersedia bagi pelayan # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Konfigurasi Kepintaran Tiruan / Permainan STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}SkripPermainan yang akan dimuatkan pada permainan seterusnya STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Kepintaran Tiruan yang akan dimuatkan pada permainan seterusnya STR_AI_CONFIG_HUMAN_PLAYER :Pemain manusia STR_AI_CONFIG_RANDOM_AI :Kepintaran Tiruan rawak STR_AI_CONFIG_NONE :(tiada) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Jumlah maksimum pesaing: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Pindah ke Atas STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Pindah Kepintaran Tiruan yang dipilih di dalam senarai ke atas @@ -3811,8 +3805,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Pindah K STR_AI_CONFIG_GAMESCRIPT :{SILVER}SkripPermainan STR_AI_CONFIG_AI :{SILVER}KepintaranTiruan -STR_AI_CONFIG_CHANGE :{BLACK}Pilih {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :Kepintaran Tiruan STR_AI_CONFIG_CHANGE_GAMESCRIPT :SkripPermainan STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Muat skrip yang lain @@ -3835,10 +3827,8 @@ STR_AI_LIST_CANCEL :{BLACK}Batal STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Jangan ubah skrip -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameter +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :SkripPermainan STR_AI_SETTINGS_CLOSE :{BLACK}Tutup STR_AI_SETTINGS_RESET :{BLACK}Semula STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4234,6 +4224,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Tidak bo STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... kenderaan sudah musnah + STR_ERROR_NO_VEHICLES_AVAILABLE_YET_EXPLANATION :{WHITE}Mulakan permainan baru selepas {DATE_SHORT} atau gunakan NewGRF yang digunakan kenderaan terdahulu # Specific vehicle errors @@ -4264,6 +4255,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Senarai STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... terlalu jauh dari destinasi sebelumnya STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... pesawat tidak memiliki jarak mencukupi +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kenderaan tidak boleh dijadualkan... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Kenderaan hanya boleh menunggu di stesen diff --git a/src/lang/maltese.txt b/src/lang/maltese.txt index b35a4a81772d4..38120c61e5fff 100644 --- a/src/lang/maltese.txt +++ b/src/lang/maltese.txt @@ -150,6 +150,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}hp STR_UNITS_POWER_METRIC :{COMMA}hp STR_UNITS_POWER_SI :{COMMA}kW + STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -265,7 +266,7 @@ STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Ibni ind STR_SCENEDIT_FILE_MENU_SEPARATOR : # Settings menu -###length 14 +###length 15 # File menu ###length 5 @@ -405,11 +406,6 @@ STR_NEWS_VEHICLE_IS_LOST :{WHITE}{VEHICLE ###length 42 -###length 2 - - -###length 21 - # Autosave dropdown ###length 5 @@ -430,7 +426,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :oħrajn - # Custom currency window @@ -440,7 +435,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :oħrajn - ###length 5 ###length 6 @@ -451,6 +445,8 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :oħrajn ###length 4 +###length 4 + ###length 7 ###length 4 @@ -470,6 +466,7 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :oħrajn ###length 3 +###setting-zero-is-special STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Stabbilixxi l-kosti għal manutenzjoni u servizzi fuq vetturi u infrastruttura @@ -580,6 +577,8 @@ STR_CONFIG_SETTING_WARN_LOST_VEHICLE :Avza jekk jinti ###length 2 +###length 2 + @@ -746,8 +745,6 @@ STR_INTRO_CAPTION :{WHITE}OpenTTD # Cheat window STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Ibdel is-sena -###length 4 - # Livery window @@ -835,6 +832,8 @@ STR_NETWORK_SERVER_MESSAGE :*** {1:STRING} # Linkgraph legend window and linkgraph legend in smallmap +# Linkgraph tooltip + # Base for station construction window(s) # Join station window @@ -857,7 +856,6 @@ STR_NETWORK_SERVER_MESSAGE :*** {1:STRING} # Signal window # Bridge selection window -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} # Road construction toolbar @@ -933,6 +931,8 @@ STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Aghzel i # World generation STR_MAPGEN_BY :{BLACK}* +###length 21 + # Strings for map borders at game generation @@ -965,6 +965,10 @@ STR_NEWGRF_SETTINGS_INCOMPATIBLE :{RED}Ma jaqblux # Sprite aligner window +###length 2 + + + # NewGRF (self) generated warnings/errors STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING} @@ -1100,6 +1104,8 @@ STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURREN ###length VEHICLE_TYPES +###length 3 + ###length VEHICLE_TYPES ###length VEHICLE_TYPES @@ -1311,14 +1317,13 @@ STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Исчи -STR_AI_CONFIG_CHANGE_NONE : # Available AIs window -# AI Parameters +# Script Parameters # Textfile window @@ -1436,6 +1441,7 @@ STR_ERROR_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Hemm wis + # Specific vehicle errors STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN :{WHITE}Ma tistax tbiddel id-direzzjoni tal-ferrovija... @@ -1452,6 +1458,8 @@ STR_ERROR_CAN_T_MOVE_THIS_ORDER :{WHITE}Ma tista STR_ERROR_CAN_T_SKIP_ORDER :{WHITE}Ma tistax taqbeż din l-ordni... +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors # Sign related errors diff --git a/src/lang/marathi.txt b/src/lang/marathi.txt index 83dd12a1b1602..fd9443d41c66a 100644 --- a/src/lang/marathi.txt +++ b/src/lang/marathi.txt @@ -196,6 +196,7 @@ STR_UNITS_VELOCITY_SI :{COMMA} m/s STR_UNITS_POWER_IMPERIAL :{COMMA}hp STR_UNITS_POWER_METRIC :{COMMA}hp + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}ट STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}ट STR_UNITS_WEIGHT_SHORT_SI :{COMMA} किलो @@ -346,9 +347,8 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :बंद करा # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :खेळाचे पर्याय -STR_SETTINGS_MENU_SCRIPT_SETTINGS :ए.आय. / गेम स्क्रिप्ट सेटिंग्ज STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF पर्याय STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :पारदर्शकता पर्याय STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :शहरांची नावे दाखवा @@ -724,27 +724,6 @@ STR_GAME_OPTIONS_CURRENCY_SEK :स्वीड STR_GAME_OPTIONS_CURRENCY_TRY :तुर्की लिरा (TRY) STR_GAME_OPTIONS_CURRENCY_SKK :स्लोवाक कोरुना (SKK) -###length 2 - - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :फ्रेंच -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :जर्मन -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :स्वीडीश -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :डच -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :फिन्निश -STR_GAME_OPTIONS_TOWN_NAME_POLISH :पोलिश -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :स्लोवाक -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :नोर्वेगीअन -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :हंगेरियन -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :ओस्त्रिअन -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :रोमेनिअन -STR_GAME_OPTIONS_TOWN_NAME_CZECH :झेख -STR_GAME_OPTIONS_TOWN_NAME_SWISS :स्विस -STR_GAME_OPTIONS_TOWN_NAME_DANISH :डेनिष -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :तुर्की -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :ईटेलिअन - # Autosave dropdown ###length 5 @@ -770,7 +749,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :अन्य - # Custom currency window @@ -780,7 +758,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :अन्य - ###length 5 ###length 6 @@ -795,6 +772,8 @@ STR_SUBSIDY_X2 :x२ STR_SUBSIDY_X3 :x३ STR_SUBSIDY_X4 :x४ +###length 4 + ###length 7 ###length 4 @@ -817,6 +796,7 @@ STR_CONFIG_SETTING_REALISTIC :खरेखु ###length 3 +###setting-zero-is-special @@ -911,6 +891,8 @@ STR_CONFIG_SETTING_WARN_LOST_VEHICLE : वाहन ###length 2 +###length 2 + @@ -1076,8 +1058,6 @@ STR_INTRO_CAPTION :{WHITE}ओप # Cheat window STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}चालू वर्ष बदला -###length 4 - # Livery window @@ -1201,6 +1181,8 @@ STR_NETWORK_SERVER_MESSAGE :*** {1:STRING} # Linkgraph legend window and linkgraph legend in smallmap +# Linkgraph tooltip + # Base for station construction window(s) # Join station window @@ -1223,8 +1205,6 @@ STR_NETWORK_SERVER_MESSAGE :*** {1:STRING} # Signal window # Bridge selection window -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_WOODEN :लाकडी @@ -1326,6 +1306,24 @@ STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA} STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_DATE :{BLACK}तिथी: +###length 21 +STR_MAPGEN_TOWN_NAME_FRENCH :फ्रेंच +STR_MAPGEN_TOWN_NAME_GERMAN :जर्मन +STR_MAPGEN_TOWN_NAME_SWEDISH :स्वीडीश +STR_MAPGEN_TOWN_NAME_DUTCH :डच +STR_MAPGEN_TOWN_NAME_FINNISH :फिन्निश +STR_MAPGEN_TOWN_NAME_POLISH :पोलिश +STR_MAPGEN_TOWN_NAME_SLOVAK :स्लोवाक +STR_MAPGEN_TOWN_NAME_NORWEGIAN :नोर्वेगीअन +STR_MAPGEN_TOWN_NAME_HUNGARIAN :हंगेरियन +STR_MAPGEN_TOWN_NAME_AUSTRIAN :ओस्त्रिअन +STR_MAPGEN_TOWN_NAME_ROMANIAN :रोमेनिअन +STR_MAPGEN_TOWN_NAME_CZECH :झेख +STR_MAPGEN_TOWN_NAME_SWISS :स्विस +STR_MAPGEN_TOWN_NAME_DANISH :डेनिष +STR_MAPGEN_TOWN_NAME_TURKISH :तुर्की +STR_MAPGEN_TOWN_NAME_ITALIAN :ईटेलिअन + # Strings for map borders at game generation STR_MAPGEN_BORDER_WATER :{BLACK}पाणी @@ -1357,6 +1355,10 @@ STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT :वस्तू # Sprite aligner window +###length 2 + + + # NewGRF (self) generated warnings/errors STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING} @@ -1535,6 +1537,8 @@ STR_PURCHASE_INFO_COST :{BLACK}कि STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}वजन: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}किंमत: {GOLD}{CURRENCY_LONG}{BLACK} गती: {GOLD}{VELOCITY} +###length 3 + ###length VEHICLE_TYPES ###length VEHICLE_TYPES @@ -1741,14 +1745,13 @@ STR_TIMETABLE_CHANGE_TIME :{BLACK}वे -STR_AI_CONFIG_CHANGE_NONE : # Available AIs window -# AI Parameters +# Script Parameters STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -1863,6 +1866,7 @@ STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}पू + # Specific vehicle errors @@ -1870,6 +1874,8 @@ STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}पू # Order related errors +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors # Sign related errors diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 48507343882f9..fac2222279cf5 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -202,6 +202,8 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hk STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hk STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -393,10 +395,10 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Avslutt # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Spillinnstillinger STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Innstillinger -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI-/Spillskript-innstillinger +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Innstillinger for spill-skript STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF-innstillinger STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Instillinger for gjennomsiktighet STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Vis bynavn @@ -967,36 +969,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indisk rupi (IN STR_GAME_OPTIONS_CURRENCY_IDR :Indonesisk Rupi (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaysisk Ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Venstrekjøring -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Høyrekjøring - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Bynavn: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Velg nasjonalitet på bynavn - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Engelsk (Original) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Fransk -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Tysk -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Engelsk (utvidet) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latinamerikansk -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Tåpelige -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Svensk -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Nederlandsk -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finsk -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polsk -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovakisk -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norsk -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungarsk -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Østeriske -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumensk -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tsjekkisk -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Sveitsisk -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dansk -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Tyrkisk -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiensk -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalansk - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatisk lagring STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Velg intervall for automatisk lagring @@ -1028,21 +1000,10 @@ STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Merk av i denne boksen for å v-synkronisere skjermen. Endring av innstillinger krever omstart av spillet. Fungerer bare med maskinvareakselerasjon aktivert -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Grensesnitt-størrelse -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Velg grensesnitt-størrelsen som skal benyttes -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(finn automatisk) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :2 ganger størrelse -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :4 ganger størrelse -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Skriftstørrelse -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Velg skriftstørrelse for grensesnitt - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(finn automatisk) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dobbel størrelse -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Firedobbel størrelse +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafikk @@ -1094,8 +1055,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Forhån STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 pund (£) i din valuta STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Endre egendefinert valutaparameter -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maks antall motstandere: {ORANGE}{COMMA} - STR_NONE :Ingen STR_FUNDING_ONLY :Kun finansiering STR_MINIMAL :Minimal @@ -1145,6 +1104,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Temperert landskap +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subarktisk landskap +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Subtropisk landskap +STR_CLIMATE_TOYLAND_LANDSCAPE :Leketøylandskap + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Veldig flatt STR_TERRAIN_TYPE_FLAT :Flatt @@ -1223,6 +1188,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Høyre STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maksimalt innledende lån: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Det maksimale beløp et selskap kan låne (uten å ta inflasjon i betraktning) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Lånerente: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Lånerente; kontrollerer også inflasjonen, hvis aktivert @@ -1504,6 +1470,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Forbedret STR_CONFIG_SETTING_ROAD_SIDE :Veikjøretøy: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Velg kjøre-siden +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Venstrekjøring +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Høyrekjøring + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Høydekartrotering: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Mot klokka @@ -2032,7 +2002,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatisk reve STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :La tog reversere ved signaler om de har ventet der lenge ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Anbefalt) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Anbefalt) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Endre verdi @@ -2075,7 +2045,7 @@ STR_INTRO_HIGHSCORE :{BLACK}Tavle me STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Innstillinger STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF-innstillinger STR_INTRO_ONLINE_CONTENT :{BLACK}Se etter innhold på nettet -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI/Spillskript-innstillinger +STR_INTRO_AI_SETTINGS :{BLACK}AI innstillinger STR_INTRO_QUIT :{BLACK}Avslutt STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Start et nytt spill. Ctrl+klikk hopper over kartkonfigurering @@ -2095,7 +2065,7 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Vise tav STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Vis innstillinger STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Vis NewGRF-instillinger STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Se etter nytt og oppdatert innhold for nedlasting -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Vis AI/Spillskript-innstillinger +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Vis KI innstillinger STR_INTRO_TOOLTIP_QUIT :{BLACK}Avslutt 'OpenTTD' STR_INTRO_BASESET :{BLACK}Det valgte innebygde grafikksettet mangler {NUM} sprite{P "" r}. Se etter oppdateringer for settet. @@ -2127,12 +2097,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Endre d STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Endre nåværende år STR_CHEAT_SETUP_PROD :{LTBLUE}Tillat endring av produksjonsmengder: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Temperert landskap -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subarktisk landskap -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Subtropisk landskap -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Leketøylandskap - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Firmafarge @@ -2366,7 +2330,6 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nytt firma) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Opprett et nytt firma og bli med i det STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Dette er deg STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Dette er verten for spillet -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" s} / {NUM} firma{P et er} # Matches ConnectionType ###length 5 @@ -2613,6 +2576,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}mettet STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}overbelastet +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Markering av dekningsområde STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Av @@ -2703,8 +2668,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Øk sign STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Velg jernbanebrotype STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Velg veibrotype STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Brovalg - klikk på broen du vil ha for å bygge den. -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Hengebro, stål STR_BRIDGE_NAME_GIRDER_STEEL :Bjelker, stål STR_BRIDGE_NAME_CANTILEVER_STEEL :Frittbærende, stål @@ -2856,6 +2819,7 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Tilfeldi STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Grunnlegg en by på et tilfeldig sted STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Mange tilfeldige byer STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Dekk kartet med tilfeldig plasserte byer +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Vis alle byer STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Navn på by: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Skriv inn navn på by @@ -3134,6 +3098,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kartstø STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Velg størrelsen på kartet i ruter. Antall tilgjengelige ruter vil være litt mindre STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Antall byer: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Bynavn: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Velg nasjonalitet på bynavn STR_MAPGEN_DATE :{BLACK}Dato: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Antall industrier: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Høyeste fjelltopp: @@ -3147,14 +3113,36 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Ørkende STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Øk ørkendekningen med ti prosent STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Reduser ørkendekning med 10 prosent STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Landskapsgenerator STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terrengtype: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Havnivå: +STR_MAPGEN_SEA_LEVEL :{BLACK}Havnivå: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Elver: STR_MAPGEN_SMOOTHNESS :{BLACK}Jevnhet: STR_MAPGEN_VARIETY :{BLACK}Variasjonsspredning: STR_MAPGEN_GENERATE :{WHITE}Generer +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Engelsk (Original) +STR_MAPGEN_TOWN_NAME_FRENCH :Fransk +STR_MAPGEN_TOWN_NAME_GERMAN :Tysk +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Engelsk (utvidet) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latinamerikansk +STR_MAPGEN_TOWN_NAME_SILLY :Tåpelige +STR_MAPGEN_TOWN_NAME_SWEDISH :Svensk +STR_MAPGEN_TOWN_NAME_DUTCH :Nederlandsk +STR_MAPGEN_TOWN_NAME_FINNISH :Finsk +STR_MAPGEN_TOWN_NAME_POLISH :Polsk +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovakisk +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norsk +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungarsk +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Østeriske +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumensk +STR_MAPGEN_TOWN_NAME_CZECH :Tsjekkisk +STR_MAPGEN_TOWN_NAME_SWISS :Sveitsisk +STR_MAPGEN_TOWN_NAME_DANISH :Dansk +STR_MAPGEN_TOWN_NAME_TURKISH :Tyrkisk +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiensk +STR_MAPGEN_TOWN_NAME_CATALAN :Katalansk + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kartkanter: STR_MAPGEN_NORTHWEST :{BLACK}Nordvest @@ -3299,6 +3287,11 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Forrige STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Fortsett til forrige normale sprite og hopp over enhver pseudo-/omfargings-/skrifttype- sprite, samt start om ved begynnelsen STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Forhåndsvisning av valgt sprite. Innrettingen ignoreres når spriten tegnes STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Flytt på ikonet for å endre X- og Y-forskyvningene. Ctrl+klikk for å flytte ikonet åtte enheter om gangen + +###length 2 + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Trådkors + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Tilbakestill relativt STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Nullstill de nåværende relative forskyvningene STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X forskyvning: {NUM}, Y forskyvning: {NUM} (Absolutt) @@ -3313,8 +3306,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Advarsel: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Feil: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}En fatal NewGRF-feil har oppstått:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}En NewGRF feil har oppstått:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} virker ikke med TTDPatch-versjonen som er rapportert av OpenTTD STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} er for versjon {STRING} av TTD STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} er laget for bruk med {STRING} @@ -3855,6 +3846,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Maks tre STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Rekkevidde: {GOLD}{COMMA} ruter STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Flytype: {GOLD}{STRING} +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Liste over tog/vogner - klikk på tog/vogn for mer informasjon. Ctrl+klikk for å skjule/vise denne typen STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Liste over kjøretøy - klikk på kjøretøy for mer informasjon. Ctrl+klikk for å skjule/vise kjøretøytypen @@ -4515,12 +4508,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Et skrip STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/Spillskript-feilsøkingsvindu er kun tilgjengelig for tjeneren # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI/Spillskript-konfigurasjon STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Spillskriptet som vil bli lastet i neste spill STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AI-ene som vil bli lastet i neste spill STR_AI_CONFIG_HUMAN_PLAYER :Menneskelig spiller STR_AI_CONFIG_RANDOM_AI :Tilfeldig AI STR_AI_CONFIG_NONE :(ingen) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maks antall motstandere: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Flytt opp STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Flytt valgte AI oppover i listen @@ -4530,9 +4523,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Flytt va STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spillskript STR_AI_CONFIG_AI :{SILVER}AI-er -STR_AI_CONFIG_CHANGE :{BLACK}Velg {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_NONE.small :AI STR_AI_CONFIG_CHANGE_AI :AI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Spillskript STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Last enda et skript @@ -4562,10 +4552,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Skjermbi STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Høydekart skjermbilde STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Oversiktskart skjermbilde -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametre +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spillskript STR_AI_SETTINGS_CLOSE :{BLACK}Lukk STR_AI_SETTINGS_RESET :{BLACK}Tilbakestill STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4982,6 +4970,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Kan ikke STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}...{NBSP}kjøretøy er ødelagt + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Ingen kjøretøyer vil være tilgjengelig i det hele tatt STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Endre din NewGRF konfigurasjon STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Ingen kjøretøyer er tilgjengelig ennå @@ -5015,6 +5004,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Kan ikke STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}...{NBSP}for langt i fra forrige destinasjon STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... luftfartøy har ikke stor nok rekkevidde +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kan ikke gi kjøretøyet rutetabell... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Kjøretøy kan bare vente på stasjoner diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index eb2ffbe7240bd..ce0625599f4ae 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -199,6 +199,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA} hk STR_UNITS_POWER_METRIC :{COMMA} hk STR_UNITS_POWER_SI :{COMMA} kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA} t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA} t STR_UNITS_WEIGHT_SHORT_SI :{COMMA} kg @@ -376,10 +377,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Avslutt # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Spelinstillingar STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Innstillinger -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI- / Spelscript-innstillingar STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF-innstillingar STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Gjennomsiktigheitsinnstillingar STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Syne bynamn @@ -926,36 +926,6 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :Eigendefinert.. STR_GAME_OPTIONS_CURRENCY_GEL :Georgiske Lari (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Iranske Rial (IRR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Venstrekøyring -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Høgrekøyring - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Namn på byar -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Vel nasjonalitet på bynamn - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Engelsk -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Fransk -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Tysk -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Engelsk (utvidet) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latinamerikansk -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Tåpelige -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Svensk -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Nederlandsk -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finsk -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polsk -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovakisk -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norsk -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungarsk -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Østerriksk -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumensk -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tsjekkisk -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Sveitsisk -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dansk -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Tyrkisk -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiensk -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalansk - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatisk lagring STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Vel intervall for automatisk lagring @@ -980,12 +950,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :anna -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Grensesnittstorleik -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Vel storleik å bruke på grensesnittet - -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dobbel størrelse -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Firedobbel størrelse @@ -1034,8 +998,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Eksempe STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 pund (£) i din valuta STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Byt eigendefinert valutaparameter -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maks. antal konkurrentar: {ORANGE}{COMMA} - STR_NONE :Ingen STR_FUNDING_ONLY :Kun finansiering STR_MINIMAL :Minimal @@ -1085,6 +1047,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Temperert landskap +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :subarktisk landskap +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :subtropisk landskap +STR_CLIMATE_TOYLAND_LANDSCAPE :"Leikeland"-landskap + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Særs flatt STR_TERRAIN_TYPE_FLAT :Flatt @@ -1158,6 +1126,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Høgre STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maksimalt startlån: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maksimalt lån eit firma kan ta opp (utan å reikne med inflasjon) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Rente: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Lånerente; kontrollerar óg mogleg inflasjon @@ -1392,6 +1361,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Forbetra STR_CONFIG_SETTING_ROAD_SIDE :Veg-køyrety: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Vel køyreside +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Venstrekøyring +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Høgrekøyring + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Høgdekartrotering: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Mot klokka @@ -1816,7 +1789,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatisk reve STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :La tog snu ved signal, når dei har venta lengje ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Anbefalt) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Anbefalt) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Byt innstillingsverdi @@ -1857,7 +1830,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Poengtav STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Innstillinger STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF-innstillingar STR_INTRO_ONLINE_CONTENT :{BLACK}Sjå etter innhald på nett -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI- / Spelscriptinnstillingar STR_INTRO_QUIT :{BLACK}Avslutt STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Start eit nytt spel. CTRL+klikk hoppar over kartkonfigurasjon @@ -1877,7 +1849,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Syn poen STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Skjerminnstillingar STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Syne NewGRF-instillingar STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Sjå etter nytt og oppdatert innhald som kan lastas ned -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Vis AI- og spelscriptinnstillingar STR_INTRO_TOOLTIP_QUIT :{BLACK}Avslutt 'OpenTTD' STR_INTRO_TRANSLATION :{BLACK}Denne nynorsk-omsettinga manglar {NUM} tekst{P "" ar}. Du må gjerne verte med i omsettingsgruppa for å hjelpe til å gjere OpenTTD betre. Sjå readme.txt for detaljar. @@ -1906,12 +1877,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Byt dat STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Byt noverande år STR_CHEAT_SETUP_PROD :{LTBLUE}Tillet endring av produksjonsmengder: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Temperert landskap -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :subarktisk landskap -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :subtropisk landskap -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :"Leikeland"-landskap - # Livery window STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Syne generelle fargetema @@ -2309,6 +2274,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}fullt utnytta STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}overbelasta +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Syne dekningsområde STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Av @@ -2397,8 +2364,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Auk tett STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Vel jernbanebrutype STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Vel type bru STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Bruval - klikk på brua du vil ha for å byggje ho -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Hengjebru, stål STR_BRIDGE_NAME_GIRDER_STEEL :Bjelkar, stål STR_BRIDGE_NAME_CANTILEVER_STEEL :Frittberande, stål @@ -2751,16 +2716,40 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kartstor STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Vel storleik på kartet, i ruter. Talet på tilgjengelege ruter vert smått mindre STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Antal byar: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Namn på byar +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Vel nasjonalitet på bynamn STR_MAPGEN_DATE :{BLACK}Dato: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Antal industriar: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Landskapsgenerator: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terrengtype -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Havflate: +STR_MAPGEN_SEA_LEVEL :{BLACK}Havflate: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Elver: STR_MAPGEN_SMOOTHNESS :{BLACK}Glattleik: STR_MAPGEN_VARIETY :{BLACK}Variasjonsdistrubusjon: STR_MAPGEN_GENERATE :{WHITE}Generer +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Engelsk +STR_MAPGEN_TOWN_NAME_FRENCH :Fransk +STR_MAPGEN_TOWN_NAME_GERMAN :Tysk +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Engelsk (utvidet) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latinamerikansk +STR_MAPGEN_TOWN_NAME_SILLY :Tåpelige +STR_MAPGEN_TOWN_NAME_SWEDISH :Svensk +STR_MAPGEN_TOWN_NAME_DUTCH :Nederlandsk +STR_MAPGEN_TOWN_NAME_FINNISH :Finsk +STR_MAPGEN_TOWN_NAME_POLISH :Polsk +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovakisk +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norsk +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungarsk +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Østerriksk +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumensk +STR_MAPGEN_TOWN_NAME_CZECH :Tsjekkisk +STR_MAPGEN_TOWN_NAME_SWISS :Sveitsisk +STR_MAPGEN_TOWN_NAME_DANISH :Dansk +STR_MAPGEN_TOWN_NAME_TURKISH :Tyrkisk +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiensk +STR_MAPGEN_TOWN_NAME_CATALAN :Katalansk + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kartkantar STR_MAPGEN_NORTHWEST :{BLACK}Nordvest @@ -2896,6 +2885,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Førre s STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Fortsett til neste normale sprite og hopp over einhver pseudo-/omfargings-/skrifttype- sprite, samt start om ved byrjinga STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Førehandsvisning av valgt sprite. Innrettinga ignorerast når spriten tegnes STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Flytt spriten rundt omkring, for å endre X- og Y-forskyvningene + +###length 2 + + STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Vel sprite STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Vel ein sprite frå eit vilkårleg sted på skjermen @@ -2906,7 +2899,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Åtvaring: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Feil: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Ein fatal NewGRF-feil har oppstått:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} vil ikkje verke med den TTDPatch versjonen som OpenTTD oppgjer STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} er for {STRING} utgåva av TTD. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} er laga for å brukast saman med {STRING} @@ -3400,6 +3392,8 @@ STR_PURCHASE_INFO_ALL_BUT :Alt utanom {CAR STR_PURCHASE_INFO_MAX_TE :{BLACK}Maks. trekkraft: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Rekkevidde: {GOLD}{COMMA} ruter +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Tog-/vognliste - klikk på tog/vogn for meir informasjon STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Køyretøyliste - klikk på køyretøy for meir informasjon @@ -4019,12 +4013,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Ein AI h STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI- / Spelscript-feilsøkingvindauget er kun tilgjengeleg for tenaren # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI- / Spelkonfigurasjonar STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Spelscriptet som blir lasta i neste spel STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AIane som blir lasta i neste spel STR_AI_CONFIG_HUMAN_PLAYER :Menneskeleg spelar STR_AI_CONFIG_RANDOM_AI :Tilfeldig AI STR_AI_CONFIG_NONE :(ingen) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maks. antal konkurrentar: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Flytt oppover STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Flytt valt AI oppover lista @@ -4034,8 +4028,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Flytt va STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spelscript STR_AI_CONFIG_AI :{SILVER}AIar -STR_AI_CONFIG_CHANGE :{BLACK}Vel {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :AI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Spelscript STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Last eit anna script @@ -4058,10 +4050,8 @@ STR_AI_LIST_CANCEL :{BLACK}Avbryt STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ikkje endre AI -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameter +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spelscript STR_AI_SETTINGS_CLOSE :{BLACK}Lukk STR_AI_SETTINGS_RESET :{BLACK}Tilbakestill STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4467,6 +4457,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Kan ikkj STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... køyretøy er øydelagd + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Ingen køyretøy vert tilgjengelege STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Byt NewGRF-innstillingar STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Det finst ikkje nokon køyretøy enno @@ -4500,6 +4491,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Kan ikkj STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... for langt borte frå førre destinasjon STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... luftfartyg har ikkje nok rekkevidde +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kan ikkje lage rutetabell for køyretøyet... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Køyretøy kan kun venta på stasjonar diff --git a/src/lang/persian.txt b/src/lang/persian.txt index 21e77d5f13e45..a91360515de82 100644 --- a/src/lang/persian.txt +++ b/src/lang/persian.txt @@ -197,6 +197,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}ا STR_UNITS_POWER_METRIC :{COMMA}{NBSP}اسب بخار STR_UNITS_POWER_SI :{COMMA}{NBSP}کیلووات + STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}تن STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}کیلوگرم @@ -366,9 +367,8 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :خروج # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :تنظیمات بازی -STR_SETTINGS_MENU_SCRIPT_SETTINGS :هوش مصنوعی / تنظیمات بازی STR_SETTINGS_MENU_NEWGRF_SETTINGS :تنظیمات NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :گزینه های شفافیت STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :نام شهرها نشان داده شود @@ -916,36 +916,6 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :دلخواه... STR_GAME_OPTIONS_CURRENCY_GEL :لیره گرجستان (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :ریال ایران (IRR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}انتخاب نوع نام شهرها - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :انگلیسی (اصلی) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :فرانسوی -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :آلمانی -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :انگلیسی (اضافه) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :آمریکای لاتین -STR_GAME_OPTIONS_TOWN_NAME_SILLY :سیلی -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :سوئدی -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :هلندی -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :فنلاند -STR_GAME_OPTIONS_TOWN_NAME_POLISH :لهستان -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :اسلواکی -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :نروژی -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :مجاری -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :اتریشی -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :رومانیایی -STR_GAME_OPTIONS_TOWN_NAME_CZECH :چکی -STR_GAME_OPTIONS_TOWN_NAME_SWISS :سوییسی -STR_GAME_OPTIONS_TOWN_NAME_DANISH :دانمارکی -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :ترکیه ای -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :ایتالیایی -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :کاتالانی - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK} ذخیره اتوماتیک STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK} انتخاب فاصله زمانی بین ذخیره کردن های اتوماتیک @@ -971,8 +941,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :دیگر -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :دو برابر - @@ -1020,8 +988,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}پیش STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}۱۰۰۰۰ پوند (£) به واحد پول شما می شود STR_CURRENCY_CHANGE_PARAMETER :{BLACK}تغییر دلخواه پارامترهای واحد پول -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}حد اکثر تعداد رقبا :{ORANGE}{COMMA} - STR_NONE :هیچکدام STR_FUNDING_ONLY :فقط سرمایه گذاری STR_MINIMAL :کمینه @@ -1071,6 +1037,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :آب و هوای معتدل +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :آب و هوای قطبی +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :آب و هوای استوایی +STR_CLIMATE_TOYLAND_LANDSCAPE :دنیای اسباب بازی ها + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :بسیار یکدست STR_TERRAIN_TYPE_FLAT :یکدست @@ -1133,6 +1105,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_CENTER :مرکز STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :راست STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :حداکثر اعتبار اولیه: {STRING} +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :نرخ سود: {STRING} @@ -1316,6 +1289,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :بهبودیا STR_CONFIG_SETTING_ROAD_SIDE :خودروهای جاده ای: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :انتخاب جهت رانندگی +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :چپ فرمان +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :راست فرمان + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :جهت چرخش نقشه بلندی: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :پادساعت‌گرد @@ -1628,7 +1605,7 @@ STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS :مسیریاب STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :برگشت خودکار با رسیدن به نشانه ها: {STRING} ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(توصیه می گردد) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(توصیه می گردد) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}تغییر مقدار @@ -1662,7 +1639,6 @@ STR_INTRO_MULTIPLAYER :{BLACK}بازی STR_INTRO_GAME_OPTIONS :{BLACK}تنضیمات بازی STR_INTRO_NEWGRF_SETTINGS :{BLACK}تنظیمات NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}چک کردن محتوی آنلاین -STR_INTRO_SCRIPT_SETTINGS :{BLACK} تنظیمات هوش مصنوعی / اسکریپت STR_INTRO_QUIT :{BLACK}خروج STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}شروع بازی جدید. Ctrl+Click پیش تنظیمات نقشه را رد و از تنظیمات گذشته استفاده می کند. @@ -1681,7 +1657,6 @@ STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}نشان STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}نمایش جدول بالاترین امتیازات STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}نمایش تنظیمات NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}بررسی وجود مجموعه ها و به روز رسانی های جدید در اینترنت -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}نمایش تنظیمات هوش مصنوعی و اسکریپت های بازی STR_INTRO_TOOLTIP_QUIT :{BLACK} خروج از 'OpenTTD' STR_INTRO_TRANSLATION :{BLACK}این ترجمه {NUM} رشته{P ی های}ترجمه نشده دارد. با ثبت نام کردن به عنوان مترجم ما را در بهتر سازی OpenTTD یاری نمایید. فایل readme.txt را برای جزییات بیشتر بخوانید. @@ -1709,12 +1684,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}تغی STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}تغییر سال جاری STR_CHEAT_SETUP_PROD :{LTBLUE}قابلیت تغییر سطح تولید صنایع: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :آب و هوای معتدل -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :آب و هوای قطبی -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :آب و هوای استوایی -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :دنیای اسباب بازی ها - # Livery window STR_LIVERY_GENERAL_TOOLTIP :{BLACK}نمایش طرح رنگهای اصلی @@ -2107,6 +2076,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}اشباع شده STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}بیش از ظرفیت +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}نور ناحیه ی اطراف ایستگاه STR_STATION_BUILD_COVERAGE_OFF :{BLACK}خاموش @@ -2195,8 +2166,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}زیاد STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}انتخب پل راه آهن STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}ساخت پل ماشین رو STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK} ساخت پل - بر روی پل مورد نظر خود کلیک کنید تا ساخته شود -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :معلق، فولادی STR_BRIDGE_NAME_GIRDER_STEEL :پیوسته، فولادی STR_BRIDGE_NAME_CANTILEVER_STEEL :پایه دار، فولادی @@ -2546,16 +2515,40 @@ STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}ساخت STR_MAPGEN_MAPSIZE :{BLACK}اندازه نقشه: STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}تعداد شهرها: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK} نام شهرها +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}انتخاب نوع نام شهرها STR_MAPGEN_DATE :{BLACK}تاریخ: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}تعداد صنایع: -STR_MAPGEN_LAND_GENERATOR :{BLACK}سازنده زمین: STR_MAPGEN_TERRAIN_TYPE :{BLACK}نوع پستی/بلندی: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}سطح دریا: +STR_MAPGEN_SEA_LEVEL :{BLACK}سطح دریا: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}رودخانه ها: STR_MAPGEN_SMOOTHNESS :{BLACK}همواری: STR_MAPGEN_VARIETY :{BLACK}توزیع انواع: STR_MAPGEN_GENERATE :{WHITE}بساز +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :انگلیسی (اصلی) +STR_MAPGEN_TOWN_NAME_FRENCH :فرانسوی +STR_MAPGEN_TOWN_NAME_GERMAN :آلمانی +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :انگلیسی (اضافه) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :آمریکای لاتین +STR_MAPGEN_TOWN_NAME_SILLY :سیلی +STR_MAPGEN_TOWN_NAME_SWEDISH :سوئدی +STR_MAPGEN_TOWN_NAME_DUTCH :هلندی +STR_MAPGEN_TOWN_NAME_FINNISH :فنلاند +STR_MAPGEN_TOWN_NAME_POLISH :لهستان +STR_MAPGEN_TOWN_NAME_SLOVAK :اسلواکی +STR_MAPGEN_TOWN_NAME_NORWEGIAN :نروژی +STR_MAPGEN_TOWN_NAME_HUNGARIAN :مجاری +STR_MAPGEN_TOWN_NAME_AUSTRIAN :اتریشی +STR_MAPGEN_TOWN_NAME_ROMANIAN :رومانیایی +STR_MAPGEN_TOWN_NAME_CZECH :چکی +STR_MAPGEN_TOWN_NAME_SWISS :سوییسی +STR_MAPGEN_TOWN_NAME_DANISH :دانمارکی +STR_MAPGEN_TOWN_NAME_TURKISH :ترکیه ای +STR_MAPGEN_TOWN_NAME_ITALIAN :ایتالیایی +STR_MAPGEN_TOWN_NAME_CATALAN :کاتالانی + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}لبه های نقشه: STR_MAPGEN_NORTHWEST :{BLACK}شمال غربی @@ -2691,6 +2684,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}تصوی STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}نمایش تصویر عادی قبلی، بدون انجام دادن هر گونه تغییرات STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}نمایش تصویر انتخاب شده. تغییر مکان تصویر در زمان بارگزاری اعمال نمی شود STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}تغییر مکان تصویر، تغییر مقدار اضافه شونده به X و Y + +###length 2 + + STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}برداشتن تصویر STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}برداشتن یک تصویر از یک نقطه از صفحه نمایش @@ -2701,7 +2698,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}هشدار: {SILVER}{STRING} 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_VERSION_NUMBER :{1:STRING} با TTDPatch که ویرایش آن توسط OpenTTD گزارش شده کار نمی کند STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} برای ویرایش {STRING}TTD می باشد STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} طراحی شده برای استفاده با {STRING} @@ -3088,6 +3084,8 @@ STR_PURCHASE_INFO_SPEED_CANAL :{BLACK}سرعت STR_PURCHASE_INFO_REFITTABLE :(قابل تعمیر) STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}برد: {GOLD}{COMMA} قطعه +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}لیست انتخاب قطار - برای اطلاعات بیشتر روی وسیله کلیک کنید. برای مخفی یا پدیدار کردن انواع قطار کنترل+کلیک کنید STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}لیست انتخاب کشتی - برای اطلاعات بیشتر روی کشتی کلیک کنید. برای مخفی یا دوباره پدیدار کردن نوع کشتی ها، کنترل+کلیک کنید @@ -3441,12 +3439,12 @@ STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}دیدن STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}پنجره رفع اشکال کد فقط برای سرور قابل دسترس است # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}تنظیمات هوش مصنوعی / بازی STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}کد بازی که در بازی بعدی بارگذاری می شود STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}هوش مصنوعی که در بازی بعدی بارگذاری می شود STR_AI_CONFIG_HUMAN_PLAYER :بازیکن آدمیزاد STR_AI_CONFIG_RANDOM_AI :انتخاب هوش مصنوعی به صورت اتفاقی STR_AI_CONFIG_NONE :(هیچکدام) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}حد اکثر تعداد رقبا :{ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :حرکت به بالا STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}حرکت دادن AI انتخاب شده به سمت بالا در لیست @@ -3456,8 +3454,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}حرکت STR_AI_CONFIG_GAMESCRIPT :{SILVER}کدبازی STR_AI_CONFIG_AI :{SILVER}هوشهای مصنوعی -STR_AI_CONFIG_CHANGE :{BLACK}انتخاب {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :هوش مصنوعی(AI) STR_AI_CONFIG_CHANGE_GAMESCRIPT :کد بازی STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}بارگزاری کد دیگر @@ -3479,10 +3475,8 @@ STR_AI_LIST_CANCEL :{BLACK}لغو STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}کد را تغییر نده -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} پارامترها +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :هوش مصنوعی(AI) -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :کد بازی STR_AI_SETTINGS_CLOSE :{BLACK}بستن STR_AI_SETTINGS_RESET :{BLACK}بازنشاندن STR_AI_SETTINGS_START_DELAY :تعداد روزهایی که این بازیگر هوش مصنوعی پس از بازیگر هوش مصنوعی قبلی قبل از اتصال صبر می کند(کم و بیش): {ORANGE}{STRING} @@ -3764,6 +3758,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}امکا STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... وسیله نقلیه منهدم شد + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}بطور کلی هیچ خودرویی در دسترس نخواهد بود STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}تنظیمات مربوط به NewGRF را تغییر دهید STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}هنوز خودرویی در دسترس نیست @@ -3796,6 +3791,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}نمی STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}از هدف قبلی بسیار دور است... STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... هواپیما برد کافی ندارد +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}نمی شود مدیریت زمانی وسیله را تغییر داد... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}وسایل نقلیه فقط در ایستگاه می توانند منتظر بمانند diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 749db86d5b739..9c4ba2f8e7134 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -575,10 +575,20 @@ STR_UNITS_VELOCITY_METRIC :{COMMA}{NBSP}km STR_UNITS_VELOCITY_SI :{COMMA}{NBSP}m/s STR_UNITS_VELOCITY_GAMEUNITS :{DECIMAL}{NBSP}p{P ole ola ól}/dzień -STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}KM +STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}KM STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}KM/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}KM/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}KM/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -605,8 +615,8 @@ STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Filtr: -STR_LIST_FILTER_OSKTITLE :{BLACK}Wpisz słowo filtru -STR_LIST_FILTER_TOOLTIP :{BLACK}Wpisz słowo, wg którego filtrować listę +STR_LIST_FILTER_OSKTITLE :{BLACK}Wpisz jedno lub więcej słów kluczowych, aby przefiltrować listę +STR_LIST_FILTER_TOOLTIP :{BLACK}Wpisz jedno lub więcej słów kluczowych, aby przefiltrować listę STR_TOOLTIP_GROUP_ORDER :{BLACK}Wybierz kolejność grupowania STR_TOOLTIP_SORT_ORDER :{BLACK}Wybierz kolejność sortowania (malejąco/rosnąco) @@ -755,9 +765,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Tworzeni STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Tworzenie przedsiębiorstw STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Konstrukcja dróg STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Konstrukcja torów tramwajowych -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Posadź drzewa. Shift przełącza pomiędzy trybem sadzenia a szacowaniem jego kosztów +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Posadź drzewa. Ctrl zaznacza teren po przekątnej. Shift przełącza pomiędzy trybem sadzenia a szacowaniem jego kosztów STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Umieść napis -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Umieść obiekt. Shift przełącza pomiędzy trybem budowania a szacowaniem jego kosztów +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Umieść obiekt. Ctrl zaznacza obszar po przekątnej. Shift przełącza pomiędzy trybem budowania a szacowaniem jego kosztów # Scenario editor file menu ###length 7 @@ -770,10 +780,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Wyjście # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Opcje gry STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Ustawienia -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Ustawienia SI / Game Script +STR_SETTINGS_MENU_AI_SETTINGS :Ustawienia SI +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Ustawienia Game Script STR_SETTINGS_MENU_NEWGRF_SETTINGS :Ustawienia NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opcje przeźroczystości STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Wyświetlanie nazw miast @@ -1345,36 +1356,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rupia Indyjska STR_GAME_OPTIONS_CURRENCY_IDR :Rupia Indonezyjska (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit malezyjski (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Jazda po lewej -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Jazda po prawej - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nazwy miast: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Wybierz styl nazw miast - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Angielskie (Oryginalne) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francuskie -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Niemieckie -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Angielskie (Rozszerzone) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Południowoamerykańskie -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Śmieszne (Angielskie) -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Szwedzkie -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holenderskie -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Fińskie -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polskie -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Słowackie -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norweskie -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Węgierskie -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austriackie -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumuńskie -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Czeskie -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Szwajcarskie -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Duńskie -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Tureckie -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Włoskie -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalońskie - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Autozapis STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Częstotliwość automatycznego zapisu stanu gry @@ -1391,7 +1372,7 @@ STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Wybierz STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} (ukończono {NUM}%) STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Pełny ekran -STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Zaznacz, jeśli chcesz grać w OpenTTD w trybie pełnoekranowym +STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Zaznacz to pole, jeśli chcesz grać w OpenTTD w trybie pełnoekranowym STR_GAME_OPTIONS_RESOLUTION :{BLACK}Rozdzielczość ekranu STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}Wybierz rozdzielczość ekranu @@ -1407,21 +1388,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Zaznacz STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Bieżący sterownik: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Rozmiar interfejsu -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Wybierz rozmiar elementów interfejsu +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Rozmiar interfejsu +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Przeciągnij suwak, aby ustawić rozmiar interfejsu. Przytrzymaj Ctrl, aby uzyskać płynną regulację +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Wykryj rozmiar automatycznie +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Zaznacz to pole, aby rozmiar interfejsu był wykrywany automatycznie -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(wykryj automatycznie) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normalny -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Podwójny -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Poczwórny +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Skaluj fazy krawędzi +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Zaznacz to pole, aby skalować fazy krawędzi zgodnie z rozmiarem interfejsu -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Wielkość czcionki -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Wybierz wielkość czcionki interfejsu - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(wykryj automatycznie) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normalna -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Podwójna -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Poczwórna +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafika @@ -1473,8 +1452,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Podglą STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 funtów (£) w twojej walucie STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Zmień parametr własnej waluty -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksymalna liczba przeciwników: {ORANGE}{COMMA} - STR_NONE :Brak STR_FUNDING_ONLY :Tylko sponsorowanie STR_MINIMAL :Minimum @@ -1524,6 +1501,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Klimat umiarkowany +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Klimat arktyczny +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Klimat tropikalny +STR_CLIMATE_TOYLAND_LANDSCAPE :Krajobraz zabawkowy + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Bardzo płaski STR_TERRAIN_TYPE_FLAT :Płaski @@ -1543,7 +1526,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}Brak pas # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Ustawienia -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrowanie po frazie: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtr: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Otwórz wszystko STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Zamknij wszystko STR_CONFIG_SETTING_RESET_ALL :{BLACK}Zresetuj wszystkie ustawienia @@ -1603,6 +1586,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :z prawej strony STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maksymalna wysokość początkowej pożyczki: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maksymalna wysokość pożyczki, jaką firma może zaciągnąć (bez uwzględnienia inflacji) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Brak pożyczki {RED}Wymagany Game Script, aby zapewnić początkowe fundusze STR_CONFIG_SETTING_INTEREST_RATE :Oprocentowanie: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Oprocentowanie pożyczki; kontroluje też inflację, jeśli jest włączona @@ -1829,6 +1815,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Grubość linii STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Pokaż nazwę NewGRF-a w oknie budowy pojazdu: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Dodaj wiersz do okna budowy pojazdów, pokazujący z którego NewGRF-a wybrany pojazd pochodzi. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Pokaż w oknach list jakie ładunki mogą być przewożone przez pojazdy: {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Jeśli włączone, ładunek możliwy do przewiezienia przez pojazd będzie wyświetlany nad nim na listach pojazdów. STR_CONFIG_SETTING_LANDSCAPE :Krajobraz: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Krajobrazy określają podstawowe scenariusze gry, które różnią się przedsiębiorstwami, ładunkiem i wymogami dla rozwoju miast. Pliki NewGRF i skrypty umożliwiają dokładniejszą kontrolę warunków rozgrywki @@ -1883,6 +1871,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Ulepszony STR_CONFIG_SETTING_ROAD_SIDE :Pojazdy drogowe: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Wybierz stronę, po której będą jeździć samochody +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Jazda po lewej +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Jazda po prawej + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Obrót mapy wysokości: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Przeciwnie do wsk. zegara @@ -2092,7 +2084,7 @@ STR_CONFIG_SETTING_AI_PROFILE_HARD :Trudny STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Pozwól na SI w grze wieloosobowej: {STRING} STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Pozwól komputerowym graczom SI na udział w grach dla wielu graczy -STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :ilość #opcodes przed uśpieniem skryptu: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :Liczba wysyłanych kodów instrukcji przed zawieszeniem skryptów: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Maksymalna liczba kroków obliczeniowych, jakie skrypt może zrobić w jednej kolejce STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Maksymalne zużycie pamięci na skrypt: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Ilość pamięci jaką może zużywać pojedynczy skrypt zanim zostanie przymusowo zakończony. Może wymagać zwiększenia dla większych map. @@ -2303,7 +2295,7 @@ STR_CONFIG_SETTING_TOWN_GROWTH_FAST :duża STR_CONFIG_SETTING_TOWN_GROWTH_VERY_FAST :bardzo duża STR_CONFIG_SETTING_LARGER_TOWNS :Proporcje miast, które będą metropoliami: {STRING} -STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :Liczba miast, które staną się metropoliami - czyli miastami, które na początku są większe i szybciej się rozwijają +STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :Liczba miast, które staną się metropoliami - czyli miastami, które od początku są większe i szybciej się rozwijają STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 z {COMMA} ###setting-zero-is-special STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Żadne @@ -2316,13 +2308,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Przeznacz {STRI STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Czas potrzebny na każde przeliczenie komponentu grafu połączeń. Po rozpoczęciu przeliczania tworzony jest wątek, który może działać przez podaną liczbę dni. Im mniejszą wartość ustawisz, tym większe prawdopodobieństwo, że wątek nie zostanie ukończony w wyznaczonym czasie. Wtedy gra zatrzymuje się do czasu jego zakończenia („lag”). Im większą wartość ustawisz, tym dłużej będzie trwała aktualizacja dystrybucji, gdy zmienią się trasy. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Tryb dystrybucji dla pasażerów: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Tryb „symetryczny” oznacza, że mniej więcej tyle samo pasażerów będzie podróżować ze stacji A do stacji B, co z B do A. Tryb „asymetryczny” oznacza, że w obu kierunkach może podróżować dowolna liczba pasażerów. Tryb „ręczny” oznacza, że dla pasażerów nie będzie przeprowadzana dystrybucja automatyczna. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Tryb „symetryczny” oznacza, że mniej więcej tyle samo pasażerów będzie podróżować ze stacji A do stacji B, co z B do A. Tryb „asymetryczny” oznacza, że w obu kierunkach może podróżować różna liczba pasażerów. Tryb „ręczny” oznacza, że dla pasażerów nie będzie przeprowadzana dystrybucja automatyczna. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Tryb dystrybucji dla poczty: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :Tryb „symetryczny” oznacza, że mniej więcej taka sama ilość poczty zostanie wysłana ze stacji A do stacji B, co z B do A. Tryb „asymetryczny” oznacza, że w obu kierunkach może być wysłana dowolna ilość poczty. Tryb „ręczny” oznacza, że dla poczty nie będzie przeprowadzana dystrybucja automatyczna. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :Tryb „symetryczny” oznacza, że mniej więcej taka sama ilość poczty zostanie wysłana ze stacji A do stacji B, co z B do A. Tryb „asymetryczny” oznacza, że w obu kierunkach może być wysyłana różna ilość poczty. Tryb „ręczny” oznacza, że dla poczty nie będzie przeprowadzana dystrybucja automatyczna. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Tryb dystrybucji dla klasy ładunków CHRONIONYCH: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Klasa ładunków CHRONIONYCH zawiera kosztowności w klimacie umiarkowanym, diamenty w tropikalnym lub złoto w klimacie arktycznym. NewGRF-y mogą to zmienić. Tryb „symetryczny” oznacza, że mniej więcej taka sama ilość danego ładunku zostanie wysłana ze stacji A do stacji B, co z B do A. Tryb „asymetryczny” oznacza, że dowolne ilości danego ładunku mogą być wysyłane w obu kierunkach. Tryb „ręczny” oznacza, że dla danego ładunku nie będzie przeprowadzana dystrybucja automatyczna. Zaleca się ustawienie tej opcji na asymetryczną lub ręczną, grając w klimacie tropikalnym, ponieważ banki nie będą odsyłać złota do kopalni złota. Dla klimatu umiarkowanego i arktycznego możesz wybrać symetryczny, ponieważ banki będą odsyłać kosztowności z powrotem do banku, z którego pochodzi pierwotny ładunek. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Klasa ładunków CHRONIONYCH zawiera kosztowności w klimacie umiarkowanym, diamenty w tropikalnym lub złoto w klimacie arktycznym. NewGRF-y mogą to zmienić. Tryb „symetryczny” oznacza, że mniej więcej taka sama ilość danego ładunku zostanie wysłana ze stacji A do stacji B, co z B do A. Tryb „asymetryczny” oznacza, że w obu kierunkach mogą być wysyłane różne ilości danego ładunku. Tryb „ręczny” oznacza, że dla danego ładunku nie będzie przeprowadzana dystrybucja automatyczna. Zaleca się ustawienie tej opcji na asymetryczną lub ręczną w klimacie arktycznym lub tropikalnym, ponieważ tam banki jedynie odbierają ładunek. Dla klimatu umiarkowanego możesz wybrać symetryczny, aby banki odsyłały kosztowności do pierwotnego banku. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Tryb dystrybucji dla pozostałych klas ładunków: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :Tryb „asymetryczny” oznacza, że dowolne ilości ładunków mogą być wysyłane w obu kierunkach. Tryb „ręczny” oznacza, że dla takich ładunków nie będzie przeprowadzana dystrybucja automatyczna. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :Tryb „asymetryczny” oznacza, że w obu kierunkach mogą być wysyłane różne ilości ładunków. Tryb „ręczny” oznacza, że dla takich ładunków nie będzie przeprowadzana dystrybucja automatyczna. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :ręczny STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asymetryczny @@ -2351,7 +2343,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER :Jednostka mocy STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_HELPTEXT :Kiedy moc pojazdu jest pokazywana w interfejsie użytkownika, wyświetl ją w wybranych jednostkach ###length 3 STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_IMPERIAL :Imperialne (hp) -STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_METRIC :Metryczne (hp) +STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_METRIC :Metryczne (KM) STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_SI :SI (kW) STR_CONFIG_SETTING_LOCALISATION_UNITS_WEIGHT :Jednostki wagi: {STRING} @@ -2417,7 +2409,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatycznie z STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Pozwól pociągom zawracać przed semaforem, jeśli czekają tam bardzo długo ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Zalecane) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Zalecane) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Zmiana wartości @@ -2460,31 +2452,33 @@ STR_INTRO_HIGHSCORE :{BLACK}Tabela w STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Ustawienia STR_INTRO_NEWGRF_SETTINGS :{BLACK}Ustawienia NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Sprawdź dodatki online -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Ustawienia SI/Game Script +STR_INTRO_AI_SETTINGS :{BLACK}Ustawienia SI +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Ustawienia Game Script STR_INTRO_QUIT :{BLACK}Wyjście STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Rozpocznij nową grę. Ctrl+klik pomija konfigurowanie mapy STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}Wczytaj zapisaną grę -STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}Rozpocznij nowa grę używając mapy wysokości jako krajobrazu -STR_INTRO_TOOLTIP_PLAY_SCENARIO :{BLACK}Rozpocznij grę używając własnego scenariusza +STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}Rozpocznij nowa grę, używając mapy wysokości jako krajobrazu +STR_INTRO_TOOLTIP_PLAY_SCENARIO :{BLACK}Rozpocznij nową grę, używając przygotowanego scenariusza STR_INTRO_TOOLTIP_SCENARIO_EDITOR :{BLACK}Stwórz własny świat/scenariusz STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}Rozpocznij grę wieloosobową -STR_INTRO_TOOLTIP_TEMPERATE :{BLACK}Wybierz krajobraz 'umiarkowany' -STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}Wybierz krajobraz 'arktyczny' -STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}Wybierz krajobraz 'tropikalny' -STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Wybierz krajobraz 'zabawkowy' +STR_INTRO_TOOLTIP_TEMPERATE :{BLACK}Wybierz krajobraz „umiarkowany” +STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}Wybierz krajobraz „arktyczny” +STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}Wybierz krajobraz „tropikalny” +STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Wybierz krajobraz „zabawkowy” STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Wyświetl opcje gry STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Wyświetl tabelę wyników STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Wyświetl ustawienia gry STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Wyświetl ustawienia NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Poszukaj nowych lub zaktualizowanych dodatków do pobrania -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Pokaż ustawienia SI / Game Script -STR_INTRO_TOOLTIP_QUIT :{BLACK}Wyjdź z 'OpenTTD' +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Wyświetl ustawienia SI +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Wyświetl ustawienia Game Script +STR_INTRO_TOOLTIP_QUIT :{BLACK}Wyjdź z „OpenTTD” STR_INTRO_BASESET :{BLACK}Aktualnie używany podstawowy zestaw graficzny nie posiada {NUM} wymagan{P ego ych ych} sprite{P 'u 'ów 'ów}. Proszę poszukać aktualizacji dla zestawu podstawowego. -STR_INTRO_TRANSLATION :{BLACK}Tej wersji językowej brakuje jeszcze {NUM} wpis{P "" y ów}. Możesz pomóc ulepszyć nam OpenTTD rejestrując się jako tłumacz. Szczegóły znajdziesz w pliku readme.txt. +STR_INTRO_TRANSLATION :{BLACK}Tej wersji językowej brakuje jeszcze {NUM} wpis{P "" y ów}. Możesz pomóc ulepszyć nam OpenTTD, rejestrując się jako tłumacz. Szczegóły znajdziesz w pliku „readme”. # Quit window STR_QUIT_CAPTION :{WHITE}Wyjście @@ -2512,12 +2506,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Zmień STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Zmień obecny rok STR_CHEAT_SETUP_PROD :{LTBLUE}Włącz modyfikowanie wielkości produkcji przedsiębiorstw: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Klimat umiarkowany -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Klimat arktyczny -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Klimat tropikalny -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Krajobraz zabawkowy - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Schemat kolorów @@ -2691,7 +2679,7 @@ STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Dopuszcz STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}Ustaw maksymalną liczbę klientów. Nie wszystkie miejsca muszą być zapełnione. STR_NETWORK_START_SERVER_COMPANIES_SELECT :{BLACK}{NUM} firm{P a y ""} STR_NETWORK_START_SERVER_NUMBER_OF_COMPANIES :{BLACK}Maksymalna liczba firm: -STR_NETWORK_START_SERVER_NUMBER_OF_COMPANIES_TOOLTIP :{BLACK}Ogranicz serwer do określonej ilości firm +STR_NETWORK_START_SERVER_NUMBER_OF_COMPANIES_TOOLTIP :{BLACK}Ogranicz serwer do określonej liczby firm STR_NETWORK_START_SERVER_NEW_GAME_NAME_OSKTITLE :{BLACK}Wpisz nazwę dla gry sieciowej @@ -2750,7 +2738,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nowa firma) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Utwórz nową firmę i dołącz do niej STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}To jesteś ty STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}To jest gospodarz gry -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" ów ów} / {NUM} firm{P a y ""} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" ów ów} - {NUM}/{NUM} firm{P ę y ""} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Liczba aktualnie podłączonych klientów, liczba firm oraz maksymalna liczba firm dozwolona przez administratora serwera # Matches ConnectionType ###length 5 @@ -2877,13 +2866,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :oczekiwanie na STR_NETWORK_MESSAGE_CLIENT_LEAVING :opuszczanie STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} dołączył do gry. -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} dołączył do gry (Klient #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} dołączył do firmy #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} dołączył do gry (Klient #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} dołączył do firmy #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} dołączył do obserwatorów -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} założył nową firmę (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} opuścił grę ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} założył nową firmę (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} opuścił grę ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} zmienił swoją nazwę na {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** Firma {STRING} przekazała firmie {1:STRING} {2:CURRENCY_LONG} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** Firma {0:STRING} przekazała firmie {1:STRING} {2:CURRENCY_LONG} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Serwer zamknął sesję STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Restart serwera...{}Proszę czekać... STR_NETWORK_MESSAGE_KICKED :*** {STRING} został wyrzucony. Powód: ({STRING}) @@ -2997,6 +2986,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}nasycony STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}przeładowany +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} miesięcznie do przetransportowania z {STATION} do {STATION} ({COMMA}% przepustowości){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} do przetransportowania z powrotem ({COMMA}% przepustowości) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Średni czas podróży: {NUM}{NBSP}d{P zień ni ni} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Podświetlaj zasięg STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Wył. @@ -3005,6 +2999,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Nie pod STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Podświetl zasięg projektowanej stacji STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Akceptuje: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Zasoby: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Koszt utrzymania: {GOLD}{CURRENCY_SHORT}/rok # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Połącz stację @@ -3087,8 +3082,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Zwiększ STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Wybierz rodzaj mostu kolejowego STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Wybierz most drogowy STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Wybór mostu - kliknij na wybranym moście, aby go zbudować -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Podwieszany, stalowy STR_BRIDGE_NAME_GIRDER_STEEL :Dźwigarowy, stalowy STR_BRIDGE_NAME_CANTILEVER_STEEL :Wspornikowy, stalowy @@ -3192,11 +3189,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Krajobra STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Obniżenie narożnika terenu. Przeciągnięcie obniża pierwszy zaznaczony róg i wyrównuje zaznaczony obszar do nowej wysokości rogu. Ctrl zaznacza obszar po przekątnej. Shift przełącza pomiędzy trybem budowania a szacowaniem jego kosztów STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Podwyższenie narożnika terenu. Przeciągnięcie podnosi pierwszy zaznaczony róg i wyrównuje zaznaczony obszar do nowej wysokości rogu. Ctrl zaznacza obszar po przekątnej. Shift przełącza pomiędzy trybem budowania a szacowaniem jego kosztów STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Wyrównaj teren do wysykości pierwszego zaznaczonego rogu. Ctrl zaznacza teren po przekątnej. Shift przełącza pomiędzy trybem budowania a szacowaniem jego kosztów -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Zakup teren do przyszłego użycia. Shift przełącza pomiędzy trybem kupowania a szacowaniem jego kosztów +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Zakup teren do przyszłego użycia. Ctrl zaznacza obszar po przekątnej. Shift przełącza pomiędzy trybem kupowania a szacowaniem jego kosztów # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Wybór obiektu -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Wybierz obiekt do budowy. Shift przełącza pomiędzy trybem budowy a szacowaniem jej kosztów +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Wybierz obiekt do budowy. Ctrl zaznacza obszar po przekątnej. Shift przełącza pomiędzy trybem budowy a szacowaniem jej kosztów STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Wybierz rodzaj obiektu do budowy STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Podgląd obiektu STR_OBJECT_BUILD_SIZE :{BLACK}Rozmiar: {GOLD}{NUM} x {NUM} pól @@ -3208,7 +3205,7 @@ STR_OBJECT_CLASS_TRNS :Nadajniki STR_PLANT_TREE_CAPTION :{WHITE}Drzewa STR_PLANT_TREE_TOOLTIP :{BLACK}Wybierz typ drzew do sadzenia. Jeśli na wybranym miejscu są już drzewa, to dodasz więcej drzew różnego typu, bez względu na wybraną opcję. STR_TREES_RANDOM_TYPE :{BLACK}Drzewa różnych rodzajów -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Sadzenie drzew różnych rodzajów. Shift przełącza pomiędzy trybem sadzenia a szacowaniem jego kosztów +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Sadzenie drzew różnych rodzajów. Ctrl zaznacza teren po przekątnej. Shift przełącza pomiędzy trybem sadzenia a szacowaniem jego kosztów STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Losowe drzewa STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Pokryj losowo krajobraz drzewami STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normalny @@ -3240,6 +3237,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Losowe m STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Budowa miasta w losowym miejscu STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Wiele losowych miast STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Pokryj mapę losowo położonymi miastami +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Rozszerz wszystkie miasta +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Zwiększ trochę rozmiar wszystkich miast STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nazwa miasta: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Wprowadź nazwę miasta @@ -3504,7 +3503,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Szczegó STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Brak dostępnych informacji STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Fraza filtru: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtr: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Zastąp plik STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Czy na pewno chcesz zastąpić istniejący stan gry? STR_SAVELOAD_DIRECTORY :{STRING} (folder) @@ -3518,6 +3517,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Rozmiar STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Wybierz rozmiar mapy w kwadratach. Liczba dostępnych kwadratów będzie nieco mniejsza STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Liczba miast: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nazwy miast: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Wybierz styl nazw miast STR_MAPGEN_DATE :{BLACK}Data: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Liczba przedsiębiorstw: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Najwyższy szczyt: @@ -3531,13 +3532,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Pokrycie STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Zwiększ pokrycie pustynią o 10% STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Zmniejsz pokrycie pustynią o 10% STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Generator terenu: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Typ terenu: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Poziom wody: +STR_MAPGEN_SEA_LEVEL :{BLACK}Poziom wody: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Liczba rzek: STR_MAPGEN_SMOOTHNESS :{BLACK}Gładkość: STR_MAPGEN_VARIETY :{BLACK}Różnorodność: STR_MAPGEN_GENERATE :{WHITE}Stwórz +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Ustawienia NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Wyświetl ustawienia NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Ustawienia SI +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Wyświetl ustawienia SI +STR_MAPGEN_GS_SETTINGS :{BLACK}Ustawienia Game Script +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Wyświetl ustawienia Game Script + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Angielskie (Oryginalne) +STR_MAPGEN_TOWN_NAME_FRENCH :Francuskie +STR_MAPGEN_TOWN_NAME_GERMAN :Niemieckie +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Angielskie (Rozszerzone) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Południowoamerykańskie +STR_MAPGEN_TOWN_NAME_SILLY :Śmieszne (Angielskie) +STR_MAPGEN_TOWN_NAME_SWEDISH :Szwedzkie +STR_MAPGEN_TOWN_NAME_DUTCH :Holenderskie +STR_MAPGEN_TOWN_NAME_FINNISH :Fińskie +STR_MAPGEN_TOWN_NAME_POLISH :Polskie +STR_MAPGEN_TOWN_NAME_SLOVAK :Słowackie +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norweskie +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Węgierskie +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austriackie +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumuńskie +STR_MAPGEN_TOWN_NAME_CZECH :Czeskie +STR_MAPGEN_TOWN_NAME_SWISS :Szwajcarskie +STR_MAPGEN_TOWN_NAME_DANISH :Duńskie +STR_MAPGEN_TOWN_NAME_TURKISH :Tureckie +STR_MAPGEN_TOWN_NAME_ITALIAN :Włoskie +STR_MAPGEN_TOWN_NAME_CATALAN :Katalońskie # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Krańce mapy: @@ -3596,7 +3625,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Szczegó STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Aktywne pliki NewGRF STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Nieaktywne pliki NewGRF STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Wybierz konfigurację: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtruj napis: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtr: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Załaduj wskazany stan ustawień STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Zapisz schemat STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Zapisz obecną listę jako stan ustawień @@ -3674,41 +3703,48 @@ STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE :Typ szyn STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}NewGFR zmienna 60+parametr x (heksadecymalnie) # Sprite aligner window -STR_SPRITE_ALIGNER_CAPTION :{WHITE}Dostosowanie obrazka {COMMA} ({STRING}) -STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}Następny obrazek -STR_SPRITE_ALIGNER_NEXT_TOOLTIP :{BLACK}Idź do następnego normalnego obrazka, pomijając jakiekolwiek pseudo/kolorowe/znakowe obrazki i zawijaj je od ostatniego do pierwszego -STR_SPRITE_ALIGNER_GOTO_BUTTON :{BLACK}Idź do obrazka -STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK}Idź do danego obrazka. Jeśli dany obrazek nie jest normalnym obrazkiem, idź do następnego normalnego obrazka -STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Poprzedni obrazek -STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Idź do poprzedniego normalnego obrazka, pomijając jakiekolwiek pseudo/kolorowe/znakowe obrazki i zawijaj je od pierwszego do ostatniego -STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Przedstawienie wybranego orbazka. Dostosowanie jest ignorowane podczas rysowania tego obrazka -STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Poruszaj obrazkiem, zmieniając przesunięcia X i Y. Ctrl+klik aby przesunąć o 8 jednostek na raz. -STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Resetuj zależność -STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Resetuj aktualne offsety zależne -STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X offset: {NUM}, Y offset: {NUM} (Całkowity) -STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}X offset: {NUM}, Y offset: {NUM} (Zależny) -STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Wybierz obrazek -STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Wybierz obrazek z dowolnego miejsca na ekranie - -STR_SPRITE_ALIGNER_GOTO_CAPTION :{WHITE}Idź do obrazka +STR_SPRITE_ALIGNER_CAPTION :{WHITE}Wyrównywanie sprite'a {COMMA} ({STRING}) +STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}Następny sprite +STR_SPRITE_ALIGNER_NEXT_TOOLTIP :{BLACK}Idź do następnego normalnego sprite'a, pomijając jakiekolwiek pseudo / przebarwione / czcionkowe sprite'y, a po ostatnim przejdź do pierwszego +STR_SPRITE_ALIGNER_GOTO_BUTTON :{BLACK}Idź do sprite'a +STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK}Idź do danego sprite'a. Jeśli dany sprite nie jest normalnym spritem, przejdź do następnego normalnego sprite'a +STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Poprzedni sprite +STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Idź do poprzedniego normalnego sprite'a, pomijając jakiekolwiek pseudo / przebarwione / czcionkowe sprite'y, a po pierwszym przejdź do ostatniego +STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Prezentacja wybranego sprite'a. Wyrównanie jest ignorowane podczas rysowania tego sprite'a +STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Poruszaj spritem, zmieniając przesunięcia X i Y. Ctrl+klik aby przesunąć o 8 jednostek na raz + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Wyśrodkowanie przesunięcia +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Wyśrodkowanie sprite'a + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Prowadnice + +STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Wyzeruj względność +STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Wyzeruj aktualne względne przesunięcia +STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Przesunięcie X: {NUM}, przesunięcie Y: {NUM} (bezwzględne) +STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}Przesunięcie X: {NUM}, przesunięcie Y: {NUM} (względne) +STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Wybierz sprite'a +STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Wybierz sprite'a z dowolnego miejsca na ekranie + +STR_SPRITE_ALIGNER_GOTO_CAPTION :{WHITE}Idź do sprite'a # NewGRF (self) generated warnings/errors STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING} STR_NEWGRF_ERROR_MSG_WARNING :{RED}Ostrzeżenie: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Błąd: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Błąd krytyczny: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Wystąpił błąd krytyczny NewGRF:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Wystąpił błąd NewGRF:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}NewGRF „{STRING}” zwrócił błąd krytyczny:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF „{STRING}” zwrócił błąd:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} nie zadziała z wersją TTDPatcha zgłoszoną przez OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} jest przeznaczony dla TTD wersji {STRING} -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} jest zaprojektowany do użycia z {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Niewłaściwy parametr dla {1:STRING}: parametr {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} musi być wczytany przed {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} musi być wczytany po {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} wymaga OpenTTD w wersji {STRING} lub nowszej +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} jest przeznaczony dla TTD w wersji {2:STRING} +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} jest zaprojektowany do użycia z {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Niewłaściwy parametr dla {1:STRING}: parametr {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} musi być wczytany przed {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} musi być wczytany po {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} wymaga OpenTTD w wersji {2:STRING} lub nowszej STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :pliku GRF który miał być tłumaczony STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Wczytano zbyt wiele NewGRF -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Ładowanie {1:STRING} jako statyczne NewGRF z {STRING} może spowodować desynchronizacje +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Ładowanie {1:STRING} jako statyczne NewGRF z {2:STRING} może spowodować desynchronizacje STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Nieoczekiwany sprite (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Nieznana wartość Action 0 {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Próba użycia niepoprawnego ID (sprite {3:NUM}) @@ -3840,14 +3876,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Kup wyłączno STR_LOCAL_AUTHORITY_ACTION_BRIBE :Daj łapówkę lokalnym władzom ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Rozpocznij małą kampanię reklamową aby zachęcić trochę pasażerów i fabryk do korzystania z Twoich usług transportowych.{}Zapewnia tymczasowy wzrost oceny stacji w małym promieniu wokół centrum miasta.{}Koszt: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Rozpocznij średnią kampanię reklamową, aby zachęcić więcej pasażerów i fabryk do korzystania z Twoich usług transportowych.{}Zapewnia tymczasowy wzrost oceny stacji w średnim promieniu wokół centrum miasta.{}Koszt: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Rozpocznij dużą kampanię reklamową aby zachęcić mnóstwo pasażerów i fabryk do korzystania z Twoich usług transportowych.{}Zapewnia tymczasowy wzrost oceny stacji w dużym promieniu wokół centrum miasta.{}Koszt: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Ufunduj remont sieci dróg.{}Spowoduje to zakłócenia w ruchu ulicznym do 6 miesięcy.{}Koszt: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Zbuduj pomnik dla uczczenia twojej firmy.{}Trwale podniesie to ocenę twoich stacji w pobliżu tego miasta.{}Koszt: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Ufunduj nowe budynki komercyjne w mieście.{}Daje jednorazowy impuls do szybszego wzrostu miasta.{}Koszt: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Kup roczną wyłączność na prawa transportowe w mieście.{} Lokalne władze nie pozwolą pasażerom ani przedsiębiorstwom korzystać z usług innych firm.{}Koszt: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Daj łapówkę lokalnym władzom. Powiększ swoją ocenę, ryzykując poważne kary w razie złapania.{}Koszt: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Rozpocznij małą lokalną kampanię reklamową, aby przyciągnąć więcej pasażerów i ładunków do twoich usług transportowych.{}Zapewnia tymczasowe zwiększenie oceny stacji w małym promieniu wokół centrum miasta.{}{POP_COLOUR}Koszt: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Rozpocznij średnią lokalną kampanię reklamową, aby przyciągnąć więcej pasażerów i ładunków do twoich usług transportowych.{}Zapewnia tymczasowe zwiększenie oceny stacji w umiarkowanym promieniu wokół centrum miasta.{}{POP_COLOUR}Koszt: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Rozpocznij dużą lokalną kampanię reklamową, aby przyciągnąć więcej pasażerów i ładunków do twoich usług transportowych.{}Zapewnia tymczasowe zwiększenie oceny stacji w dużym promieniu wokół centrum miasta.{}{POP_COLOUR}Koszt: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Ufunduj remont sieci dróg.{}Spowoduje to zakłócenia w ruchu ulicznym do 6 miesięcy.{}{POP_COLOUR}Koszt: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Zbuduj statuę dla uczczenia swojej firmy.{}Trwale podniesie to ocenę twoich stacji w pobliżu tego miasta.{}{POP_COLOUR}Koszt: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Ufunduj nowe budynki w mieście.{}Zapewnia tymczasowe przyspieszenie rozwoju tego miasta.{}{POP_COLOUR}Koszt: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Kup roczną wyłączność na prawa transportowe w mieście.{}Lokalne władze nie pozwolą pasażerom ani przedsiębiorstwom korzystać z usług innych firm.{}{POP_COLOUR}Koszt: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Przekup lokalne władze, aby zwiększyć swoją ocenę, ryzykując surową karę w przypadku przyłapania.{}{POP_COLOUR}Koszt: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}Cele firmy {COMPANY} @@ -4020,15 +4056,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Statki STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Odsetki od pożyczki STR_FINANCES_SECTION_OTHER :{GOLD}Inne +STR_FINANCES_TOTAL_CAPTION :{WHITE}Łącznie STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Zysk netto +STR_FINANCES_PROFIT :{WHITE}Zysk STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Bilans bankowy STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Środki własne STR_FINANCES_LOAN_TITLE :{WHITE}Pożyczka STR_FINANCES_INTEREST_RATE :{WHITE}Oprocentowanie pożyczki: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maksymalna pożyczka: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Pożyczka {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Zwiększ wielkość pożyczki. Ctrl+klik pożycza największą możliwą kwotę STR_FINANCES_REPAY_BUTTON :{BLACK}Zwrot {CURRENCY_LONG} @@ -4113,7 +4152,7 @@ STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUST STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nazwy przedsiębiorstw - kliknij na nazwę przedsiębiorstwa, aby wyśrodkować na nim widok główny. Ctrl+klik otwiera nowy podgląd na lokalizację przedsiębiorstwa STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Akceptowany ładunek: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Produkowany ładunek: {SILVER}{STRING} -STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Wszystkie typy ładunku +STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Wszystkie typy ładunków STR_INDUSTRY_DIRECTORY_FILTER_NONE :Żadne # Industry view @@ -4129,7 +4168,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Wytwarza STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Potrzebuje: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} oczekuje{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Zmiana produkcji (wielokrotność 8, do 2040) @@ -4159,6 +4198,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Wyślij STR_VEHICLE_LIST_REPLACE_VEHICLES :Zastąp pojazdy STR_VEHICLE_LIST_SEND_FOR_SERVICING :Wyślij do serwisu STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Zysk w tym roku: {CURRENCY_LONG} (ostatni rok: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Wyślij do warsztatów STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Wyślij do zajezdni @@ -4242,7 +4283,7 @@ STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Koszt: { STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Ładowność: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Moc: {GOLD}+{POWER}{BLACK} Masa: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Można przystosować do: {GOLD}{STRING} -STR_PURCHASE_INFO_ALL_TYPES :wszystkie typy ładunków +STR_PURCHASE_INFO_ALL_TYPES :Wszystkie typy ładunków STR_PURCHASE_INFO_NONE :Żadne STR_PURCHASE_INFO_ENGINES_ONLY :Tylko lokomotywy STR_PURCHASE_INFO_ALL_BUT :wszystko oprócz {CARGO_LIST} @@ -4250,6 +4291,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Maks. si STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Zasięg: {GOLD}{COMMA} pól STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Typ samolotu: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Wszystkie typy ładunków +STR_CARGO_TYPE_FILTER_FREIGHT :Fracht +STR_CARGO_TYPE_FILTER_NONE :Żaden + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Lista wyboru pociągów - kliknij na pojazd, aby uzyskać informacje. Ctrl+klik przełącza ukrywanie typu pojazdu STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Lista wyboru pojazdów drogowych - kliknij na pojazd, aby uzyskać więcej informacji. Ctrl+klik przełącza ukrywanie typu pojazdu @@ -4424,7 +4470,7 @@ STR_ENGINE_PREVIEW_SHIP :{G=m}statek STR_ENGINE_PREVIEW_SHIP.b :statek STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Koszt: {CURRENCY_LONG} Masa: {WEIGHT_SHORT}{}Prędkość: {VELOCITY} Moc: {POWER}{}Koszt utrzymania: {CURRENCY_LONG}/rok{}Ładowność: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Koszt: {CURRENCY_LONG} Masa: {WEIGHT_SHORT}{}Prędkość: {VELOCITY} Moc: {POWER} Maksymalna siła pociągowa: {6:FORCE}{}Koszt utrzymania: {4:CURRENCY_LONG}/rok{}Ładowność: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Koszt: {0:CURRENCY_LONG} Masa: {1:WEIGHT_SHORT}{}Prędkość: {2:VELOCITY} Moc: {3:POWER} Maks. siła pociągowa: {6:FORCE}{}Koszt utrzymania: {4:CURRENCY_LONG}/rok{}Ładowność: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Koszt: {CURRENCY_LONG} Prędkość maksymalna: {VELOCITY}{}Ładowność: {CARGO_LONG}{}Koszt utrzymania: {CURRENCY_LONG}/rok STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Koszt: {CURRENCY_LONG} Max. prędkość: {VELOCITY}{}Typ samolotu: {STRING}{}Ładowność: {CARGO_LONG}, {CARGO_LONG}{}Koszt utrzymania: {CURRENCY_LONG}/rok STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Koszt: {CURRENCY_LONG} Max. prędkość: {VELOCITY}{}Typ samolotu: {STRING}{}Ładowność: {CARGO_LONG}{}Koszt utrzymania: {CURRENCY_LONG}/rok @@ -4582,13 +4628,14 @@ STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Max. pr STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Masa: {LTBLUE}{WEIGHT_SHORT} {BLACK}Moc: {LTBLUE}{POWER}{BLACK} Prędkość maksymalna: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Masa: {LTBLUE}{WEIGHT_SHORT} {BLACK}Moc: {LTBLUE}{POWER}{BLACK} Prędkość maksymalna: {LTBLUE}{VELOCITY} {BLACK}Maksymalna siła pociągowa: {LTBLUE}{FORCE} -STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Zysk w tym roku: {LTBLUE}{CURRENCY_LONG} (w zeszłym roku: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Zysk w tym roku: {LTBLUE}{CURRENCY_LONG} (ostatni rok: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Zysk w tym roku: {LTBLUE}{CURRENCY_LONG} (ostatni rok: {CURRENCY_LONG}) {BLACK}Min. wydajność: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Niezawodność: {LTBLUE}{COMMA}% {BLACK}Awarie od ostatniego serwisowania: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Zakupiony: {LTBLUE}{NUM}{BLACK} Wartość: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Ładowność: {LTBLUE}żadna{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Ładowność: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Ładowność: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Ładowność: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Ładowność: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Ładowność: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Wartość ładunku: {LTBLUE}{CURRENCY_LONG} @@ -4740,14 +4787,14 @@ STR_ORDERS_DELETE_BUTTON :{BLACK}Usuń STR_ORDERS_DELETE_TOOLTIP :{BLACK}Usuń podświetlone polecenie STR_ORDERS_DELETE_ALL_TOOLTIP :{BLACK}Usuń wszystkie polecenia STR_ORDERS_STOP_SHARING_BUTTON :{BLACK}Przestań dzielić -STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}Przestań dzielić listę poleceń. Ctrl+Klik dodatkowo usuwa wszystkie polecenia tego pojazdu +STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}Przestań współdzielić listę poleceń. Ctrl+klik dodatkowo usuwa wszystkie polecenia tego pojazdu STR_ORDERS_GO_TO_BUTTON :{BLACK}Idź do STR_ORDER_GO_TO_NEAREST_DEPOT :Idź do najbliższego serwisu STR_ORDER_GO_TO_NEAREST_HANGAR :Leć do najbliższego hangaru STR_ORDER_CONDITIONAL :Warunkowy skok poleceń STR_ORDER_SHARE :Współdzielenie poleceń -STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Wstaw nowe polecenie na końcu listy lub przed zaznaczonym poleceniem. Ctrl ustawi polecenie stacji na 'pełny załadunek dowolnego towaru', pkt. orientacyjnego na 'bez zatrzymywania się', a zajezdni na 'serwisuj'. Kliknięcie innego pojazdu kopiuje jego polecenia, ctrl+klik (lub 'Współdzielenie poleceń') pozwala na dzielenie z nim poleceń. Polecenie zajezdni wyłącza automatyczne serwisowanie pojazdu +STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Dodaj nowe polecenie na końcu listy lub przed zaznaczonym poleceniem. Ctrl ustawi polecenie stacji na „pełny załadunek któregoś z towarów”, posterunku na „bez zatrzymywania się”, a zajezdni na „serwisuj”. Kliknięcie innego pojazdu kopiuje jego polecenia. „Współdzielenie poleceń” lub Ctrl+klik pozwala na współdzielenie z nim poleceń. Polecenie zajezdni wyłącza automatyczne serwisowanie tego pojazdu STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Pokaż wszystkie pojazdy współdzielące te polecenia @@ -4857,22 +4904,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Data poc STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Wybierz początkową datę rozkładu jazdy. Ctrl+klik rozłoży równomierne wszystkie pojazdy współdzielące ten rozkład, począwszy od podanej daty, zgodnie z ich kolejnością, o ile rozkład ten jest kompletny STR_TIMETABLE_CHANGE_TIME :{BLACK}Zmień czas -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Zmień ilość czasu którą zaznaczone zadanie powinno zająć +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Zmień ilość czasu, jaką powinno zająć zaznaczone polecenie. Ctrl+klik ustala czas dla wszystkich poleceń STR_TIMETABLE_CLEAR_TIME :{BLACK}Usuń czas -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Usuń ilość czasu przeznaczoną na zaznaczone zadanie +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Wyczyść ilość czasu w zaznaczonym poleceniu. Ctrl+klik wyczyści czas we wszystkich poleceniach STR_TIMETABLE_CHANGE_SPEED :{BLACK}Zmień limit prędkości -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Zmień maksymalną prędkość podróży w zaznaczonym poleceniu +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Zmień maksymalną prędkość przejazdu w zaznaczonym poleceniu. Ctrl+klik zmieni prędkość we wszystkich poleceniach STR_TIMETABLE_CLEAR_SPEED :{BLACK}Wyczyść limit prędkości -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Wyczyść maksymalną prędkość podróży w zaznaczonym poleceniu +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Wyczyść maksymalną prędkość przejazdu w zaznaczonym poleceniu. Ctrl+klik wyczyści prędkość we wszystkich poleceniach STR_TIMETABLE_RESET_LATENESS :{BLACK}Wyzeruj spóźnienia -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Wyzeruj licznik spóźnienia, aby pojazd podróżował zgodnie z rozkładem jazdy +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Wyzeruj licznik spóźnienia, aby pojazd podróżował zgodnie z rozkładem jazdy. Ctrl+klik spowoduje wyzerowanie całej grupy, więc ostatni pojazd będzie punktualny, a wszystkie pozostałe będą przed czasem STR_TIMETABLE_AUTOFILL :{BLACK}Automat. wypełnienie -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Wypełnij automatycznie rozkład jazdy wartościami z następnego przejazdu (Ctrl+klik, aby spróbować utrzymać czasy oczekiwania) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Wypełnij automatycznie rozkład jazdy wartościami z następnego przejazdu. Ctrl+klik, aby spróbować utrzymać czasy oczekiwania STR_TIMETABLE_EXPECTED :{BLACK}Wymagany STR_TIMETABLE_SCHEDULED :{BLACK}Zaplanowany @@ -4916,12 +4963,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Jeden z STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Okno debugowania SI / Game Script jest dostępne tylko na serwerze # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Konfiguracja SI / Game Script +STR_AI_CONFIG_CAPTION_AI :{WHITE}Konfiguracja SI +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Konfiguracja Game Script STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Game Script, który zostanie załadowany podczas kolejnej gry STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}SI, które zostaną załadowane podczas kolejnej gry STR_AI_CONFIG_HUMAN_PLAYER :Ludzki gracz STR_AI_CONFIG_RANDOM_AI :Losowe SI STR_AI_CONFIG_NONE :(brak) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maksymalna liczba przeciwników: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Przesuń w górę STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Przesuń wybraną SI w górę listy @@ -4929,19 +4978,18 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Przesuń STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Przesuń wybraną SI w dół listy STR_AI_CONFIG_GAMESCRIPT :{SILVER}Game Script +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametry STR_AI_CONFIG_AI :{SILVER}SI -STR_AI_CONFIG_CHANGE :{BLACK}Wybierz {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :SI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Game Script +STR_AI_CONFIG_CHANGE_AI :{BLACK}Wybierz SI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Wybierz Game Script STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Wczytaj kolejny skrypt STR_AI_CONFIG_CONFIGURE :{BLACK}Konfiguruj STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Konfiguruj parametry skryptu # Available AIs window STR_AI_LIST_CAPTION :{WHITE}Dostępne {STRING} -STR_AI_LIST_CAPTION_AI :Gracze SI +STR_AI_LIST_CAPTION_AI :SI STR_AI_LIST_CAPTION_GAMESCRIPT :Game Scripty STR_AI_LIST_TOOLTIP :{BLACK}Kliknij, aby wybrać skrypt @@ -4962,7 +5010,7 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Zrzut ek STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Zrzut ekranu mapy wysokościowej STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Zrzut ekranu minimapy -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametry STR_AI_SETTINGS_CAPTION_AI :SI STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Game Script @@ -4979,7 +5027,7 @@ STR_TEXTFILE_VIEW_README :{BLACK}Odczytaj STR_TEXTFILE_VIEW_CHANGELOG :{BLACK}Lista zmian STR_TEXTFILE_VIEW_LICENCE :{BLACK}Licencja ###length 3 -STR_TEXTFILE_README_CAPTION :{WHITE}{STRING} {STRING} - plik readme.txt +STR_TEXTFILE_README_CAPTION :{WHITE}{STRING} {STRING} - plik „readme” STR_TEXTFILE_CHANGELOG_CAPTION :{WHITE}{STRING} {STRING} - lista zmian STR_TEXTFILE_LICENCE_CAPTION :{WHITE}{STRING} {STRING} - licencja @@ -5129,6 +5177,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... zbyt STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nie można stworzyć przedsiębiorstw... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Nie można tutaj wybudować: {STRING}... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Nie można tutaj wybudować tego przedsiębiorstwa... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Nie można znaleźć przedsiębiorstwa... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... zbyt blisko innego przedsiębiorstwa STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... należy najpierw wybudować miasto STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... dozwolone jedno na miasto @@ -5143,7 +5192,9 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... las STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... można zbudować tylko powyżej linii śniegu STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... można zbudować tylko poniżej linii śniegu -STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Nie ma odpowiednich miejsc dla przedsiębiorstw '{STRING}' +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Ufundowanie pechowo nie powiodło się; spróbuj ponownie +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Nie ma odpowiednich miejsc do poszukiwań takiego przedsiębiorstwa +STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Nie ma odpowiednich miejsc dla przedsiębiorstw „{STRING}” STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Zmień parametry tworzenia map, żeby uzyskać lepsze mapy # Station construction related errors @@ -5310,6 +5361,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Obiekt n STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... siedziba firmy na drodze STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Nie można nabyć tego terenu... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... to już jest twoje! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... osiągnięto limit budowy obiektów # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Nie można stworzyć grupy... @@ -5382,6 +5434,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Nie moż STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... pojazd jest zniszczony +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... nie wszystkie pojazdy są takie same + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Żadne pojazdy nie będą dostępne STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Zmień konfigurację swoich NewGRF-ów STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Obecnie żaden pojazd nie jest dostępny @@ -5399,7 +5453,7 @@ STR_ERROR_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Samolot # Order related errors STR_ERROR_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Brak miejsca na polecenia STR_ERROR_TOO_MANY_ORDERS :{WHITE}Zbyt wiele poleceń -STR_ERROR_CAN_T_INSERT_NEW_ORDER :{WHITE}Nie można wstawić nowego polecenia... +STR_ERROR_CAN_T_INSERT_NEW_ORDER :{WHITE}Nie można dodać nowego polecenia... STR_ERROR_CAN_T_DELETE_THIS_ORDER :{WHITE}Nie można usunąć tego polecenia... STR_ERROR_CAN_T_MODIFY_THIS_ORDER :{WHITE}Nie można zmodyfikować tego polecenia... STR_ERROR_CAN_T_MOVE_THIS_ORDER :{WHITE}Nie można przenieść tego polecenia... @@ -5408,6 +5462,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Nie moż STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... pojazd nie może jechać do wszystkich stacji STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... pojazd nie może jechać do tej stacji STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... pojazd dzielący ten rozkaz nie może jechać do tej stacji +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... nie wszystkie pojazdy mają takie same polecenia +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... nie wszystkie pojazdy współdzielą polecenia STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Nie można współdzielić listy poleceń... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Nie można zaprzestać współdzielenia listy poleceń... @@ -5415,6 +5471,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Nie moż STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... zbyt daleko od poprzedniego celu STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... samolot nie ma wystarczającego zasięgu +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Brak stacji kolejowej +STR_ERROR_NO_BUS_STATION :{WHITE}Brak przystanku autobusowego +STR_ERROR_NO_TRUCK_STATION :{WHITE}Brak stacji dla ciężarówek +STR_ERROR_NO_DOCK :{WHITE}Brak doku +STR_ERROR_NO_AIRPORT :{WHITE}Brak lotniska/lądowiska +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Brak przystanków na odpowiednim typie drogi +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Brak odpowiednich przystanków dla tego typu tramwajów +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Brak przystanków przeznaczonych dla pojazdów przegubowych.{}Pojazdy przegubowe wymagają przystanku przelotowego, a nie zatokowego +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Ten samolot nie może wylądować na tym lądowisku +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Ten helikopter nie może wylądować na tym lotnisku +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Brak posterunku kolejowego +STR_ERROR_NO_BUOY :{WHITE}Brak boi + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Nie można wyznaczyć rozkładu jazdy pojazdu... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Pojazdy mogą czekać tylko na stacjach diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 5127062d8cf4d..5ae46119b3f74 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}cv STR_UNITS_POWER_METRIC :{COMMA}cv STR_UNITS_POWER_SI :{COMMA}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -226,9 +236,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA} m STR_UNITS_HEIGHT_SI :{COMMA} m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Chave de filtragem: -STR_LIST_FILTER_OSKTITLE :{BLACK}Insira uma frase para filtrar por -STR_LIST_FILTER_TOOLTIP :{BLACK}Insira uma palavra-chave para filtrar a lista por +STR_LIST_FILTER_TITLE :{BLACK}Filtro: +STR_LIST_FILTER_OSKTITLE :{BLACK}Insira uma ou mais palavras-chave para filtrar a lista +STR_LIST_FILTER_TOOLTIP :{BLACK}Insira uma ou mais palavras-chave para filtrar a lista STR_TOOLTIP_GROUP_ORDER :{BLACK}Seleccionar ordem de agrupamento STR_TOOLTIP_SORT_ORDER :{BLACK}Seleccione forma de ordenação (descendente/ascendente) @@ -258,10 +268,10 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP :{BLACK}Mostrar STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT :{BLACK}Mostrar escondido ###length VEHICLE_TYPES -STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP :{BLACK}Ao activar este botão, os veículos ferroviários ocultos também serão exibidos -STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE_TOOLTIP :{BLACK}Ao activar este botão, os veículos rodoviários ocultos também serão exibidos -STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP_TOOLTIP :{BLACK}Ao activar este botão, os navios ocultos também serão exibidos -STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Ao activar este botão, os aviões ocultos também serão exibidos +STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP :{BLACK}Ao ativar este botão, os veículos ferroviários ocultos também serão exibidos +STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE_TOOLTIP :{BLACK}Ao ativar este botão, os veículos rodoviários ocultos também serão exibidos +STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP_TOOLTIP :{BLACK}Ao ativar este botão, os navios ocultos também serão exibidos +STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Ao ativar este botão, os aviões ocultos também serão exibidos # Query window STR_BUTTON_DEFAULT :{BLACK}Padrão @@ -308,7 +318,7 @@ STR_SORT_BY_RATING_MIN :Menor carga STR_SORT_BY_ENGINE_ID :EngineID (ordem clássica) STR_SORT_BY_COST :Custo STR_SORT_BY_POWER :Potência -STR_SORT_BY_TRACTIVE_EFFORT :Força de Tracção +STR_SORT_BY_TRACTIVE_EFFORT :Esforço de tração STR_SORT_BY_INTRO_DATE :Data de Introdução STR_SORT_BY_RUNNING_COST :Custo de circulação STR_SORT_BY_POWER_VS_RUNNING_COST :Potência/Custo de circulação @@ -377,9 +387,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Gerar lo STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Gerar indústrias STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Construir estradas STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Construção de carris para elétricos -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantar árvores. Shift alterna contruir/mostrar custo estimado +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantar árvores. "Ctrl" seleciona a área na diagonal. "Shift" alterna construir/mostrar custo estimado STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Colocar sinais -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar objecto. Shift alterna contruir/mostrar custo estimado +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar objeto. Ctrl seleciona a área diagonalmente. Shift alterna construir/mostrar custo estimado # Scenario editor file menu ###length 7 @@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Sair # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Opções do Jogo STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Definições -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Definições de IA / Scripts de Jogo +STR_SETTINGS_MENU_AI_SETTINGS :Definições de IA +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Definições de script de jogo STR_SETTINGS_MENU_NEWGRF_SETTINGS :Definições NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opções de Transparência STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Mostrar nomes de localidades @@ -598,8 +609,8 @@ STR_GRAPH_COMPANY_VALUES_CAPTION :{WHITE}Valor da STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Tarifas por carga STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL :{TINY_FONT}{BLACK}Dias em trânsito STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Pagamento por entregar 10 unidades (ou 10 000 litros) de carga numa distância de 20 quadrados -STR_GRAPH_CARGO_ENABLE_ALL :{TINY_FONT}{BLACK}Activar tudo -STR_GRAPH_CARGO_DISABLE_ALL :{TINY_FONT}{BLACK}Desactivar tudo +STR_GRAPH_CARGO_ENABLE_ALL :{TINY_FONT}{BLACK}Ativar tudo +STR_GRAPH_CARGO_DISABLE_ALL :{TINY_FONT}{BLACK}Desativar tudo STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}Mostrar todas as cargas no gráfico de tarifas por carga STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Não mostrar carga no gráfico de tarifas por carga STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Mostrar/ocultar gráfico para o tipo de carga @@ -776,8 +787,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}Desactivar tudo -STR_SMALLMAP_ENABLE_ALL :{BLACK}Activar tudo +STR_SMALLMAP_DISABLE_ALL :{BLACK}Desativar tudo +STR_SMALLMAP_ENABLE_ALL :{BLACK}Ativar tudo STR_SMALLMAP_SHOW_HEIGHT :{BLACK}Mostrar altura STR_SMALLMAP_TOOLTIP_DISABLE_ALL_INDUSTRIES :{BLACK}Não mostrar indústrias no mapa STR_SMALLMAP_TOOLTIP_ENABLE_ALL_INDUSTRIES :{BLACK}Mostrar todas as indústrias no mapa @@ -966,42 +977,12 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rupia Indiana ( STR_GAME_OPTIONS_CURRENCY_IDR :Rupia Indonésia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit da Malásia (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Circular pela esquerda -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Circular pela direita - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nomes das localidades: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Seleccionar o estilo dos nomes das localidades - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Inglês -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francês -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Alemão -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Inglês (Adicional) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latino-Americano -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Absurdo -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Sueco -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holandês -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandês -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polaco -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Eslovaco -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norueguês -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Húngaro -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austríaco -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romeno -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Checo -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Suíço -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dinamarquês -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turco -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiano -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalão - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Guardar automaticamente STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Seleccionar o intervalo para guardar automático # Autosave dropdown ###length 5 -STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF :Desactivado +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF :Desativado STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_1_MONTH :Cada mês STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_3_MONTHS :Cada 3 meses STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_6_MONTHS :Cada 6 meses @@ -1028,21 +1009,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Marque e STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}"Driver" atual: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Tamanho interface -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Seleccionar tamanho do elemento de interface a usar +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Tamanho do interface +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Arraste o controle deslizante para definir o tamanho do interface. Mantenha pressionada a tecla Ctrl para um ajuste contínuo +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Auto-detetar o tamanho +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marque esta caixa para detetar automaticamente o tamanho do interface -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(auto-detetar) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dobro do tamanho -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quádruplo do tamanho +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Escalar chanfros +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marque esta caixa para dimensionar os chanfros por tamanho de interface -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Tamanho da fonte -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Seleccionar tamanho da fonte de interface a usar - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(auto-detetar) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dobro do tamanho -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quádruplo do tamanho +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Gráficos @@ -1094,8 +1073,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Pré-vi STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Libras (£) na sua moeda STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Mudar parâmetro de moeda modificada -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Número máximo de oponentes: {ORANGE}{COMMA} - STR_NONE :Nenhum STR_FUNDING_ONLY :Financiamento apenas STR_MINIMAL :Mínimo @@ -1145,6 +1122,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Terreno temperado +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Terreno subárctico +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Terreno subtropical +STR_CLIMATE_TOYLAND_LANDSCAPE :Terreno terra dos brinquedos + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Muito Plano STR_TERRAIN_TYPE_FLAT :Plano @@ -1164,7 +1147,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}Não exi # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Definições -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrar frase: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtro: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Expandir todas STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Colapsar todas STR_CONFIG_SETTING_RESET_ALL :{BLACK}Repor todos os valores @@ -1205,7 +1188,7 @@ STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}Mostrar ###length 3 STR_CONFIG_SETTING_OFF :Desligado STR_CONFIG_SETTING_ON :Ligado -STR_CONFIG_SETTING_DISABLED :Desactivado +STR_CONFIG_SETTING_DISABLED :Desativado ###length 3 STR_CONFIG_SETTING_COMPANIES_OFF :Desligado @@ -1224,9 +1207,12 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Direita STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Valor máximo do empréstimo inicial: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Quantia máxima que uma companhia pode pedir (sem ter em conta a inflação) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Sem empréstimo {RED}Requer Script de Jogo para fornecer fundos iniciais STR_CONFIG_SETTING_INTEREST_RATE :Taxa de juro: {STRING} -STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Taxa de juro do empréstimo; também controla a inflacção, se activo +STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Taxa de juro do empréstimo; também controla a inflação, se ativo STR_CONFIG_SETTING_RUNNING_COSTS :Custos operacionais: {STRING} STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Configurar nível de manutenção e custos operacionais de veículos e infraestrutura @@ -1251,13 +1237,13 @@ STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Custos de const STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Configurar o nível de construção e custos de compra STR_CONFIG_SETTING_RECESSIONS :Recessões: {STRING} -STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Se activo, podem ocorrer recessões em intervalos de poucos anos. Durante uma recessão a produção em geral é mais baixa (volta aos níveis anteriores quando termina) +STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Se ativo, podem ocorrer recessões em intervalos de poucos anos. Durante uma recessão a produção em geral é mais baixa (volta aos níveis anteriores quando termina) STR_CONFIG_SETTING_TRAIN_REVERSING :Desabilitar inversão de combóios nas estações: {STRING} -STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Quando activo, os combóios não podem inverter marcha em estações não-terminais, mesmo se existir um caminho mais curto para o destino seguinte com inversão +STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Quando ativo, os comboios não podem inverter marcha em estações não-terminais, mesmo se existir um caminho mais curto para o próximo destino ao inverter STR_CONFIG_SETTING_DISASTERS :Desastres: {STRING} -STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Activa desastres que podem ocasionalmente bloquear ou destruir veículos ou infraestruturas +STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Ativa desastres que podem ocasionalmente bloquear ou destruir veículos ou infraestruturas STR_CONFIG_SETTING_CITY_APPROVAL :Atitude da autoridade local: {STRING} STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Escolha de que forma o ruído e dano ambiental causado pelas empresas afeta o rating da povoação e futuras ações de construção nessa povoação @@ -1276,7 +1262,7 @@ STR_CONFIG_SETTING_CATCHMENT :Dimensionamento STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Haver diferentes áreas de cobertura para diferentes tipos de estações e aeroportos STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Estações da companhia podem servir industrias equipadas com estações neutras: {STRING} -STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Quando activo, industrias com estações incluídas (com as Petrolíferas) podem ser servidas por estações da companhia construídas nas redondezas. Quando inactivo, estas industrias só podem ser servidas pela sua própria estação. Qualquer estação da companhia não poderá servir a industria, nem a estação incluída poder servir outra entidade senão a própria industria +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Quando ativo, industrias com estações incluídas (com as Petrolíferas) podem ser servidas por estações da companhia construídas nas redondezas. Quando inativo, estas industrias só podem ser servidas pela sua própria estação. Qualquer estação da companhia não poderá servir a industria, nem a estação incluída pode servir outra entidade senão a própria industria STR_CONFIG_SETTING_EXTRADYNAMITE :Permite remover mais estradas, pontes e túneis detidos pela cidade: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Facilitar a remoçar de edifícios e infraestruturas detidas pela localidade @@ -1289,10 +1275,10 @@ STR_CONFIG_SETTING_SMOKE_AMOUNT :Quantidade de f STR_CONFIG_SETTING_SMOKE_AMOUNT_HELPTEXT :Assignar quanto fumo ou quantas faíscas são emitidas pelos veículos STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL :Modelo de aceleração de comboios: {STRING} -STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL_HELPTEXT :Escolha o modelo de física para a aceleração de comboios. O modelo "original" penalisa as inclinações para todos os veículos. O modelo "realista" penalisa as curvas e inclinações tendo em conta várias propriedades do objecto, como o tamanho e esforço tractivo +STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL_HELPTEXT :Escolha o modelo de física para a aceleração de comboios. O modelo "original" penaliza as inclinações para todos os veículos. O modelo "realista" penaliza as curvas e inclinações tendo em conta várias propriedades do comboio, tais como o comprimento e o esforço de tração STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL :Tipo de aceleração dos veículos rodoviários: {STRING} -STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL_HELPTEXT :Escolha o modelo de física para a aceleração de veículos de estrada. O modelo "original" penalisa as inclinações para todos os veículos. O modelo "realista" penalisa as curvas e inclinações tendo em conta várias propriedades do motor, como o esforço tractivo +STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL_HELPTEXT :Escolha o modelo de física para a aceleração de veículos de estrada. O modelo "original" penaliza as inclinações para todos os veículos. O modelo "realista" penaliza as curvas e inclinações tendo em conta várias propriedades do motor, tais como o esforço de tração STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS :Ângulo de inclinação para comboios: {STRING} STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Ângulo de inclinação de um quadrado para um comboio. Valores mais elevados tornam a subida mais difícil @@ -1320,11 +1306,11 @@ STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH :Tamanho máximo STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT :Tamanho máximo para construção de túneis STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD :Método de financiamento de indústrias primárias: {STRING} -STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :Método de financiar uma indústria primária. 'nenhum' significa que não é possível financiar nenhuma, 'prospecção' significa que é possível financiar, mas a construção é feita num local arbitrário no mapa e até pode falhar, 'como as outras' significa que as indústrias de matérias primas podem ser construídas em qualquer sítio pelas empresas, como se fossem indústrias de processamento +STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :Método de financiar uma indústria primária. 'nenhum' significa que não é possível financiar nenhuma; 'em prospeção' significa que é possível financiar, mas a construção é feita num local aleatório no mapa e pode até falhar; 'como as outras' significa que as indústrias de matérias primas podem ser construídas em qualquer local escolhido pelas empresas, como se fossem indústrias de processamento ###length 3 STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NONE :Nenhum STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NORMAL :Como as outras -STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_PROSPECTING :Prospecção +STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_PROSPECTING :Em prospeção STR_CONFIG_SETTING_INDUSTRY_PLATFORM :Área plana à volta das industrias: {STRING} STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :Quantidade de terreno plano á volta de uma industria. Isto garante que terreno vazio esteja disponível para construir linhas, etc @@ -1353,7 +1339,7 @@ STR_CONFIG_SETTING_STOP_LOCATION_MIDDLE :no meio STR_CONFIG_SETTING_STOP_LOCATION_FAR_END :no extremo longe STR_CONFIG_SETTING_AUTOSCROLL :Deslocar janela quando o rato está na borda do mapa: {STRING} -STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT :Quando activo, os visualizadores começam a deslocar-se logo que o rato esteja no extremo da janela +STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT :Quando ativo, os visualizadores começam a deslocar-se logo que o rato esteja no extremo da janela ###length 4 STR_CONFIG_SETTING_AUTOSCROLL_DISABLED :Desligado STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN :Visualizador principal, só ecrã cheio @@ -1376,7 +1362,7 @@ STR_CONFIG_SETTING_ALLOW_GIVE_MONEY :Permite enviar STR_CONFIG_SETTING_ALLOW_GIVE_MONEY_HELPTEXT :Permite transferências de dinheiro entre empresas em modo multi-jogador STR_CONFIG_SETTING_FREIGHT_TRAINS :Multiplicador de peso para simular comboios pesados: {STRING} -STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :Define o impacto de carregar mercadoria nos combóios. Um valor superior torna o carregamento de meradoria mais exigente para os combóios, especialmente em terreno inclinado +STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :Define o impacto de carregar mercadoria nos comboios. Um valor elevado torna o transporte de mercadorias mais exigente para os comboios, especialmente em terreno inclinado STR_CONFIG_SETTING_PLANE_SPEED :Fator de velocidade de avião: {STRING} STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Set the relative speed of planes compared to other vehicle types, to reduce the amount of income of transport by aircraft @@ -1396,13 +1382,13 @@ STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :Permite constru STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Não é possível mudar quando já existem veículos. STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Manutenção de infraestruturas: {STRING} -STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Quando activo, as infraestruturas têm custos de manutenção. O custo cresce mais do que proporcionalmente com o tamanho da rede e com isso afecta mais as companhias maiores comparado com as mais pequeneas +STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Quando ativo, as infraestruturas têm custos de manutenção. O custo cresce mais do que proporcionalmente com o tamanho da rede e com isso afeta mais as companhias maiores comparando com as mais pequenas STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Côr de inicio da empresa: {STRING} STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Escolher côr de inicio da empresa STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Aeroportos nunca expiram: {STRING} -STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Activar esta preferência torna cada tipo de aeroporto disponível para sempre após a sua introdução +STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Ativar esta preferência torna cada tipo de aeroporto disponível para sempre após a sua introdução STR_CONFIG_SETTING_WARN_LOST_VEHICLE :Avisar se o veículo está perdido: {STRING} STR_CONFIG_SETTING_WARN_LOST_VEHICLE_HELPTEXT :Mostrar mensagens sobre veículos que não conseguem encontrar o caminho para o seu próximo destino. @@ -1415,13 +1401,13 @@ STR_CONFIG_SETTING_ORDER_REVIEW_EXDEPOT :Sim, mas exclui STR_CONFIG_SETTING_ORDER_REVIEW_ON :De todos os veículos STR_CONFIG_SETTING_WARN_INCOME_LESS :Avisar se o lucro de um veiculo for negativo: {STRING} -STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT :Quando activo, uma notícia é enviada quando um veículo não deu lucro durante um ano +STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT :Quando ativo, uma notícia é enviada quando um veículo não deu lucro durante um ano STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :Veículos nunca expiram: {STRING} -STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :Quando activo, todos os modelos de veículos permanecerão disponíveis para sempre após a sua introdução +STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :Quando ativo, todos os modelos de veículos permanecerão disponíveis para sempre após a sua introdução STR_CONFIG_SETTING_AUTORENEW_VEHICLE :Auto-renovação de veículos quando ficam velhos: {STRING} -STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :Quando activo, um veículo a chegar ao fim de vida é automaticamente substituído quando as condições de renovação estão reunidas +STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :Quando ativo, um veículo a chegar ao fim de vida é automaticamente substituído quando as condições de renovação estão reunidas STR_CONFIG_SETTING_AUTORENEW_MONTHS :Renovar automaticamente quando um veículo chega a {STRING} a idade máxima STR_CONFIG_SETTING_AUTORENEW_MONTHS_HELPTEXT :Idade relativa a partir da qual um veículo deva ser indicado para auto-renovação @@ -1450,6 +1436,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Largura da linh STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Exibir o nome do "NewGRF" na janela de compra de veículos: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Adiciona uma linha à janela de compra de veículos, mostrando a qual "NewGRF" pertence o veículo selecionado. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Mostrar as cargas que os veículos podem transportar nas janelas de listagem {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Quando ativo, a carga transportável do veículo aparecerá acima nas listas de veículos STR_CONFIG_SETTING_LANDSCAPE :Cenário: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Os climas definem a jogabilidade base dos cenários com diferentes cargas e requisitos de crescimento das localidades. Os "NewGRF" e "Scripts" de Jogo permitem um controlo mais preciso. @@ -1504,6 +1492,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Melhorada STR_CONFIG_SETTING_ROAD_SIDE :Veículos rodoviários: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Escolher o lado de condução +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Circular pela esquerda +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Circular pela direita + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotação mapa de alt.: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Sentido anti-horário @@ -1547,7 +1539,7 @@ STR_CONFIG_SETTING_SCROLLMODE_RMB :Mover mapa com STR_CONFIG_SETTING_SCROLLMODE_LMB :Mover mapa com Botão Esquerdo Rato STR_CONFIG_SETTING_SMOOTH_SCROLLING :Suavizar deslocamento da navegação no mapa: {STRING} -STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controla como a vista principal navega para uma posição específica ao clicar no mapa pequeno ou ao dar um comando para navegar para um objecto específico no mapa. Se activo, a vista principal navega suavemente, se inactivo a vista salta directamente para o destino. +STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controla como a vista principal navega para uma posição específica ao clicar no mapa pequeno ou ao dar um comando para navegar para um objeto específico no mapa. Se ativo, a vista principal navega suavemente, se inativo a vista salta diretamente para o destino. STR_CONFIG_SETTING_MEASURE_TOOLTIP :Mostrar medidas nas várias ferramentas de construção: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Mostrar distâncias em quadrados e diferenças de altura enquanto arrasta o rato durante tarefas de construção @@ -1566,7 +1558,7 @@ STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER :Velocidade da r STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER_HELPTEXT :Controlo de sensibilidade da roda de rolagem do rato STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING :Função da roda do rato: {STRING} -STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING_HELPTEXT :Activar navegação com rodas de scroll bidimensional +STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING_HELPTEXT :Ativar "scroll" com rodas de rato bidimensionais ###length 3 STR_CONFIG_SETTING_SCROLLWHEEL_ZOOM :Ampliar mapa STR_CONFIG_SETTING_SCROLLWHEEL_SCROLL :Percorrer mapa @@ -1575,7 +1567,7 @@ STR_CONFIG_SETTING_SCROLLWHEEL_OFF :Desligado STR_CONFIG_SETTING_OSK_ACTIVATION :Teclado no ecrã: {STRING} STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT :Selecione o método de abertura de teclado virtual para escrita de texto em caixas, usando apenas o cursor. Esta opção destina-se principalmente para equipamentos pequenos sem teclado físico. ###length 4 -STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :Desactivado +STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :Desativado STR_CONFIG_SETTING_OSK_ACTIVATION_DOUBLE_CLICK :Duplo clique STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK_FOCUS :Clique simples (quando em foco) STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK :Clique (imediatamente) @@ -1595,7 +1587,7 @@ STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL : + clique STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Desligado STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Fechar janelas ao fazer clique direito: {STRING} -STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Fecha uma janela ao fazer clique direito dentro dela. Desactiva os textos de ajuda ao fazer clique direito! +STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Fecha uma janela ao fazer clique direito dentro dela. Desativa os textos de ajuda ao fazer clique direito! STR_CONFIG_SETTING_AUTOSAVE :Guardar automaticamente: {STRING} STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Seleccione o intervalo entre gravações automáticas @@ -1608,7 +1600,7 @@ STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_SHORT :curto (31-12-20 STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_ISO :ISO (2008-12-31) STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME :Pausa automática ao iniciar um novo jogo: {STRING} -STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Quando activo, o jogo ficará em pausa automaticamente num novo jogo, permitindo o estudo ao pormenor do mapa +STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Quando ativo, o jogo ficará em pausa automaticamente num novo jogo, permitindo o estudo ao pormenor do mapa STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL :Durante pausa permitir: {STRING} STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_HELPTEXT :Seleccionar que acções podem ser feitas enquanto o jogo está em pausa @@ -1619,7 +1611,7 @@ STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_LANDSCAPING :Todas expecto a STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_ACTIONS :Todas as acções STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS :Usar a lista avançada de veículos: {STRING} -STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :Activar a utilização de listas avançadas de veículos para o agrupamento de veículos +STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :Ativar a utilização de listas avançadas de veículos para o agrupamento de veículos STR_CONFIG_SETTING_LOADING_INDICATORS :Usar indicadores de carga: {STRING} STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :Seleccionar se os indicadores de carga são mostrados acima de veículos em carga ou descarga @@ -1643,7 +1635,7 @@ STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_MOST_USED :Mais utilizado STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION :Mostrar caminho de ferro reservado: {STRING} STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION_HELPTEXT :Dar cores diferentes aos carris reservados para ajudar a detectar problemas com combóios que recusam entrar em bloqueios baseados em caminhos -STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS :Deixar ferramentas de construção activas depois de usadas: {STRING} +STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS :Deixar ferramentas de construção ativas depois de usadas: {STRING} STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS_HELPTEXT :Manter as ferramentas de construção de pontes, túneis, etc. abertas após uso STR_CONFIG_SETTING_AUTO_REMOVE_SIGNALS :Remover automaticamente os sinais durante a construção de vias férreas: {STRING} @@ -1691,20 +1683,20 @@ STR_CONFIG_SETTING_MAX_AIRCRAFT_HELPTEXT :Número máximo STR_CONFIG_SETTING_MAX_SHIPS :Máximo de navios por empresa: {STRING} STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :Número máximo de navios que uma companhia pode ter -STR_CONFIG_SETTING_AI_BUILDS_TRAINS :Desactivar comboios para o computador: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Activar esta preferência impossibilita a criação de comboios por jogadores controlados pelo computador +STR_CONFIG_SETTING_AI_BUILDS_TRAINS :Desativar comboios para o computador: {STRING} +STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Ativar esta preferência impossibilita a criação de comboios por jogadores controlados pelo computador -STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Desactivar veículos rodoviários para o computador: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Activar esta preferência impossibilita a construção de veículos de estrada por um jogador controlado pelo computador +STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Desativar veículos rodoviários para o computador: {STRING} +STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Ativar esta preferência impossibilita a construção de veículos de estrada por um jogador controlado pelo computador -STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Desactivar aeronaves para o computador: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Activar esta preferência impossibilita a construção de aeronaves por um jogador controlado pelo computador +STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Desativar aeronaves para o computador: {STRING} +STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Ativar esta preferência impossibilita a construção de aeronaves por um jogador controlado pelo computador -STR_CONFIG_SETTING_AI_BUILDS_SHIPS :Desactivar navios para o computador: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :Activar esta preferência impossibilita a construção de navios por um jogador controlado pelo computador +STR_CONFIG_SETTING_AI_BUILDS_SHIPS :Desativar navios para o computador: {STRING} +STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :Ativar esta preferência impossibilita a construção de navios por um jogador controlado pelo computador STR_CONFIG_SETTING_AI_PROFILE :Perfil de preferências por omissão: {STRING} -STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Escolher o perfil de preferências a usar para AIs aleatórias ou para valores iniciais ao adicionar uma nova AI ou Script de Jogo +STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Escolher o perfil de preferências a usar para IAs aleatórias ou para valores iniciais ao adicionar uma nova IA ou Script de Jogo ###length 3 STR_CONFIG_SETTING_AI_PROFILE_EASY :Fácil STR_CONFIG_SETTING_AI_PROFILE_MEDIUM :Média @@ -1720,7 +1712,7 @@ STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Definir o volum STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Os intervalos de serviço são em percentagem: {STRING} -STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Escolher se a manutenção de veículos é activada pelo tempo passado deste a última manutenção, ou pela fiabilidade abaixo de uma certa percentagem da fiabilidade máxima +STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Escolher se a manutenção de veículos é ativada pelo tempo decorrido deste a última manutenção, ou pela fiabilidade abaixo de uma certa percentagem da fiabilidade máxima STR_CONFIG_SETTING_SERVINT_TRAINS :Intervalo de serviço para comboios por omissão: {STRING} STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :Definir o intervalo de manutenção por omissão para novos veículos sobre carris, se não for configurado um intervalo de manutenção explícito para o veículo @@ -1738,10 +1730,10 @@ STR_CONFIG_SETTING_NOSERVICE :Não fazer manu STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Quando ativo, os veículos não farão manutenção se não puderem avariar STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Ativar limites de velocidade para vagões: {STRING} -STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Quando activo, usar também os limites de velocidade das carruagens para decidir a velocidade máxima de um comboio +STR_CONFIG_SETTING_WAGONSPEEDLIMITS_HELPTEXT :Quando ativo, aplica também os limites de velocidade dos vagões para decidir a velocidade máxima do comboio -STR_CONFIG_SETTING_DISABLE_ELRAILS :Desactivar carris electrificados: {STRING} -STR_CONFIG_SETTING_DISABLE_ELRAILS_HELPTEXT :Activar esta preferência desactiva o requisito de electrificar carris para que composições eléctricas os possam utilizar +STR_CONFIG_SETTING_DISABLE_ELRAILS :Desativar carris eletrificados: {STRING} +STR_CONFIG_SETTING_DISABLE_ELRAILS_HELPTEXT :Ativar esta preferência desativa o requisito de eletrificar carris para que composições elétricas os possam utilizar STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN :Chegada do primeiro veículo à estação do jogador: {STRING} STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN_HELPTEXT :Mostrar um jornal na chegada do primeiro veículo a uma estação nova do jogador @@ -1813,7 +1805,7 @@ STR_CONFIG_SETTING_ECONOMY_TYPE_SMOOTH :Suave STR_CONFIG_SETTING_ECONOMY_TYPE_FROZEN :Congelada STR_CONFIG_SETTING_ALLOW_SHARES :Permite comprar acções de outras empresas: {STRING} -STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Quando activo, permite a compra e venda de acções de companhias. As acções apenas estarão disponíveis quando a companhia atinge uma determinada idade. +STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Quando ativo, permite a compra e venda de ações de companhias. As ações apenas estarão disponíveis quando a companhia atinge uma determinada idade. STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Idade mínima da empresa para negociar ações: {STRING} STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Definir a idade mínima de uma companhia a partir da qual outros jogadores poderão comprar ou vender ações da mesma. @@ -1825,7 +1817,7 @@ STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Ao arrastar, co STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT :Define a distância a que os sinais serão construídos num carril até ao próximo obstáculo (sinal, junção), se os sinais são arrastados STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE :{COMMA} quadrado{P 0 "" s} STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE :Ao arrastar, manter distância fixa entre sinais: {STRING} -STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :Seleccionar o comportamento da colocação de sinais ao usar Ctrl+arrasto. Se desactivado, sinais são colocados à volta de túneis ou pontes para evitar longos trajectos sem sinais. Se activo, sinais são colocados a cada N mosaicos, facilitando o alinhamento de sinais em linhas paralelas +STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :Selecionar o comportamento da colocação de sinais ao usar Ctrl+arrasto. Se desativado, os sinais são colocados à volta de túneis ou pontes para evitar longos trajetos sem sinais. Se ativo, os sinais são colocados a cada N mosaicos, facilitando o alinhamento de sinais em linhas paralelas STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Usar automaticamente sinais clássicos antes de: {STRING} STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Configurar o ano em que sinais eléctricos podem ser usados para os carris. Antes deste ano, sinais não-eléctricos serão usados (que têm a mesma funcionalidade, mas aspecto diferente) @@ -1852,15 +1844,15 @@ STR_CONFIG_SETTING_TOWN_LAYOUT_3X3_GRID :grelha 3x3 STR_CONFIG_SETTING_TOWN_LAYOUT_RANDOM :Aleatório STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :As localidades têm permissão para construir estradas: {STRING} -STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Permite às localidades a construção de estradas para crescimento. Desactivar para não permitir às autoridades a construção de estradas +STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Permite às localidades a construção de estradas para crescimento. Desativar para prevenir a construção de estradas pelas autoridades locais. STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Localidades podem construir passagens de nível: {STRING} -STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Activar esta preferência permite às localidades construir cruzamentos nivelados +STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Ativar esta preferência permite às localidades construir cruzamentos nivelados STR_CONFIG_SETTING_NOISE_LEVEL :Permitir que a localidade controle o nível de ruído dos aeroportos: {STRING} -STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Com esta preferência desactivada, podem haver dois aeroportos em cada localidade. Com esta preferência activa, o número de aeroportos numa localidade é limitado pela aceitação do ruído na mesma, que depende da população, do tamanho do aeroporto e da sua distância +STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Com esta preferência desativada, podem haver dois aeroportos em cada localidade. Com esta preferência ativa, o número de aeroportos numa localidade é limitado pela aceitação do ruído na mesma, que depende da população, do tamanho do aeroporto e da sua distância STR_CONFIG_SETTING_TOWN_FOUNDING :Fundar localidades no jogo: {STRING} -STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Activar esta preferência permite aos jogadores fundar novas povoações no jogo +STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Ativar esta preferência permite aos jogadores fundar novas povoações no jogo ###length 3 STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Proibido STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Permitido @@ -1937,13 +1929,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Requer {STRING} STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tempo para cada recalculo de um componente de um gráfico. Quando um recalculo começa, um processo é criado e é executado para esse número de dias. Quantos menos dias forem definidos, maior a probabilidade do processo não terminar quando já deveria ter terminado. Neste caso, o jogo irá parar até ele terminar ("lag"). Quanto maior o definir, mais tempo levará para a distribuição ser actualizada quando as rotas mudarem. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modo de distribuição para os passageiros: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"simétrico" significa que aproximadamente o mesmo numero de passageiros irá de uma estação A para estação B e de B para A. "assimétrico" significa que um numero arbitrário de passageiros poderá seguir em qualquer direcção. "manual" significa que nenhuma distribuição automática terá lugar para passageiros. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simétrico" significa que aproximadamente o mesmo numero de passageiros irá de uma estação A para uma estação B e de B para A. "Assimétrico" significa que um numero arbitrário de passageiros poderá seguir em qualquer direção. "Manual" significa que nenhuma distribuição automática terá lugar para passageiros. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Modo de distribuição para o correio: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"simétrico" significa que aproximadamente a mesma quantidade de correio será enviada de uma estação A para estação B assim como de B para A. "assimétrico" significa que uma quantidade arbitrária de correio poderá ser enviada em qualquer direcção. "manual" significa que nenhuma distribuição automática terá lugar para o correio. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Simétrico" significa que aproximadamente a mesma quantidade de correio será enviada de uma estação A para a estação B assim como de B para A. "Assimétrico" significa que uma quantidade arbitrária de correio poderá ser enviada em qualquer direção. "Manual" significa que nenhuma distribuição automática terá lugar para o correio. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Modo de distribuição para a classe de carga ARMOURED: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :A classe de carga ARMOURED contém valores no clima temperado, diamantes no tropical ou ouro no árctico. Os NewGRFs podem mudar isto. "simétrico" significa que aproximadamente a mesma quantidade de carga será enviada da estação A para estação B assim como da B para a A. "assimétrico" significa que quantidades arbitrárias dessa carga podem ser enviadas em qualquer direcção. "manual" significa que nenhuma distribuição automática ocorrerá para essa carga. Recomenda-se que seja definido para assimétrico ou manual quando a jogar no árctico, pois os bancos não devolvem ouro para as minas de ouro. Para o temperado e tropical pode ser escolhido simétrico pois os bancos irão devolver valores ao banco de origem de algumas cargas de valores. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :A classe de carga "ARMOURED" (Blindado) contém valores no clima temperado, diamantes no tropical ou ouro no ártico. Os NewGRFs podem mudar isto. "Simétrico" significa que aproximadamente a mesma quantidade de carga será enviada da estação A para a estação B assim como da B para a A. "Assimétrico" significa que quantidades arbitrárias dessa carga podem ser enviadas em qualquer direção. "Manual" significa que nenhuma distribuição automática ocorrerá para essa carga. Recomenda-se que seja definido para assimétrico ou manual quando a jogar no ártico ou no tropical, pois os bancos nesses climas só recebem mercadorias. Para o temperado pode ser também escolhido simétrico pois os bancos irão remeter valores ao banco de origem. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modo de distribuição para outras classes de carga: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"simetrico" significa que aproximadamente a mesma quantidade de carga será enviada da estação A para estação B assim como da B para a A. "asimetrico" significa que o arbitrario dessa carga pode ser enviada em qualquer direção. "manual" significa que nenhuma distribuição automática ocorrerá para essa carga. Provavelmente será melhor definir como "assimétrico" ou manual. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Assimétrico" significa que quantidades arbitrárias de carga podem ser enviadas em qualquer direção. "Manual" significa que nenhuma distribuição automática ocorrerá para essas cargas. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimétrico @@ -2038,7 +2030,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Inversão autom STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Permitir que os comboios invertam o sentido de marcha nos sinais, caso estejam à espera muito tempo ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomendado) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recomendado) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Alterar valor @@ -2079,9 +2071,10 @@ STR_INTRO_MULTIPLAYER :{BLACK}Multi-jo STR_INTRO_GAME_OPTIONS :{BLACK}Opções de jogo STR_INTRO_HIGHSCORE :{BLACK}Tabela de classificações STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Definições -STR_INTRO_NEWGRF_SETTINGS :{BLACK}Definições NewGRF +STR_INTRO_NEWGRF_SETTINGS :{BLACK}Definições de NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Verificar conteúdo online -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Definições de IA/Script de jogo +STR_INTRO_AI_SETTINGS :{BLACK}Definições de IA +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Definições de Script de Jogo STR_INTRO_QUIT :{BLACK}Sair STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Iniciar um novo jogo. Ctrl+Clique salta a configuração do mapa @@ -2101,7 +2094,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Mostrar STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Mostrar definições STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Mostrar definições de NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Verificar conteúdo novo e actualizado para descarga -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Mostrar definições de IA e de script de jogo +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Mostrar definições de IA +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Mostrar definições de Script de Jogo STR_INTRO_TOOLTIP_QUIT :{BLACK}Sair de 'OpenTTD' STR_INTRO_BASESET :{BLACK}O conjunto de gráficos base seleccionado tem {NUM} sprite{P "" s} em falta. Por favor verifique se existem atualizações para o conjunto. @@ -2131,13 +2125,7 @@ STR_CHEAT_EDIT_MAX_HL :{LTBLUE}Editar STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}Editar altura máxima de montanhas no mapa STR_CHEAT_CHANGE_DATE :{LTBLUE}Alterar data: {ORANGE}{DATE_SHORT} STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Alterar ano actual -STR_CHEAT_SETUP_PROD :{LTBLUE}Activar modificação de valores de produção: {ORANGE}{STRING} - -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Terreno temperado -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Terreno subárctico -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Terreno subtropical -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Terreno terra dos brinquedos +STR_CHEAT_SETUP_PROD :{LTBLUE}Ativar modificação de valores de produção: {ORANGE}{STRING} # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Novo Esquema de Cores @@ -2209,7 +2197,7 @@ STR_FACE_AFRICAN :{BLACK}Africano STR_FACE_SELECT_AFRICAN :{BLACK}Seleccionar Caras Africanas STR_FACE_YES :Sim STR_FACE_NO :Não -STR_FACE_MOUSTACHE_EARRING_TOOLTIP :{BLACK}Activar bigode ou brinco +STR_FACE_MOUSTACHE_EARRING_TOOLTIP :{BLACK}Ativar bigode ou brinco STR_FACE_HAIR :Cabelo: STR_FACE_HAIR_TOOLTIP :{BLACK}Mudar cabelo STR_FACE_EYEBROWS :Sobrancelhas: @@ -2217,7 +2205,7 @@ STR_FACE_EYEBROWS_TOOLTIP :{BLACK}Mudar so STR_FACE_EYECOLOUR :Cor dos olhos: STR_FACE_EYECOLOUR_TOOLTIP :{BLACK}Mudar cor dos olhos STR_FACE_GLASSES :Óculos: -STR_FACE_GLASSES_TOOLTIP :{BLACK}Activar óculos +STR_FACE_GLASSES_TOOLTIP :{BLACK}Ativar óculos STR_FACE_GLASSES_TOOLTIP_2 :{BLACK}Mudar óculos STR_FACE_NOSE :Nariz: STR_FACE_NOSE_TOOLTIP :{BLACK}Mudar nariz @@ -2371,7 +2359,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nova empresa) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Criar uma nova empresa e juntar-se a ela STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Este é você STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Este é o anfitrião do jogo -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s} / {NUM} companhi{P a as} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s} - {NUM}/{NUM} companhi{P a as} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}O número de clientes ligados atualmente, número de empresas e número máximo de empresas permitido pelo administrador do servidor # Matches ConnectionType ###length 5 @@ -2498,13 +2487,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :esperando pela STR_NETWORK_MESSAGE_CLIENT_LEAVING :a sair STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} entrou no jogo -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} entrou no jogo (Cliente #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} entrou na empresa #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} entrou no jogo (Client #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} entrou na empresa #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} entrou como espectador -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} iniciou uma nova empresa (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} deixou o jogo ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} iniciou uma nova empresa (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} deixou o jogo ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} mudou o nome para {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} deu {2:CURRENCY_LONG} a {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} deu {2:CURRENCY_LONG} a {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}O servidor fechou a sessão STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}O servidor está a reiniciar...{}Por favor espere... STR_NETWORK_MESSAGE_KICKED :*** {STRING} foi expulso. Motivo: ({STRING}) @@ -2618,6 +2607,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}saturado STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}sobrecarregado +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} a ser transportado mensalmente de {STATION} para {STATION} ({COMMA}% da capacidade){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} a ser transportado de volta ({COMMA}% da capacidade) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Tempo médio de viagem: {NUM}{NBSP}dia{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Exibir área de cobertura STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Não @@ -2626,6 +2620,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Não exi STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Exibir área de cobertura do sítio proposto STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Aceita: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Fornecimentos: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Custo de manutenção: {GOLD}{CURRENCY_SHORT}/ano # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Juntar estação @@ -2708,8 +2703,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Aumentar STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Seleccione Ponte Ferroviária STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Seleccionar Ponte Rodoviária STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Selecção de ponte - clique na ponte desejada para a construir -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Suspensa, Aço STR_BRIDGE_NAME_GIRDER_STEEL :Viga, Aço STR_BRIDGE_NAME_CANTILEVER_STEEL :Consola, Aço @@ -2733,7 +2730,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Construi STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Construir paragem de eléctricos para passageiros. Ctrl permite juntar estações. Shift alterna contruir/mostrar custo estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Construir área de carregamento de camiões. Ctrl permite juntar estações. Shift alterna contruir/mostrar custo estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Construir paragem de eléctricos para carga. Ctrl permite juntar estações. Shift alterna contruir/mostrar custo estimado -STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Activar/Desactivar estradas de sentido único +STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Ativar/Desativar estradas de sentido único STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Construir ponte de estrada. Shift alterna contruir/mostrar custo estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Construir ponte para eléctricos. Shift alterna contruir/mostrar custo estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Construir túnel de estrada. Shift alterna contruir/mostrar custo estimado @@ -2813,11 +2810,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Terreno STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Baixar terreno. Ao pressionar e arrastar o cursor, o primeiro ponto selecionado é rebaixado e o terreno da área selecionada é nivelado com a nova altura do primeiro ponto. Ctrl seleciona a área na diagonal. Shift mostra a estimativa de custos. STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Elevar terreno. Ao pressionar e arrastar o cursor, o primeiro ponto selecionado é elevado e o terreno da área selecionada é nivelado com a nova altura do primeiro ponto. Ctrl seleciona a área na diagonal. Shift mostra a estimativa de custos. STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Nívelar uma área de terreno até a altura do primeiro ponto selecionado. Ctrl selecciona a área na diagonal. Shift mostra a estimativa de custos. -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreno para uso futuro. Shift mostra a estimativa de custos. +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreno para uso futuro. Ctrl seleciona a área diagonalmente. Shift alterna entre construir/mostrar custo estimado # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Selecção de Objecto -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Seleccionar objecto para construir. Shift alterna construir/mostrar custo estimado +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selecionar objeto para construir. Ctrl seleciona a área diagonalmente. Shift alterna construir/mostrar custo estimado STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Selecionar a classe do objecto a construir STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Pré-visualização do objecto STR_OBJECT_BUILD_SIZE :{BLACK}Tamanho: {GOLD}{NUM} x {NUM} quadrados @@ -2829,7 +2826,7 @@ STR_OBJECT_CLASS_TRNS :Transmissores STR_PLANT_TREE_CAPTION :{WHITE}Árvores STR_PLANT_TREE_TOOLTIP :{BLACK}Escolha um tipo de árvore para plantar. Se o quadrado já tiver uma árvore, serão adicionadas mais árvores de difrentes tipos independentemente do tipo selecionado STR_TREES_RANDOM_TYPE :{BLACK}Árvores de tipo aleatório -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Colocar árvores de tipo aleatório. Shift alterna construir/mostrar custo estimado +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Plantar árvores de tipo aleatório. "Ctrl" seleciona a área na diagonal. "Shift" alterna construir/mostrar custo estimado STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Plantar aleatoriamente STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plantar árvores aleatoriamente no terreno STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2861,6 +2858,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Localida STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Fundar uma localidade num local aleatório STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Várias localidades aleatórias STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cobrir o mapa com localidades colocadas aleatoriamente +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Expandir todas as localidades +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Fazer com que todas as localidades cresçam ligeiramente STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nome da localidade: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Introduza o nome da localidade @@ -2893,7 +2892,7 @@ STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP :{BLACK}Cobrir o STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_CAPTION :{WHITE}Criar indústrias aleatórias STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_QUERY :{YELLOW}Tem a certeza que deseja criar muitas indústrias aleatórias? STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST :{BLACK}Custo: {YELLOW}{CURRENCY_LONG} -STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY :{BLACK}Prospectar +STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY :{BLACK}Prospetar STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY :{BLACK}Construir STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY :{BLACK}Criar STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES :{BLACK}Remover todas as indústrias @@ -3081,9 +3080,9 @@ STR_FRAMERATE_DRAWING :{BLACK}Renderiz STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Janelas de exibição do mundo: STR_FRAMERATE_VIDEO :{BLACK}Saída de video: STR_FRAMERATE_SOUND :{BLACK}Mistura de Som: -STR_FRAMERATE_ALLSCRIPTS :{BLACK} GS/AI total: +STR_FRAMERATE_ALLSCRIPTS :{BLACK} SJ/IA total: STR_FRAMERATE_GAMESCRIPT :{BLACK} Script de jogo: -STR_FRAMERATE_AI :{BLACK} AI {NUM} {STRING} +STR_FRAMERATE_AI :{BLACK} IA {NUM} {STRING} ###length 15 STR_FRAMETIME_CAPTION_GAMELOOP :Loop de jogo @@ -3100,7 +3099,7 @@ STR_FRAMETIME_CAPTION_VIDEO :Saída de video STR_FRAMETIME_CAPTION_SOUND :Mistura de Som STR_FRAMETIME_CAPTION_ALLSCRIPTS :total scripts GS/AI STR_FRAMETIME_CAPTION_GAMESCRIPT :Script de jogo -STR_FRAMETIME_CAPTION_AI :AI {NUM} {STRING} +STR_FRAMETIME_CAPTION_AI :IA {NUM} {STRING} # Save/load game/scenario @@ -3125,7 +3124,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalhes STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Nenhuma informação disponível STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtro de sequência: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtro: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Substituir Ficheiro STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Tem a certeza que deseja substituir o ficheiro existente? STR_SAVELOAD_DIRECTORY :{STRING} (Diretório) @@ -3139,6 +3138,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Dim. do STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Seleccionar o tamanho do mapa em mosaicos. O numero de mosaicos disponiveis será ligeiramente menor STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Num. de localidades: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nomes das localidades: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Seleccionar o estilo dos nomes das localidades STR_MAPGEN_DATE :{BLACK}Data: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Num. de indústrias: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Pico mais alto: @@ -3152,13 +3153,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Cobertur STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Aumentar a cobertura do deserto em dez por cento STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Diminuir a cobertura do deserto em dez por cento STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Criação do terreno: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tipo de terreno: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Nível do mar: +STR_MAPGEN_SEA_LEVEL :{BLACK}Nível do mar: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Rios: STR_MAPGEN_SMOOTHNESS :{BLACK}Suavidade: STR_MAPGEN_VARIETY :{BLACK}Variedade da distribuição: STR_MAPGEN_GENERATE :{WHITE}Gerar +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Definições de NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Mostrar definições de NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Definições de IA +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Mostrar definições de IA +STR_MAPGEN_GS_SETTINGS :{BLACK}Definições de Script de Jogo +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Mostrar definições de script de jogo + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Inglês +STR_MAPGEN_TOWN_NAME_FRENCH :Francês +STR_MAPGEN_TOWN_NAME_GERMAN :Alemão +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Inglês (Adicional) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latino-Americano +STR_MAPGEN_TOWN_NAME_SILLY :Absurdo +STR_MAPGEN_TOWN_NAME_SWEDISH :Sueco +STR_MAPGEN_TOWN_NAME_DUTCH :Holandês +STR_MAPGEN_TOWN_NAME_FINNISH :Finlandês +STR_MAPGEN_TOWN_NAME_POLISH :Polaco +STR_MAPGEN_TOWN_NAME_SLOVAK :Eslovaco +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norueguês +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Húngaro +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austríaco +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romeno +STR_MAPGEN_TOWN_NAME_CZECH :Checo +STR_MAPGEN_TOWN_NAME_SWISS :Suíço +STR_MAPGEN_TOWN_NAME_DANISH :Dinamarquês +STR_MAPGEN_TOWN_NAME_TURKISH :Turco +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiano +STR_MAPGEN_TOWN_NAME_CATALAN :Catalão # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Limites do mapa: @@ -3214,10 +3243,10 @@ STR_GENERATION_PREPARING_GAME :{BLACK}A prepar # NewGRF settings STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Definições NewGRF STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Informação detalhada do NewGRF -STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Ficheiros NewGRF activos -STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Ficheiros NewGRF inactivos +STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Ficheiros NewGRF ativos +STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Ficheiros NewGRF inativos STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Seleccionar predefinição: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtro de sequência: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtro: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Carrega a predefinição seleccionada STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Guardar STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Guarda a lista numa predefinição @@ -3261,7 +3290,7 @@ STR_NEWGRF_SETTINGS_PARAMETER_NONE :Nenhum STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}Sem informação disponível STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}Ficheiro correspondente não encontrado -STR_NEWGRF_SETTINGS_DISABLED :{RED}Desactivado +STR_NEWGRF_SETTINGS_DISABLED :{RED}Desativado STR_NEWGRF_SETTINGS_INCOMPATIBLE :{RED}Incompatível com esta versão do OpenTTD # NewGRF save preset window @@ -3275,7 +3304,7 @@ STR_SAVE_PRESET_SAVE :{BLACK}Grava STR_SAVE_PRESET_SAVE_TOOLTIP :{BLACK}Grava a predefinição com o nome seleccionado # NewGRF parameters window -STR_NEWGRF_PARAMETERS_CAPTION :{WHITE}Alterar parâmetros NewGRF +STR_NEWGRF_PARAMETERS_CAPTION :{WHITE}Alterar parâmetros de NewGRF STR_NEWGRF_PARAMETERS_CLOSE :{BLACK}Fechar STR_NEWGRF_PARAMETERS_RESET :{BLACK}Repor STR_NEWGRF_PARAMETERS_RESET_TOOLTIP :{BLACK}Retorna todos os parâmetros ao seu valor padrão @@ -3304,6 +3333,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Gráfico STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Proceder ao gráfico normal anterior, ignorando quaisquer gráficos pseudo/recolorir/tipo-de-letra e dando a volta no início STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representação do gráfico seleccionado actualmente. O alinhamento é ignorado a desenhar este gráfico STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Desloca o gráfico, alterando os intervalos X e Y. Ctrl+Clique desloca o gráfico 8 unidades de uma só vez + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Deslocamento centrado +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centrado + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Mira + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Repor relativo STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Repor intervalos relativos atuais STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Intervalo X: {NUM}, Intervalo Y: {NUM} (Absoluto) @@ -3318,18 +3354,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Aviso: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Erro: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Ocorreu um erro fatal num NewGRF:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Ocorreu um erro de NewGRF:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}O NewGRF "{STRING}" retornou um erro fatal:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}O NewGRF "{STRING}" retornou um erro fatal:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} não funciona com a versão do TTDPatch reportada por OpenTTD. -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} é para a versão {STRING} do TTD. -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} foi concebido para ser usado com {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Parâmetro inválido para {1:STRING}: parâmetro {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} deve ser carregado antes do {STRING}. -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} deve ser carregado depois do {STRING}. -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requer a versão {STRING} ou superior do OpenTTD. +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} é para a versão {2:STRING} do TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} foi concebido para ser usado com {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Parâmetro inválido para {1:STRING}: parâmetro {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} deve ser carregado antes de {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} deve ser carregado depois de {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requer OpenTTD versão {2:STRING} ou superior STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :ficheiro GRF concebido para o traduzir STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Demasiados NewGRFs carregados. -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Carregar {1:STRING} como NewGRF estático com {STRING} pode causar dessincronização. +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Carregar {1:STRING} como NewGRF estático com {2:STRING} pode causar dessincronização STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Gráfico inválido (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Propriedade Action 0 desconhecida {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Tentativa de uso de ID Inválido (sprite {3:NUM}) @@ -3337,7 +3373,7 @@ STR_NEWGRF_ERROR_CORRUPT_SPRITE :{YELLOW}{STRING STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Contém múltiplas entradas Action 8 - (sprite {3:NUM}) STR_NEWGRF_ERROR_READ_BOUNDS :Leitura além dos limites do pseudo-sprite (sprite {3:NUM}) STR_NEWGRF_ERROR_GRM_FAILED :Recursos GRF pedidos não disponíveis (sprite {3:NUM}) -STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} foi desactivado por {STRING} +STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} foi desativado por {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Formato de Gráfico Inválido ou desconhecido (sprite {3:NUM}) STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Demasiados elementos na lista de valores de propriedade (sprite {3:NUM}, propriedade {4:HEX}) STR_NEWGRF_ERROR_INDPROD_CALLBACK :Revogação da produção industrial inválida (sprite {3:NUM}, "{2:STRING}") @@ -3351,7 +3387,7 @@ STR_NEWGRF_COMPATIBLE_LOADED :{ORANGE}Ficheir STR_NEWGRF_TOO_MANY_NEWGRFS :{WHITE}Impossivel adicionar ficheiro: alcançado limite de ficheiros NewGRF STR_NEWGRF_COMPATIBLE_LOAD_WARNING :{WHITE}GRF(s) compatíveis carregados para ficheiros em falta -STR_NEWGRF_DISABLED_WARNING :{WHITE}Ficheiro(s) GRF em falta foram desactivados +STR_NEWGRF_DISABLED_WARNING :{WHITE}Ficheiro(s) GRF em falta foram desativados STR_NEWGRF_UNPAUSE_WARNING_TITLE :{YELLOW}Ficheiro(s) GRF em falta STR_NEWGRF_UNPAUSE_WARNING :{WHITE}Sair da pausa pode causar problemas ao OpenTTD. Não envie informações sobre este tipo de problemas.{}Deseja realmente sair da pausa? @@ -3461,14 +3497,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Comprar exclusi STR_LOCAL_AUTHORITY_ACTION_BRIBE :Subornar a autoridade local ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Iniciar uma campanha local publicitária pequena, para atrair mais passageiros e carga à sua empresa.{}Providencia um incremento temporário na avaliação das estações num raio pequeno à volta do centro da localidade.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Iniciar uma campanha local publicitária média, para atrair mais passageiros e carga à sua empresa.{}Providencia um incremento temporário na avaliação das estações num raio médio à volta do centro da localidade.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Iniciar uma campanha local publicitária grande, para atrair mais passageiros e carga à sua empresa.{}Providencia um incremento temporário na avaliação das estações num raio grande à volta do centro da localidade.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Financiar a reconstrução da rede rodoviária urbana.{}Causa engarrafamentos consideráveis ao tráfego rodoviário até 6 meses.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Construir uma estátua em honra da sua empresa.{}Providencia um incremento permanente na avaliação das estações nesta localidade.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Financiar a construção de novos edifícios na localidade.{}Providencia um incremento temporário no crescimento desta localidade.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Comprar 1 ano de direitos exclusivos de transportes nesta localidade.{}A autoridade local não permitirá que os passageiros e a carga usem as estações dos seus concorrentes.{}Custo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Subornar a autoridade local para aumentar a sua avaliação, correndo o risco de uma penalidade severa se apanhado.{}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniciar uma campanha local publicitária pequena, para atrair mais passageiros e carga à sua empresa.{}Providencia um incremento temporário na avaliação das estações num raio pequeno à volta do centro da localidade.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniciar uma campanha local publicitária média, para atrair mais passageiros e carga à sua empresa.{}Providencia um incremento temporário na avaliação das estações num raio médio à volta do centro da localidade.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniciar uma campanha local publicitária grande, para atrair mais passageiros e carga à sua empresa.{}Providencia um incremento temporário na avaliação das estações num raio grande à volta do centro da localidade.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Financiar a reconstrução da rede rodoviária urbana.{}Causa engarrafamentos consideráveis ao tráfego rodoviário até 6 meses.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Construir uma estátua em honra da sua empresa.{}Providencia um incremento permanente na avaliação das estações nesta localidade.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Financiar a construção de novos edifícios na localidade.{}Providencia um incremento temporário no crescimento desta localidade.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Comprar 1 ano de direitos exclusivos de transportes nesta localidade.{}A autoridade local não permitirá que os passageiros e a carga usem as estações dos seus concorrentes.{}{POP_COLOUR}Custo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Subornar a autoridade local para aumentar a sua avaliação, correndo o risco de uma penalidade severa se for apanhado.{}{POP_COLOUR}Custo: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Objectivos @@ -3641,15 +3677,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Navios STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Juros do Empréstimo STR_FINANCES_SECTION_OTHER :{GOLD}Outros +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Lucro Líquido +STR_FINANCES_PROFIT :{WHITE}Lucro STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Balanço bancário STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Fundos Próprios STR_FINANCES_LOAN_TITLE :{WHITE}Empréstimo STR_FINANCES_INTEREST_RATE :{WHITE}Juro do Empréstimo: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Empréstimo Máximo: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Pedir empréstimo {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Aumentar empréstimo. Ctrl+Clique aumenta tanto empréstimo quanto possível STR_FINANCES_REPAY_BUTTON :{BLACK}Pagar empréstimo {CURRENCY_LONG} @@ -3750,7 +3789,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produz: STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Requer: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} a aguardar{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Modificar produção (múltiplo de 8, até 2040) @@ -3780,6 +3819,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Enviar i STR_VEHICLE_LIST_REPLACE_VEHICLES :Substituir Veículos STR_VEHICLE_LIST_SEND_FOR_SERVICING :Enviar para Serviço STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Lucro deste ano: {CURRENCY_LONG} (último ano: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Enviar para Depósito STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Enviar para Depósito @@ -3871,6 +3912,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Máx. Fo STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Alcance: {GOLD}{COMMA} quadrados STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipo de aeronave: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Todos os tipos de carga +STR_CARGO_TYPE_FILTER_FREIGHT :Mercadorias +STR_CARGO_TYPE_FILTER_NONE :Nenhum + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Lista de veículos ferroviários - clique num veículo para informações STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Lista de veículos rodoviários - clique num veículo para informações @@ -4039,7 +4085,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :aeronave STR_ENGINE_PREVIEW_SHIP :navio STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Custo: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocidade Máx.: {VELOCITY} Potência: {POWER}{}Custo de Circulação: {CURRENCY_LONG}/ano{}Capacidade: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Custo: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocidade Máx.: {VELOCITY} Potência: {POWER} F.T. Máx.: {6:FORCE}{}Custo de Circulação: {4:CURRENCY_LONG}/ano{}Capacidade: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Custo: {0:CURRENCY_LONG} Peso: {1:WEIGHT_SHORT}{}Velocidade: {2:VELOCITY} Potência: {3:POWER} Tração Máx: {6:FORCE}{}Custo de Circulação: {4:CURRENCY_LONG}/ano{}Capacidade: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Velocidade Máx.: {VELOCITY}{}Capacidade: {CARGO_LONG}{}Custo de Circulação: {CURRENCY_LONG}/ano STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Velocidade Máx.: {VELOCITY}{}Tipo de Aeronave: {STRING}{}Capacidade: {CARGO_LONG}, {CARGO_LONG}{}Custo de Circulação: {CURRENCY_LONG}/ano STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Velocidade Máx.: {VELOCITY}{}Tipo de Aeronave: {STRING}{}Capacidade: {CARGO_LONG}{}Custo de Circulação: {CURRENCY_LONG}/ano @@ -4081,7 +4127,7 @@ STR_REPLACE_ALL_ROADTYPE :Todos os veícu ###length 2 STR_REPLACE_HELP_RAILTYPE :{BLACK}Selecione o tipo de carril para o qual deseja efectuar a substituição dos motores -STR_REPLACE_HELP_ROADTYPE :BLACK}Selecione o tipo de estrada para o qual deseja efectuar a substituição dos motores +STR_REPLACE_HELP_ROADTYPE :{BLACK}Selecione o tipo de estrada para o qual deseja efectuar a substituição dos motores ###next-name-looks-similar STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Exibe o tipo de motor que substituirá o que está seleccionado à esquerda, se algum @@ -4198,12 +4244,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {L STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potência: {LTBLUE}{POWER}{BLACK} Velocidade máx.: {LTBLUE}{VELOCITY} {BLACK}Tração Máx.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucro neste ano: {LTBLUE}{CURRENCY_LONG} (último ano: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Lucro deste ano: {LTBLUE}{CURRENCY_LONG} (último ano: {CURRENCY_LONG}) {BLACK}Performance min.: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidade: {LTBLUE}{COMMA}% {BLACK}Avarias desde o último serviço: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacidade: {LTBLUE}Nenhuma{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidade: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacidade: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Créditos de Transferência: {LTBLUE}{CURRENCY_LONG} @@ -4362,7 +4409,7 @@ STR_ORDER_GO_TO_NEAREST_DEPOT :Ir para o depó STR_ORDER_GO_TO_NEAREST_HANGAR :Ir para o hangar mais próximo STR_ORDER_CONDITIONAL :Saltar ordem condicional STR_ORDER_SHARE :Partilhar ordens -STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Inserir nova ordem antes da ordem seleccionada, ou adicionar ao fim da lista. Ctrl torna em 'encher' as ordens em estações, em 'sem parar' as ordens de pontos de passagem e em 'serviço' as ordens em depósitos. 'Ordens Partilhadas' ou Ctrl permite que este veículos partilhe ordens com o veículo escolhido. Clicando em um veículo de copia as ordens desse veículo +STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Inserir nova ordem antes da ordem selecionada, ou adicionar ao fim da lista. Ctrl torna as ordens de estações em 'encher completamente qualquer carga'; as ordens em pontos de passagem 'sem parar'; e ordens de depósitos 'serviço'. 'Partilhar ordens' ou Ctrl permite que este veículo partilhe ordens com o veículo selecionado. Clicar num veículo copia as ordens desse veículo. Uma ordem para depósito desativa a manutenção programada (serviço) do veículo. STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Mostra todos os veículos que seguem este mesmo trajecto @@ -4472,22 +4519,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Data de STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Selecione uma data como ponto de partida deste horário. Ctrl+Clique distribui uniformemente todos os veiculos partilhando esta ordem pela sua ordem relativa, se a ordem for completamente calendarizada STR_TIMETABLE_CHANGE_TIME :{BLACK}Mudar Tempo -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Muda o espaço de tempo que a ordem seleccionada deve durar +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Mudar a duração do tempo que a ordem selecionada deve durar. Ctrl+Clique define o tempo para todas as ordens STR_TIMETABLE_CLEAR_TIME :{BLACK}Apagar Tempo -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Apagar o tempo que dura a ordem seleccionada +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Limpar a duração do tempo da ordem selecionada. Ctrl+Clique limpa os tempos para todas as ordens STR_TIMETABLE_CHANGE_SPEED :{BLACK}Alterar limite de velocidade -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Mudar a velocidade maxima durante a viagem da ordem selecionada +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Mudar a velocidade máxima durante a viagem da ordem selecionada. Ctrl+Clique define a velocidade para todas as ordens STR_TIMETABLE_CLEAR_SPEED :{BLACK}Remover limite de velocidade -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Limpar a velocidade maxima durante a viagem da ordem selecionada +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Limpar a velocidade máxima de viagem da ordem selecionada. Ctrl+Clique limpa as velocidades para todas as ordens. STR_TIMETABLE_RESET_LATENESS :{BLACK}Apagar Contador Atraso -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Limpar o contador de atraso, para que o veículo passe a estar a horas +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Limpar o contador de atraso, para que o veículo esteja pontual. Ctrl+Click reiniciará o grupo todo, para que o último veículo esteja pontual e todos os outros estejam antecipados. STR_TIMETABLE_AUTOFILL :{BLACK}Auto preencher -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Preencher o horário automaticamente com os valores da próxima viagem (CTRL-clique para tentar manter os tempos de espera) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Preencher o horário automaticamente com os valores da próxima viagem. Ctrl+Clique para tentar manter os tempos de espera. STR_TIMETABLE_EXPECTED :{BLACK}Esperado STR_TIMETABLE_SCHEDULED :{BLACK}Marcado @@ -4531,12 +4578,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Houve um STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}A janela de Depuração de IA/Scripts de jogo está disponível apenas para o servidor # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Configuração IA/Script de jogo +STR_AI_CONFIG_CAPTION_AI :{WHITE}Configuração de IA +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Configuração de Script de Jogo STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}O Script de jogo que será carregado no próximo jogo STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}As IAs que serão carregadas no próximo jogo STR_AI_CONFIG_HUMAN_PLAYER :Jogador humano STR_AI_CONFIG_RANDOM_AI :IA aleatória STR_AI_CONFIG_NONE :(nenhum) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Número máximo de oponentes: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Mover para cima STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Move a IA seleccionada para cima @@ -4544,12 +4593,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Mover pa STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Move a IA seleccionada para baixo STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script de jogo +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parâmetros STR_AI_CONFIG_AI :{SILVER}IAs -STR_AI_CONFIG_CHANGE :{BLACK}Selecionar {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :IA -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script de jogo +STR_AI_CONFIG_CHANGE_AI :{BLACK}Selecionar IA +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Selecionar Script de Jogo STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carregar outro script STR_AI_CONFIG_CONFIGURE :{BLACK}Configurar STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configurar os parâmetros do script @@ -4577,10 +4625,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Mapa com STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Mapa de alturas STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minimap screenshot -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parâmetros STR_AI_SETTINGS_CAPTION_AI :IA -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script de jogo +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script de Jogo STR_AI_SETTINGS_CLOSE :{BLACK}Fechar STR_AI_SETTINGS_RESET :{BLACK}Repor STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4744,6 +4792,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... dema STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Não é possível gerar indústrias... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Não é possível construir {STRING} aqui... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Não é possível construir este tipo de indústria aqui... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Não é possível prospetar indústria... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... muito perto de outra indústria STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... é necessário construir uma localidade primeiro STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... só é permitido uma por localidade @@ -4758,6 +4807,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... a fl STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... só se pode construir acima da linha da neve STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... só se pode construir abaixo da linha da neve +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}O financiamento falhou em prospetar devido ao azar; tente novamente +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Não havia locais adequados para prospetar esta indústria STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Não foram encontrados locais adequados para '{STRING}' indústrias STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Altera os parâmetros de geração do mapa para obter um mapa melhor @@ -4766,7 +4817,7 @@ STR_ERROR_CAN_T_BUILD_RAILROAD_STATION :{WHITE}Não é STR_ERROR_CAN_T_BUILD_BUS_STATION :{WHITE}Não é possível construir estação de autocarros... STR_ERROR_CAN_T_BUILD_TRUCK_STATION :{WHITE}Não é possível construir estação de carregamento de camiões... STR_ERROR_CAN_T_BUILD_PASSENGER_TRAM_STATION :{WHITE}Não é possível construir estação de passageiros para eléctricos... -STR_ERROR_CAN_T_BUILD_CARGO_TRAM_STATION :{WHITE}Não é possível construir estação de carga para eléctricos... +STR_ERROR_CAN_T_BUILD_CARGO_TRAM_STATION :{WHITE}Não é possível construir estação de carga para elétricos... STR_ERROR_CAN_T_BUILD_DOCK_HERE :{WHITE}Não é possível construir doca aqui... STR_ERROR_CAN_T_BUILD_AIRPORT_HERE :{WHITE}Não é possível construir aeroporto aqui... @@ -4790,7 +4841,7 @@ STR_ERROR_MUST_REMOVE_RAILWAY_STATION_FIRST :{WHITE}É preci STR_ERROR_CAN_T_REMOVE_BUS_STATION :{WHITE}Impossível remover estação... STR_ERROR_CAN_T_REMOVE_TRUCK_STATION :{WHITE}Impossível remover estação... STR_ERROR_CAN_T_REMOVE_PASSENGER_TRAM_STATION :{WHITE}Impossível remover paragem de eléctricos de passageiros -STR_ERROR_CAN_T_REMOVE_CARGO_TRAM_STATION :{WHITE}Impossível remover estação de eléctricos de mercadorias... +STR_ERROR_CAN_T_REMOVE_CARGO_TRAM_STATION :{WHITE}Impossível remover estação de elétricos de mercadorias... STR_ERROR_MUST_REMOVE_ROAD_STOP_FIRST :{WHITE}Deverá remover a paragem rodoviária primeiro STR_ERROR_THERE_IS_NO_STATION :{WHITE}... não há nenhuma estação aqui @@ -4798,7 +4849,7 @@ STR_ERROR_MUST_DEMOLISH_RAILROAD :{WHITE}Precisa STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST :{WHITE}Precisa de demolir a estação de autocarros primeiro STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST :{WHITE}Precisa de demolir a estação de carga primeiro STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST :{WHITE}Precisa demolir estação de eléctricos primeiro -STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST :{WHITE}Precisa demolir estação de eléctricos primeiro +STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST :{WHITE}Precisa demolir estação de elétricos primeiro STR_ERROR_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Deverá demolir a doca primeiro STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Precisa de demolir o aeroporto primeiro @@ -4925,6 +4976,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objecto STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... sede de empresa no caminho STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Não é possível comprar esta área de terreno... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... já a possui! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... atingido o limite de construção de objeto # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Impossível criar grupo... @@ -4997,6 +5049,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Não é STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... o veículo está destruido +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... nem todos os veículos são idênticos + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Nenhum veículo estará disponível STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Mudar a sua configuração NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Nenhum veículo ainda disponível @@ -5023,6 +5077,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Impossí STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... veiculo não pode ir a todas as estações STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... veiculo não pode ir a essa estação STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... um veículo a partilhar esta ordem não pode ir a essa estação +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... nem todos os veículos têm as mesmas ordens +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... nem todos os veículos estão a partilhar ordens STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Não é possível partilhar a lista de ordens... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Impossível parar de partilhar a lista de ordens... @@ -5030,6 +5086,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Não é STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... muito distante do destino anterior STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... o avião não tem alcance suficiente +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Não existe estação ferroviária +STR_ERROR_NO_BUS_STATION :{WHITE}Não existe paragem de autocarro +STR_ERROR_NO_TRUCK_STATION :{WHITE}Não existe estação de camiões +STR_ERROR_NO_DOCK :{WHITE}Não existe doca +STR_ERROR_NO_AIRPORT :{WHITE}Não existe aeroporto/heliporto +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Não existem paragens com tipo de estrada compatível +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Não existem paragens compatíveis com o tipo de elétrico +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Não existem paragens adequadas para veículos rodoviários articulados.{}Os veículos rodoviários articulados requerem paragens de rua, e não paragens em becos/terminais +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Este avião não pode aterrar neste heliporto +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Este helicóptero não pode aterrar neste aeroporto +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Não existe ponto de passagem ferroviário +STR_ERROR_NO_BUOY :{WHITE}Não existe bóia + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Impossível programar veículo... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Veículos apenas podem esperar em estações. diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index d7e536a8360f4..36b2f63fa8c79 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}cp STR_UNITS_POWER_METRIC :{COMMA}cp STR_UNITS_POWER_SI :{COMMA}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}cp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}cp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}cp/kg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}cp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}cp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}cp/kg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -226,8 +236,8 @@ STR_UNITS_HEIGHT_SI :{COMMA} m # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Filtru: -STR_LIST_FILTER_OSKTITLE :{BLACK}Filtru -STR_LIST_FILTER_TOOLTIP :{BLACK}Introduceți un cuvânt-cheie pentru filtrarea listei +STR_LIST_FILTER_OSKTITLE :{BLACK}Introduceți unul sau mai multe cuvinte cheie pentru a filtra lista +STR_LIST_FILTER_TOOLTIP :{BLACK}Introduceți unul sau mai multe cuvinte cheie pentru a filtra lista STR_TOOLTIP_GROUP_ORDER :{BLACK}Selectează ordinea de grupare STR_TOOLTIP_SORT_ORDER :{BLACK}Alegeți ordinea de sortare (ascendentă/descendentă) @@ -376,9 +386,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Generare STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Generare industrii STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Construcţii rutiere STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Construcție tramvai -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantează arbori. Shift comută între plantare/afişare cost estimat +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantează arbori. Ctrl selectează zona în diagonală. Shift comută între plantare/afişare cost estimat STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Plasează semn -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Amplasează obiect. Shift comută între amplasare/afişare cost estimat +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Plasați obiectul. Ctrl selectează zona în diagonală. Shift comută construirea/afișarea estimării costurilor # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Ieşire din joc # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Opţiunile jocului STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Setări -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Setări IA / Script Joc +STR_SETTINGS_MENU_AI_SETTINGS :Setările AI +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Setări pentru scriptul jocului STR_SETTINGS_MENU_NEWGRF_SETTINGS :Setări NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opţiuni transparenţă STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Afişează numele oraşelor @@ -855,7 +866,7 @@ STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL :{BIG_FONT}{BLAC STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_COAL :{BIG_FONT}{BLACK}Rezerve noi de cărbune la {INDUSTRY}!{}Se preconizează dublarea producţiei! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_OIL :{BIG_FONT}{BLACK}Rezerve noi de petrol la {INDUSTRY}!{}Se preconizează dublarea producţiei! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM :{BIG_FONT}{BLACK}Noile tehnologii folosite la {INDUSTRY} vor aduce dublarea producţiei! -STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH :{BIG_FONT}{BLACK}Producţia de {STRING} de la {INDUSTRY} creste cu {COMMA}%! +STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH :{BIG_FONT}{BLACK}Producţia de {STRING} de la {INDUSTRY} crește cu {COMMA}%! STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL :{BIG_FONT}{BLACK}{INDUSTRY} scade producţia cu 50% STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM :{BIG_FONT}{BLACK}Insectele cauzează distrugeri masive la {INDUSTRY}!{}Producţia scade cu 50% STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH :{BIG_FONT}{BLACK}Producţia de {STRING} de la {INDUSTRY} scade cu {COMMA}%! @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rupia Indiană STR_GAME_OPTIONS_CURRENCY_IDR :Rupia indoneziană (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit Malaysian (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Pe partea stângă -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Pe partea dreaptă - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Numele orașelor: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Alege naţionalitatea numelor oraşelor - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Englezeşti (Original) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Franţuzeşti -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Nemţeşti -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Englezeşti (Adiţional) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latino-Americane -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Amuzante -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Suedeze -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Olandeze -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandeze -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Poloneze -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovace -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norvegiene -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungureşti -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austriece -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Româneşti -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Ceheşti -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Elveţiene -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Daneze -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turceşti -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italieneşti -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalană - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Salvare automată STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Alege intervalul de timp dintre salvările automate @@ -1025,22 +1006,21 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Setarea STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Bifați această căsuță pentru sincronizarea verticală a imaginii. Modificarea setării va fi aplicată doar după repornirea jocului și funcționează doar cu accelerarea hardware activată +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Driver curent: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Mărime interfată -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Alege mărimea elementelor de interfaţa +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Dimensiune interfaţă +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Trageți glisorul pentru a seta dimensiunea interfeței. Țineți apăsat Ctrl pentru ajustare continuă +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Detectează automat dimensiunea +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Bifați această căsuţă pentru a detecta automat dimensiunea interfeței -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(auto-detecție) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normală -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Mărime dublă -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Mărime cvadruplă +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Scalează marginile +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Bifați această casetă pentru a scala marginile în funcție de dimensiunea interfeței -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Dimensiune font -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Alege dimensiunea fontului pentru interfață - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(auto-detecție) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Mărime dublă -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Mărime cvadruplă +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafică @@ -1092,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Previzu STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 de Lire sterline (£) în moneda proprie STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Schimbă un parametru al monedei proprii -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Numărul maxim de companii concurente: {ORANGE}{COMMA} - STR_NONE :Nimic STR_FUNDING_ONLY :Doar finanțare STR_MINIMAL :Minim @@ -1143,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :peisajul temperat +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :peisajul sub-arctic +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :peisajul sub-tropical +STR_CLIMATE_TOYLAND_LANDSCAPE :peisajul 'ţara jucăriilor' + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Foarte plat STR_TERRAIN_TYPE_FLAT :Plat @@ -1220,8 +1204,11 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_LEFT :stânga STR_CONFIG_SETTING_HORIZONTAL_POS_CENTER :centru STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :dreapta -STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Valoarea maximă a împrumutului initial: {STRING} +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Valoarea maximă a împrumutului inițial: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Valoarea maximă pe care o companie o poate împrumuta (fără a ține cont de inflație) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Niciun împrumut {RED}Necesită un script de joc pentru oferirea fondurilor inițiale STR_CONFIG_SETTING_INTEREST_RATE :Rata dobânzii: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Rata dobânzii; de asemenea controlează inflația dacă este activată @@ -1318,7 +1305,7 @@ STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH :Lungimea maxim STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT :Lungimea maximă pentru construcţia de tuneluri STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD :Metoda manuală de construcţie a industriilor primare: {STRING} -STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :Metoda de finanţare a industriilor primare. 'nici una' înseamnă că nu este posibile să se finanţeze nici una, 'prospectare' înseamnă ca finanţarea este posibilă, dar construcţia se realizează intr-un loc aleator şi poate eşua, 'la fel ca celelalte industrii' inseamnă că industriile de materie primă pot fi construite de către companii la fel ca industriile procesatoare, în orice locaţie doresc +STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :Metoda de finanțare a industriilor primare. „niciuna” înseamnă că nu este posibil să se finanțeze niciuna, „prospectare” înseamnă că finanțarea este posibilă, dar construcția se realizează într-un loc aleator și poate eșua, „la fel ca celelalte industrii” înseamnă că industriile de materie primă pot fi construite de către companii la fel ca industriile procesatoare, în orice locație doresc ###length 3 STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NONE :niciuna STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NORMAL :ca alte industrii @@ -1448,6 +1435,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Grosimea liniil STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Afișează numele NewGRF în fereastra de construcție a vehiculului: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Adaugă o linie în fereastra de construcție a vehiculului, afișând din care NewGRF vine vehiculul selectat. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Afișați mărfurile pe care vehiculele le pot transporta în ferestrele listei {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Dacă este activată, încărcătura transportabilă a vehiculului va apărea deasupra acestuia în listele de vehicule STR_CONFIG_SETTING_LANDSCAPE :Peisaj: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Peisajele definesc scenariile de bază a jocului cu cerințe diferite pentru încărcături și dezvoltare a orașelor. NewGRF și scripturile de joc permit un control mai fin @@ -1502,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Îmbunătăţit STR_CONFIG_SETTING_ROAD_SIDE :Autovehicule: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Alege banda pentru condus +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Pe partea stângă +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Pe partea dreaptă + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotaţie hartă înălţimi: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Spre stânga @@ -1528,7 +1521,13 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Verde STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Verde închis STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Mov +STR_CONFIG_SETTING_LINKGRAPH_COLOURS :Anvelopā de culori pentru flux încārcāturā: {STRING} +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_HELPTEXT :Schemă de culori pentru anvelopă flux încărcătură. ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :Din verde în roșu (original) +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Din verde în albastru +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Din gri în roșu +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :Tonuri de gri STR_CONFIG_SETTING_SCROLLMODE :Comportament derulare vizor: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Comportamentul derulării hărții @@ -1684,16 +1683,16 @@ STR_CONFIG_SETTING_MAX_SHIPS :Nr. max. de nav STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :Numărul maxim de nave pe care o companie le poate deține STR_CONFIG_SETTING_AI_BUILDS_TRAINS :Dezactivează trenurile pentru jucătorii controlaţi de calculator: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Prin activarea acestei opțiuni, jucatorul controlat de calculator nu poate construi trenuri +STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Prin activarea acestei opțiuni, jucătorul controlat de calculator nu poate construi trenuri STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Dezactivează autovehiculele pentru jucătorii controlaţi de calculator: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Prin activarea acestei opțiuni, jucatorul controlat de calculator nu poate construi vehicule rutiere +STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Prin activarea acestei opțiuni, jucătorul controlat de calculator nu poate construi vehicule rutiere STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Dezactivează aeronavele pentru jucătorii controlaţi de calculator: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Prin activarea acestei opțiuni, jucatorul controlat de calculator nu poate construi aeronave +STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Prin activarea acestei opțiuni, jucătorul controlat de calculator nu poate construi aeronave STR_CONFIG_SETTING_AI_BUILDS_SHIPS :Dezactivează navele pentru jucătorii controlaţi de calculator: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :Prin activarea acestei opțiuni, jucatorul controlat de calculator nu poate construi nave +STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :Prin activarea acestei opțiuni, jucătorul controlat de calculator nu poate construi nave STR_CONFIG_SETTING_AI_PROFILE :Configurația implicită: {STRING} STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Alege o configurație care va fi folosită pentru AI aleator, sau care va fi furniza valori implicite când se adaugă un nou AI sau script @@ -1859,7 +1858,7 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :permis STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :permis, aspect particularizat al oraşului STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Modalitatea de generare a cargoului dintr-un oraș: {STRING} -STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Cât cargo este produs de casele dintr-un oraș, relativ la populația totală a orașului.{}Creștere pătratică: Un oraș de 2 ori mai mare generează de 4 ori mai mulți pasageri.{}Creștere liniară: Un oraș de 2 ori mai mare generează de 4 ori mai mulți pasageri. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Câtă marfa este produsă de casele dintr-un oraș, relativ la populația totală a orașului.{}Creștere pătratică: Un oraș de 2 ori mai mare generează de 4 ori mai mulți pasageri.{}Creștere liniară: Un oraș de 2 ori mai mare generează de 4 ori mai mulți pasageri. ###length 2 STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Pătratică (originală) STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Liniar @@ -1929,13 +1928,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Acordă {STRING STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Timpul necesar pentru fiecare recalculare a unei componente a graficului de legătură. Când se începe o recalculare, este generat un fir de execuție căruia i se permite să ruleze pentru acest număr de zile. Cu cât setați acest lucru mai scurt, cu atât este mai probabil ca firul să nu fie terminat atunci când trebuie. Apoi jocul se oprește până când este ("lag"). Cu cât îl setați mai mult, cu atât este nevoie de mai mult pentru ca distribuția să fie actualizată când se schimbă rutele. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modalitatea de distribuire a pasagerilor: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"simetric" înseamnă că aproximativ același număr de pasageri va fi transportat din stația A spre stația B, precum de la B la A. "asimetric" presupune transportul unui număr arbitrar de pasageri în fiecare direcție. "manual" înseamnă că repartizarea pasagerilor nu va fi automatizată. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simetric" înseamnă că aproximativ același număr de pasageri va fi transportat din stația A spre stația B, precum de la B la A. "Asimetric" presupune transportul unui număr arbitrar de pasageri în fiecare direcție. "Manual" înseamnă că repartizarea pasagerilor nu va fi automatizată. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Modalitatea de distribuire a poştei: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"simetric" înseamnă că aproximativ aceeași cantitate de poștă va fi expediată din stația A spre stația B, precum de la B la A. "asimetric" presupune expedierea de cantități arbitrare de poștă în fiecare direcție. "manual" înseamnă că repartizarea poștei nu va fi automatizată. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Simetric" înseamnă că aproximativ aceeași cantitate de poștă va fi expediată din stația A spre stația B, precum de la B la A. "Asimetric" presupune expedierea de cantități arbitrare de poștă în fiecare direcție. "Manual" înseamnă că repartizarea poștei nu va fi automatizată. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Modalitatea de distribuire pentru clasa de cargo BLINDAT: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Clasa de marfă ARMORED conține obiecte de valoare în climat temperat, diamante în climat subtropical sau aur în climat subarctic. NewGRF-urile pot schimba asta. „simetric” înseamnă că aproximativ aceeași cantitate din acea marfă va fi trimisă de la o stație A la o stație B ca de la B la A. „asimetric” înseamnă că cantități arbitrare ale acelei mărfuri pot fi trimise în ambele direcții. „manual” înseamnă că nu va avea loc nicio distribuție automată pentru acea marfă. Este recomandat să setați acest lucru la asimetric sau manual atunci când jucați subarctic, deoarece băncile nu vor trimite aur înapoi la minele de aur. Pentru cele temperate și subtropicale, puteți alege și simetric, deoarece băncile vor trimite obiectele de valoare înapoi la banca de origine a unei încărcături de obiecte de valoare. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Clasa de marfă ARMORED conține obiecte de valoare în climat temperat, diamante în climat subtropical sau aur în climat subarctic. NewGRF-urile pot schimba asta. „Simetric” înseamnă că aproximativ aceeași cantitate din acea marfă va fi trimisă de la o stație A la o stație B ca de la B la A. „Asimetric” înseamnă că cantități arbitrare ale acelei mărfuri pot fi trimise în ambele direcții. „Manual” înseamnă că nu va avea loc nicio distribuție automată pentru acea marfă. Este recomandat să setați acest lucru la asimetric sau manual atunci când jucați subarctic sau subtropical, deoarece băncile doar primesc bunuri in aceste climate. Pentru climatul temperat, puteți alege și simetric, deoarece băncile vor trimite obiectele de valoare înapoi la banca de origine a unei încărcături. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modalitatea de distribuire pentru alte clase de cargo: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asimetric" înseamnă că pot fi trimise cantități diferite de marfă în ambele direcții. "manual" înseamnă că nu se va face distribuție automată pentru acele mărfuri. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimetric" înseamnă că pot fi trimise cantități diferite de marfă în ambele direcții. "Manual" înseamnă că nu se va face distribuție automată pentru acele mărfuri. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimetric @@ -2030,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Întoarcere aut STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Permite trenurilor să întoarcă la semafor, dacă aşteaptă de mult timp ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomandat) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recomandat) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Schimbă valoarea setării @@ -2073,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Tabela c STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Setări STR_INTRO_NEWGRF_SETTINGS :{BLACK}Setări NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Resurse online -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Setări IA / Scripturi Joc +STR_INTRO_AI_SETTINGS :{BLACK}Setări AI +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Setări pentru scriptul jocului STR_INTRO_QUIT :{BLACK}Ieşire STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Începere joc nou. Ctrl+Click pentru a sări peste fereastra de configuraţie a harţii @@ -2093,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Afișeaz STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Setări afişare STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Afişează setările NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Verifică dacă există resurse noi sau actualizate pentru descărcare -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Afişează setările pentru Inteligența Artificială şi pentru Scripturi Joc +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Afișează setările AI +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Afișează setările scriptului de joc STR_INTRO_TOOLTIP_QUIT :{BLACK}Ieși din 'OpenTTD' STR_INTRO_BASESET :{BLACK}Setul grafic actual are lipsă {NUM} {P sprite spriteuri "de spriteuri"}. Verificați actualizările pentru setul de bază. @@ -2125,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Schimb STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Schimbă anul curent STR_CHEAT_SETUP_PROD :{LTBLUE}Activează accesul la valorile de producţie: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :peisajul temperat -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :peisajul sub-arctic -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :peisajul sub-tropical -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :peisajul 'ţara jucăriilor' - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Schemă de culori @@ -2363,7 +2358,6 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Companie nouă STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Creează o nouă companie și intră în ea STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Aici ești tu STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Aceasta este gazda jocului -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} {P client clienți "de clienți"} / {NUM}{P companie companii "de companii"} # Matches ConnectionType ###length 5 @@ -2490,13 +2484,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :se așteaptă p STR_NETWORK_MESSAGE_CLIENT_LEAVING :iese STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} a intrat în joc -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} a intrat în joc (Clientul #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} a intrat în compania #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} a intrat în joc (Clientul #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} a intrat în compania #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} a intrat ca spectator STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} a început o companie nouă (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} a ieşit din joc ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} a ieşit din joc ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} și-a schimbat numele în {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} a dat {2:CURRENCY_LONG} către {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} a dat {2:CURRENCY_LONG} către {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Serverul a închis conexiunea STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Serverul este repornit...{}Vă rugăm aşteptaţi... STR_NETWORK_MESSAGE_KICKED :*** {STRING} a fost dat afară. Motiv: ({STRING}) @@ -2610,6 +2604,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}saturat STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}supraîncărcat +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} care urmează să fie transportat pe lună de la {STATION} la {STATION} ({COMMA}% din capacitate){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} de transportat înapoi ({COMMA}% din capacitate) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Durată medie de călătorie: {NUM}{NBSP}{P "zi" "zile" "de zile"} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Aria de acoperire STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Inactiv @@ -2618,6 +2617,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Nu arăt STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Arată aria de acoperire a locaţiei propuse STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Acceptă: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Furnizează: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Cost întreținere: {GOLD}{CURRENCY_SHORT}/an # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Uneşte staţia @@ -2700,8 +2700,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Creşte STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Alege pod de cale ferată STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Alege pod rutier STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Alegere pod - click pe podul preferat pentru a-l construi -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Suspensie, Oţel STR_BRIDGE_NAME_GIRDER_STEEL :Grindă, Oţel STR_BRIDGE_NAME_CANTILEVER_STEEL :Arc, Oţel @@ -2805,11 +2807,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Modifica STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Scade altitudinea unui punct de teren. Trage cu mouse-ul pentru a coborî primul punct de teren și a nivela restul zonei la noua înălțime a acestuia. Ctrl pentru selecţie pe diagonală. STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Creşte altitudinea unui punct de teren. Trage cu mouse-ul pentru a ridica primul punct de teren și a nivela restul zonei la noua înălțime a acestuia. Ctrl pentru selecţie pe diagonală. STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Nivelează terenul la înălțimea primului colț selectat. Ctrl pentru selecție pe diagonală -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Cumpără teren pentru folosire ulterioară. Shift comută între cumpărare/afişare cost estimat +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Cumpărați teren pentru utilizare ulterioară. Ctrl selectează zona în diagonală. Shift comută construirea/afișarea estimării costurilor # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Selecţia obiectelor -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selectaţi obiectele pentru construcţie. Shift comută între construire/afişare cost estimat +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selectați obiectul de construit. Ctrl selectează zona în diagonală. Shift comută construirea/afișarea estimării costurilor STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Selectează clasa obiectului de construit STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Previzualizarea obiectului STR_OBJECT_BUILD_SIZE :{BLACK}Dimensiune: {GOLD}{NUM} x {NUM} pătrăţele @@ -2821,7 +2823,7 @@ STR_OBJECT_CLASS_TRNS :Transmiţătoar STR_PLANT_TREE_CAPTION :{WHITE}Arbori STR_PLANT_TREE_TOOLTIP :{BLACK}Alege specia de arbori de plantat. Dacă există deja un arbore în locația dorită, se vor adăuga arbori de tip mixt, indiferent de specia selectată STR_TREES_RANDOM_TYPE :{BLACK}Arbori din specii aleatoare -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Plantează arbori din diverse specii la întâmplare. Shift comută între plantare/afişare cost estimat +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Plantează arbori din diverse specii la întâmplare. Ctrl selectează zona în diagonală. Shift comută între plantare/afişare cost estimat STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Arbori aleatori STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plantează aleator arbori pe uscat STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2853,6 +2855,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Oraş al STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Construieşte un oraş într-o locaţie aleatoare STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Mai multe oraşe aleatoare STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Umple harta cu oraşe generate aleator +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Extinde orasele +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Fă toate orașele să crească ușor STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nume oraş: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Introdu numele oraşului @@ -3117,7 +3121,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalii STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Nicio informaţie disponibilă STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtrare după: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtru: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Suprascrie fișierul STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Sigur vrei să suprascrii fișierul existent? STR_SAVELOAD_DIRECTORY :{STRING} (listă) @@ -3131,6 +3135,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Mărime STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Alege mărimea hărții folosind ca unitate de măsură suprafețele. Numărul de suprafețe disponibile va fi puțin mai mic decât această valoare STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Nr. de oraşe: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Numele orașelor: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Alege naţionalitatea numelor oraşelor STR_MAPGEN_DATE :{BLACK}Data: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Nr. de industrii: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Cel mai înalt vârf: @@ -3144,13 +3150,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Acoperir STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Mărește întinderea deșertului cu zece procente STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Reduce întinderea deșertului cu zece procente STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Generator de teren: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tip teren: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Nivelul mării: +STR_MAPGEN_SEA_LEVEL :{BLACK}Nivelul mării: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Râuri: STR_MAPGEN_SMOOTHNESS :{BLACK}Netezime: STR_MAPGEN_VARIETY :{BLACK}Distribuţia varietăţii: STR_MAPGEN_GENERATE :{WHITE}Generează +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Setări NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Afişează setările NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Configurație AI +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Afișează setările AI +STR_MAPGEN_GS_SETTINGS :{BLACK}Setări pentru scriptul de joc +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Afișează setările scriptului de joc + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Englezeşti (Original) +STR_MAPGEN_TOWN_NAME_FRENCH :Franţuzeşti +STR_MAPGEN_TOWN_NAME_GERMAN :Nemţeşti +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Englezeşti (Adiţional) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latino-Americane +STR_MAPGEN_TOWN_NAME_SILLY :Amuzante +STR_MAPGEN_TOWN_NAME_SWEDISH :Suedeze +STR_MAPGEN_TOWN_NAME_DUTCH :Olandeze +STR_MAPGEN_TOWN_NAME_FINNISH :Finlandeze +STR_MAPGEN_TOWN_NAME_POLISH :Poloneze +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovace +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norvegiene +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungureşti +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austriece +STR_MAPGEN_TOWN_NAME_ROMANIAN :Româneşti +STR_MAPGEN_TOWN_NAME_CZECH :Ceheşti +STR_MAPGEN_TOWN_NAME_SWISS :Elveţiene +STR_MAPGEN_TOWN_NAME_DANISH :Daneze +STR_MAPGEN_TOWN_NAME_TURKISH :Turceşti +STR_MAPGEN_TOWN_NAME_ITALIAN :Italieneşti +STR_MAPGEN_TOWN_NAME_CATALAN :Catalană # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Margine: @@ -3296,6 +3330,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Imaginea STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Mergi la precedenta imagine normală, sărind peste pseudo-imagini, recolorări sau fonturi şi reporneşte când s-a ajuns la sfârşit STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Reprezentarea imaginii curente. Aliniamentul este ignorat STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Mișcă imaginea schimbând distanțele pe axele X şi Y. Ctrl+Clic pentru mutarea imaginii câte opt unități la un pas + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Offset centrat +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Centrază sprite + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Focus + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Resetează relativele STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Resetază limitele relative actuale STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Limita X: {NUM}, Limita Y: {NUM} (Absolut) @@ -3310,18 +3351,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Atenţie: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Eroare: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}O eroare fatală NewGRF a avut loc:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}O eroare NewGRF a avut loc:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}NewGRF-ul "{STRING}" a avut o eroare fatală:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF-ul "{STRING}" a avut o eroare:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} nu va funcţiona cu versiunea TTDPatch raportată de OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} este pentru versiunea {STRING} a TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} este conceput pentru a fi folosit cu {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Parametru invalid pentru {1:STRING}: parametrul {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} trebuie să fie încărcat înaintea {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} trebuie să fie încărcat după {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} necesită OpenTTD versiunea {STRING} sau mai nouă +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} este pentru versiunea {2:STRING} a TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} este conceput pentru a fi folosit cu {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Parametru invalid pentru {1:STRING}: parametrul {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} trebuie să fie încărcat înaintea {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} trebuie să fie încărcat după {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} necesită OpenTTD versiunea {2:STRING} sau mai nouă STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :fişierul GRF conceput pentru traducere STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Sunt încărcate prea multe NewGRF-uri -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Încărcarea {1:STRING} ca un NewGRF static cu {STRING} ar putea cauza desincronizări +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Încărcarea {1:STRING} ca un NewGRF static cu {2:STRING} ar putea cauza desincronizări STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Element grafic neașteptat (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Proprietate necunoscută pentru Acțiunea 0 {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Încercare de a folosi un ID invalid (sprite {3:NUM}) @@ -3453,14 +3494,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Cumpără drept STR_LOCAL_AUTHORITY_ACTION_BRIBE :Mituieşte autoritatea locală ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Inițiază o campanie publicitară mică pentru a atrage mai mulți călători și mai multe mărfuri spre compania ta.{}Oferă temporar un spor la cotația stației tale pe o rază mică în jurul centrului orașului.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Inițiază o campanie publicitară medie pentru a atrage mai mulți călători și mai multe mărfuri spre compania ta.{}Oferă temporar un spor la cotația stației tale pe o rază medie în jurul centrului orașului.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Inițiază o mare campanie publicitară pentru a atrage mai mulți călători și mai multe mărfuri spre compania ta.{}Oferă temporar un spor la cotația stației tale pe o rază mare în jurul centrului orașului.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Finanțează reconstrucția rețelei locale de drumuri.{}Aceasta cauzează perturbări majore ale traficului rutier timp de până la 6 luni.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Construiește o statuie în cinstea companiei tale.{}Oferă un spor permanent la cotația stației tale în acest oraș.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Finanțează construcția de noi clădiri comerciale în oraș.{}Oferă un spor temporar dezvoltării în acest oraș.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Cumpără drepturi exclusive de transport în acest oraș, timp de un an.{}Autoritățile locale nu vor permite călătorilor și mărfurilor să folosească stațiile competitorilor.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Mituieşte autorităţile locale pentru a-ţi îmbunătăţi ratingul, dar cu riscul de a fi prins şi de a plăti amenzi serioase.{} Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inițiază o campanie publicitară mică pentru a atrage mai mulți călători și mai multe mărfuri spre compania ta.{}Oferă temporar un spor la cotația staților tale pe o rază mică în jurul centrului orașului.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inițiază o campanie publicitară medie pentru a atrage mai mulți călători și mai multe mărfuri spre compania ta.{}Oferă temporar un spor la cotația stațiilor tale pe o rază medie în jurul centrului orașului.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inițiază o mare campanie publicitară pentru a atrage mai mulți călători și mai multe mărfuri spre compania ta.{}Oferă temporar un spor la cotația stațiilor tale pe o rază mare în jurul centrului orașului.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Finanțați reconstrucția rețelei de drumuri urbane.{}Provoacă perturbări considerabile ale traficului rutier timp de până la 6 luni.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Construiește o statuie în onoarea companiei tale.{}Oferă un spor permanent pentru cotele stațiilor tale din acest oraș.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Finanțează construcția de noi clădiri în oraș.{}Oferă un spor temporar dezvoltării în acest oraș.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Cumpără drepturi exclusive de transport în acest oraș, timp de un an.{}Autoritățile locale nu vor permite călătorilor și mărfurilor să folosească stațiile competitorilor.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Mituiți autoritatea locală pentru a vă crește ratingul, cu riscul unei sancțiuni severe dacă eşti prins.{}{POP_COLOUR}Cost: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Scopuri @@ -3613,24 +3654,38 @@ STR_FINANCES_CAPTION :{WHITE}Situaţi STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}Venit +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Cheltuieli operaționale +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Cheltuieli Capital ###length 13 STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Construcţii STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Vehicule noi -STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Costuri trenuri -STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Costuri de exploatare autovehicule -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Costuri aeronave -STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Costuri nave +STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Trenuri +STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Autovehicule +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Aeronave +STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Nave +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Infrastructură +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Trenuri +STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}Autovehicule +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Avion +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Nave STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Dobânda la credit STR_FINANCES_SECTION_OTHER :{GOLD}Altele -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} -STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} +STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Profit STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Balanţă curentă +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Fonduri proprii STR_FINANCES_LOAN_TITLE :{WHITE}Credite +STR_FINANCES_INTEREST_RATE :{WHITE}Dobândā la credit: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Limită credit: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Împrumută {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Împrumută o nouă sumă de bani. Ctrl-click pentru a împrumuta suma maximă posibilă STR_FINANCES_REPAY_BUTTON :{BLACK}Plăteşte înapoi {CURRENCY_LONG} @@ -3731,7 +3786,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produce: STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Necesită: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} așteaptă{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Schimba productia (multiplu de 8, până la 2040) @@ -3756,11 +3811,13 @@ STR_VEHICLE_LIST_AVAILABLE_ROAD_VEHICLES :Vehicule dispon STR_VEHICLE_LIST_AVAILABLE_SHIPS :Nave disponibile STR_VEHICLE_LIST_AVAILABLE_AIRCRAFT :Aeronave disponibile -STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}Gestioneaza lista -STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Trimite instructiunile tuturor vehiculelor din aceasta lista -STR_VEHICLE_LIST_REPLACE_VEHICLES :Inlocuieste vehiculele +STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}Gestionează lista +STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Trimite instrucțiuni tuturor vehiculelor din această listă +STR_VEHICLE_LIST_REPLACE_VEHICLES :Înlocuiește vehiculele STR_VEHICLE_LIST_SEND_FOR_SERVICING :Trimite in service STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Profit anul acesta: {CURRENCY_LONG} (anul trecut: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Trimite la depou STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Trimite la depou @@ -3768,7 +3825,7 @@ STR_VEHICLE_LIST_SEND_SHIP_TO_DEPOT :Trimite la depo STR_VEHICLE_LIST_SEND_AIRCRAFT_TO_HANGAR :Trimite la hangar STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP :{BLACK}Click pt oprirea tuturor vehiculelor din listă -STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP :{BLACK}Apasa pentru pornirea tuturor vehiclulelor din lista +STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP :{BLACK}Apasă pentru pornirea tuturor vehiclulelor din listă STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP :{BLACK}Vezi o listă de proiecte de motoare disponibile pentru acest tip de vehicul STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION :{WHITE}Comenzi sincronizate pentru {COMMA} {P vehicul vehicule "de vehicule"} @@ -3852,6 +3909,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Efort tr STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Rază acțiune: {GOLD}{COMMA} pătrățele STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tip de aeronavă: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Toate tipurile de marfă +STR_CARGO_TYPE_FILTER_FREIGHT :Marfă +STR_CARGO_TYPE_FILTER_NONE :Niciunul + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Lista de selectie a componentelor trenului - clic pe vehicule pt. informatii STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Listă selecţie vehicule rutiere - apasă pe vehicul pentru informaţii @@ -4020,7 +4082,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :aeronavă STR_ENGINE_PREVIEW_SHIP :navă STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cost: {CURRENCY_LONG} Greutate: {WEIGHT_SHORT}{}Viteză: {VELOCITY} Putere: {POWER}{}Mentenanță: {CURRENCY_LONG}/an{}Capacitate: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {CURRENCY_LONG} Greutate: {WEIGHT_SHORT}{}Viteză: {VELOCITY} Putere: {POWER} Ef. T. Max.: {6:FORCE}{}Mentenanță: {4:CURRENCY_LONG}/an{}Capacitate: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {0:CURRENCY_LONG} Greutate: {1:WEIGHT_SHORT}{}Viteză: {2:VELOCITY} Putere: {3:POWER} Ef. T. Max.: {6:FORCE}{}Cost operare: {4:CURRENCY_LONG}/an{}Capacitate: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Viteză max.: {VELOCITY}{}Capacitate: {CARGO_LONG}{}Mentenanță: {CURRENCY_LONG}/an STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Viteză max.: {VELOCITY}{}Tip de aeronavă: {STRING}{}Capacitate: {CARGO_LONG}, {CARGO_LONG}{}Mentenanță: {CURRENCY_LONG}/an STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Viteză max.: {VELOCITY}{}Tip aeronavă: {STRING}{}Capacitate: {CARGO_LONG}{}Mentenanță: {CURRENCY_LONG}/an @@ -4130,13 +4192,13 @@ STR_VEHICLE_VIEW_AIRCRAFT_STATUS_START_STOP_TOOLTIP :{BLACK}Acțiune # Messages in the start stop button in the vehicle view STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}Încărcare / Descărcare -STR_VEHICLE_STATUS_LEAVING :{LTBLUE}Pleaca +STR_VEHICLE_STATUS_LEAVING :{LTBLUE}Pleacă STR_VEHICLE_STATUS_CRASHED :{RED}Accident! STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}Defect STR_VEHICLE_STATUS_STOPPED :{RED}Oprit STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL :{RED}Oprire, {VELOCITY} STR_VEHICLE_STATUS_TRAIN_NO_POWER :{RED}Fara curent -STR_VEHICLE_STATUS_TRAIN_STUCK :{ORANGE}Astept cale libera +STR_VEHICLE_STATUS_TRAIN_STUCK :{ORANGE}Aștept cale liberă STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR :{ORANGE}Prea departe pentru următoarea destinație STR_VEHICLE_STATUS_HEADING_FOR_STATION_VEL :{LTBLUE}Spre {STATION}, {VELOCITY} @@ -4179,12 +4241,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Greutate STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Greutate: {LTBLUE}{WEIGHT_SHORT} {BLACK}Putere: {LTBLUE}{POWER}{BLACK} Viteză max.: {LTBLUE}{VELOCITY} {BLACK}Efort tractiv: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit pe anul curent: {LTBLUE}{CURRENCY_LONG} (anul precedent: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Profit anul curent: {LTBLUE}{CURRENCY_LONG} (anul trecut: {CURRENCY_LONG}) {BLACK}performanta minima: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Eficienţă: {LTBLUE}{COMMA}% {BLACK}Defecţiuni de la ultimul service: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Construit: {LTBLUE}{NUM}{BLACK} Valoare: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacitate: {LTBLUE}Nimic{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacitate: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacitate: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacitate: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacitate: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacitate: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transferă Credit: {LTBLUE}{CURRENCY_LONG} @@ -4210,8 +4273,8 @@ STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Valoare: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Încãrcãtura totalã (capacitatea) acestui tren: -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Gol STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} de la {STATION} @@ -4450,25 +4513,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Acest or STR_TIMETABLE_STATUS_START_AT :{BLACK}Acest orar va începe la {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Dată pornire -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Alege o dată ca punct de pornire pentru acest orar. Ctrl+clic setează punctul de pornire al acestui orar și distribuie uniform comanda tuturor vehiculelor în cu comenzi similare, dacă comenzile au un orar complet +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Alege o dată ca punct de pornire pentru acest orar. Ctrl+clic distribuie toate vehiculele uniform de la data setată bazată pe comenzile relative, dacă comenzile au un orar complet STR_TIMETABLE_CHANGE_TIME :{BLACK}Modifică timpul -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Modifică durata de timp alocată comenzii selectate +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Modificați timpul pe care ar trebui să o dureze comanda evidențiată. Ctrl+Click setează ora pentru toate comenzile STR_TIMETABLE_CLEAR_TIME :{BLACK}Curata timp STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Elimină durata de timp pentru comanda selectată STR_TIMETABLE_CHANGE_SPEED :{BLACK}Schimbă limita de viteză -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Schimbă limita maximă de viteză a comenzii selectate +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Schimbă limita maximă de viteză a comenzii selectate. Ctrl+Click setează viteza pentru toate comenzile STR_TIMETABLE_CLEAR_SPEED :{BLACK}Şterge limita de viteză -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Șterge limita maximă de viteză a comenzii selectate +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Ștergeți viteza maximă de deplasare a comenzii evidențiate. Ctrl+Click șterge viteza pentru toate comenzile STR_TIMETABLE_RESET_LATENESS :{BLACK}Reinitializeaza contorul de intarziere -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reiniţializează contorul de întârziere, astfel ca vehiculul să ajungă la timp +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reiniţializează contorul de întârziere, astfel ca vehiculul să ajungă la timp. Ctrl+clic va reseta tot grupul astfel încât cel mai întârziat vehicul va ajunge la timp și toate celelalte vor ajunge mai devreme STR_TIMETABLE_AUTOFILL :{BLACK}Auto-completare -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Completează automat tabela cu timpi cu valorile pentru urmatoarea călătorie (CTRL-clic pentru a încerca să păstraţi timpii de aşteptare) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Completați automat orarul cu valorile din următoarea călătorie. Ctrl+Click pentru a încerca să păstrați timpii de așteptare STR_TIMETABLE_EXPECTED :{BLACK}Estimat STR_TIMETABLE_SCHEDULED :{BLACK}Planificat @@ -4488,7 +4551,7 @@ STR_DATE_YEAR_TOOLTIP :{BLACK}Alege an # AI debug window -STR_AI_DEBUG :{WHITE}Depanare IA / Script Joc +STR_AI_DEBUG :{WHITE}Depanare IA / Script de joc STR_AI_DEBUG_NAME_AND_VERSION :{BLACK}{STRING} (v{NUM}) STR_AI_DEBUG_NAME_TOOLTIP :{BLACK}Numele scriptului STR_AI_DEBUG_SETTINGS :{BLACK}Setări @@ -4512,25 +4575,26 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}O Inteli STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Fereastra pentru depanare IA / Script Joc este disponibilă doar serverului # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Configurație Inteligentă Artificială / Scripturi Joc -STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Script Joc încărcat în jocul următor +STR_AI_CONFIG_CAPTION_AI :{WHITE}Configurație AI +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Configurarea scriptului de joc +STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Scriptul care va fi încărcat în jocul următor STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Modulul de IA care va fi încărcat în jocul următor STR_AI_CONFIG_HUMAN_PLAYER :Jucator uman STR_AI_CONFIG_RANDOM_AI :IA aleator STR_AI_CONFIG_NONE :(niciunul) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Numărul maxim de companii concurente: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}În sus STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Mută IA selectată sus în listă STR_AI_CONFIG_MOVE_DOWN :{BLACK}În jos STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Mută IA selectată jos în listă -STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script Joc +STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script de joc +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametri STR_AI_CONFIG_AI :{SILVER}IA -STR_AI_CONFIG_CHANGE :{BLACK}Selectare {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :IA -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script Joc +STR_AI_CONFIG_CHANGE_AI :{BLACK}Selectați IA +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Selectați scriptul jocului STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Încarcă un alt script STR_AI_CONFIG_CONFIGURE :{BLACK}Configurază STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configurează parametrii scriptului @@ -4558,10 +4622,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Captură STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Captură de hartă topografică STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Captură de hartă a lumii -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametrii -STR_AI_SETTINGS_CAPTION_AI :IA -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script Joc +# Script Parameters +STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametri +STR_AI_SETTINGS_CAPTION_AI :{WHITE}IA +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script de joc STR_AI_SETTINGS_CLOSE :{BLACK}Închide STR_AI_SETTINGS_RESET :{BLACK}Resetează STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4725,6 +4789,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... prea STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nu pot genera industrii... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Nu se poate construi {STRING} aici... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Acest tip de industrie nu se poate construi aici... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Nu pot prospecta industria... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... prea aproape de altă industrie STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... mai întâi trebuie creat un oraş STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... un singur obiectiv de acest tip este permis per oraş @@ -4739,6 +4804,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... păd STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... poate fi construit doar deasupra liniei zăpezii STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... poate fi construit doar sub linia zăpezii +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Ghinion, finanțarea prospectării a eșuat. Încearcă din nou +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Nu există locuri potrivite de prospectat pentru această industrie STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Nu s-au găsit locuri potrivite pentru industriile '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Modifică parametrii generatorului ca să obții o hartă mai bună @@ -4906,6 +4973,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Obiect STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... sediu de companie în cale STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Nu poţi cumpăra teren aici... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... este deja în proprietatea ta! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... limita de obiecte construibile a fost atinsă # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Nu pot crea grupul... @@ -4978,6 +5046,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Nu se po STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vehiculul este distrus +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... nu toate vehiculele sunt identice + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Niciun vehicul nu va fi disponibil STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Schimbă configuraţia NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Niciun vehicul nu este disponibil încă @@ -5004,6 +5074,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Nu pot s STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... vehiculul nu poate ajunge la toate staţiile STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... vehiculul nu poate ajunge la acea staţie STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... un vehicul care are acest ordin nu poate ajunge la acea staţie +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... nu toate vehiculele au aceleași comenzi +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... nu toate vehiculele împart comenzi STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Nu se poate trece la comenzi sincronizate... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Nu pot opri sincronizarea listei de comenzi... @@ -5011,6 +5083,11 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Nu pot c STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... prea departe de destinaţia precedentă STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... avionul nu are o rază de acțiune suficientă +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Nu există opriri care să fie potrivite pentru vehiculele rutiere articulate.{}Vehiculele rutiere articulate necesită o oprire de drum, nu o oprire într-o rampă. +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Nu există niciun punct intermediar feroviar +STR_ERROR_NO_BUOY :{WHITE}Nu există geamanduri + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Nu pot programa vehiculul... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Vehiculele pot aştepta numai în staţii diff --git a/src/lang/russian.txt b/src/lang/russian.txt index f361d7736fe0e..b945b99a61f2d 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -326,6 +326,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}л STR_UNITS_POWER_METRIC :{COMMA}{NBSP}лс STR_UNITS_POWER_SI :{COMMA}{NBSP}кВт +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}лс/т +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}лс/т +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}лс/Мг +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}лс/т +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}лс/т +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}лс/Мг +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}кВт/т +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}кВт/т +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}Вт/кг + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}т STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}т STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}кг @@ -352,8 +362,8 @@ STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}м # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Фильтр: -STR_LIST_FILTER_OSKTITLE :{BLACK}Введите строку фильтра -STR_LIST_FILTER_TOOLTIP :{BLACK}Введите ключевое слово для фильтрации списка +STR_LIST_FILTER_OSKTITLE :{BLACK}Введите ключевые слова для фильтрации списка +STR_LIST_FILTER_TOOLTIP :{BLACK}Введите ключевые слова для фильтрации списка STR_TOOLTIP_GROUP_ORDER :{BLACK}Выбор порядка группировки STR_TOOLTIP_SORT_ORDER :{BLACK}Смена направления сортировки (убывание/возрастание) @@ -373,7 +383,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 ###length VEHICLE_TYPES @@ -502,9 +512,9 @@ 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_PLANT_TREES :{BLACK}Посадить деревья. При нажатом Shift - оценка стоимости высадки. +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Посадить деревья.{}При нажатом Ctrl - выбор диагональной области.{}При нажатом Shift - оценка стоимости высадки. STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Поставить метку -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Разместить объект. При нажатом Shift - оценка стоимости строительства. +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Разместить объект.{}При нажатом Ctrl - выбор диагональной области.{}При нажатом Shift - оценка стоимости строительства. # Scenario editor file menu ###length 7 @@ -517,10 +527,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Выход # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Основные настройки STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Расширенные настройки -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Настройки ИИ / скрипта +STR_SETTINGS_MENU_AI_SETTINGS :Настройки ИИ +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Настройки игровых скриптов STR_SETTINGS_MENU_NEWGRF_SETTINGS :Настройки NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Настройки прозрачности STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Показывать названия городов @@ -897,7 +908,7 @@ STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES :{TINY_FONT}{BLA STR_SMALLMAP_LEGENDA_FOREST :{TINY_FONT}{BLACK}Лес STR_SMALLMAP_LEGENDA_RAILROAD_STATION :{TINY_FONT}{BLACK}Ж/д станция STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Грузовой терминал -STR_SMALLMAP_LEGENDA_BUS_STATION :{TINY_FONT}{BLACK}Автобусная станция +STR_SMALLMAP_LEGENDA_BUS_STATION :{TINY_FONT}{BLACK}Автобусная остановка STR_SMALLMAP_LEGENDA_AIRPORT_HELIPORT :{TINY_FONT}{BLACK}Аэропорт/Вертодром STR_SMALLMAP_LEGENDA_DOCK :{TINY_FONT}{BLACK}Пристань STR_SMALLMAP_LEGENDA_ROUGH_LAND :{TINY_FONT}{BLACK}Бездорожье @@ -1110,36 +1121,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Индийск STR_GAME_OPTIONS_CURRENCY_IDR :Индонезийская рупия (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Малайзийский ринггит (MYR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}Язык, который будет использоваться для выбора названий населённых пунктов - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Английские -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Французские -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Немецкие -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Английские (дополн.) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Латино-американские -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Английские (шуточные) -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Шведские -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Нидерландские -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Финские -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Польские -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Словацкие -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Норвежские -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Венгерские -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Австрийские -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Румынские -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Чешские -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Швейцарские -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Датские -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Турецкие -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Итальянские -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Каталанские - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Автосохранение STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Интервал автосохранения игры @@ -1172,21 +1153,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Вклю STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Видеодрайвер: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Размер элементов интерфейса -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Выберите размер элементов интерфейса +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Масштаб интерфейса +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Изменяйте масштаб интерфейса с помощью ползунка. Удерживайте Ctrl для тонкой настройки. +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Автоопределение +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Нажмите для автоматической установки масштаба интерфейса -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(Автовыбор) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Обычный -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Удвоенный -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Учетверённый +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Рельефные элементы +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Масштабировать рельефные элементы интерфейса -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Размер шрифта -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Выберите размер шрифта, используемого в игре - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(Автовыбор) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Нормальный -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Двукратный -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Четырёхкратный +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Настройки графики @@ -1238,8 +1217,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Обр STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10{NBSP}000 фунтов стерлингов (£) в вашей валюте STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Изменить параметр валюты -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Максимальное количество конкурентов: {ORANGE}{COMMA} - STR_NONE :Нет STR_FUNDING_ONLY :Строить самому STR_MINIMAL :Минимальное @@ -1293,6 +1270,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Умеренный ландшафт +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Субарктический ландшафт +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Субтропический ландшафт +STR_CLIMATE_TOYLAND_LANDSCAPE :Игрушечный ландшафт + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Плоский STR_TERRAIN_TYPE_FLAT :Равнинный @@ -1374,6 +1357,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :справа STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Максимальная сумма кредита: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Максимальная сумма кредита для компании (без учета инфляции) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :нет {RED}(необходим игровой скрипт, предоставляющий начальные средства) STR_CONFIG_SETTING_INTEREST_RATE :Процентная ставка: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Процентная ставка по кредитам; также устанавливает уровень инфляции, если та включена. @@ -1600,6 +1586,8 @@ 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_SHOW_CARGO_IN_LISTS :Показывать типы перевозимых грузов в списках ТС: {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Если включено, в списках транспорта будут указаны типы грузов, которые каждое ТС может перевозить. STR_CONFIG_SETTING_LANDSCAPE :Тип карты: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Тип карты определяет основу игрового процесса, например, доступные типы транспорта и грузов, различные условия роста городов. Всё это также может быть изменено с помощью модулей NewGRF и игровых скриптов. @@ -1654,6 +1642,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Улучшен STR_CONFIG_SETTING_ROAD_SIDE :Движение автотранспорта: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Выберите сторону дороги, по которой движется автотранспорт +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Левостороннее +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Правостороннее + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Вращение карты высот: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Против часовой стрелки @@ -2188,7 +2180,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Автомат STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Разрешить поездам разворачиваться у светофора, если они долго ждут разрешающего сигнала ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Рекомендуется) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Рекомендуется) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Изменить значение @@ -2231,7 +2223,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Табл STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Расширенные настройки STR_INTRO_NEWGRF_SETTINGS :{BLACK}Настройки NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Проверить онлайн-контент -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Настройки ИИ / скрипта +STR_INTRO_AI_SETTINGS :{BLACK}Настройки ИИ +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Настройки игровых скриптов STR_INTRO_QUIT :{BLACK}Выход STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Начать новую игру. Ctrl+щелчок пропускает этап настройки карты. @@ -2251,7 +2244,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Пока STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Изменить расширенные настройки игры STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Показать настройки NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Найти новый и обновлённый контент для загрузки -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Изменить настройки ИИ / игрового скрипта +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Показать настройки ИИ +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Показать настройки игровых скриптов STR_INTRO_TOOLTIP_QUIT :{BLACK}Выйти из OpenTTD STR_INTRO_BASESET :{BLACK}В выбранном наборе базовой графики отсутству{P 0 е ю ю}т {NUM} спрайт{P "" а ов}. Пожалуйста, обновите набор графики. @@ -2283,12 +2277,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Изм STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Изменить текущий год STR_CHEAT_SETUP_PROD :{LTBLUE}Разрешить изменение производительности: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Умеренный ландшафт -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Субарктический ландшафт -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Субтропический ландшафт -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Игрушечный ландшафт - # Livery window STR_LIVERY_CAPTION :{WHITE}Цвета компании «{COMPANY}» @@ -2521,7 +2509,8 @@ 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_CLIENT_COMPANY_COUNT :{BLACK}{NUM} клиент{P "" а ов} / {NUM} компани{P я и й} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}Клиентов: {NUM}; компаний: {NUM}/{NUM} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Количество подключённых в данный момент клиентов, существующих компаний и максимально допустимое количество компаний # Matches ConnectionType ###length 5 @@ -2648,13 +2637,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :ожидает STR_NETWORK_MESSAGE_CLIENT_LEAVING :отключение STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} подключился к игре -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} подключился к игре (клиент #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} подключился к компании #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} подключился к игре (клиент #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} подключился к компании #{2:NUM} 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_CLIENT_COMPANY_NEW :*** {0:STRING} основал новую компанию (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} покинул игру ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} сменил(а) имя на {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** Компания «{STRING}» передала «{STRING}» {CURRENCY_LONG} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** Компания «{0:STRING}» передала «{1:STRING}» {2:CURRENCY_LONG} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Сервер закрыл сессию STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Сервер перезапускается...{}Пожалуйста, подождите... STR_NETWORK_MESSAGE_KICKED :*** {STRING} был исключён из игры. Причина: ({STRING}) @@ -2780,6 +2769,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}загруж. STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}перегруз +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} в месяц к перевозке от {STATION} к {STATION} ({COMMA}% ёмкости){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} к возврату ({COMMA}% ёмкости) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Среднее время в пути: {NUM}{NBSP}д{P ень ня ней} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Подсветка зоны покрытия STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Выкл @@ -2788,6 +2782,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Не п STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Показывать зону покрытия STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Принимается: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Отправляется: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Стоимость обслуживания: {GOLD}{CURRENCY_SHORT}/г # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Объединить станции @@ -2878,8 +2873,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Увел STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Выберите железнодорожный мост STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Выберите тип моста STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Выбор моста - щёлкните по изображению моста, который вы хотите построить -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING}{}{VELOCITY}; {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Висячий стальной STR_BRIDGE_NAME_GIRDER_STEEL :Балочный стальной STR_BRIDGE_NAME_CANTILEVER_STEEL :Консольный стальной @@ -2924,7 +2921,7 @@ STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Выбо # Road vehicle station construction window STR_STATION_BUILD_BUS_ORIENTATION :{WHITE}Направление остановки -STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP :{BLACK}Выберите направление автобусной остановки +STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP :{BLACK}Выберите направление остановки STR_STATION_BUILD_TRUCK_ORIENTATION :{WHITE}Ориентация терминала STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP :{BLACK}Выберите направление грузового терминала STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION :{WHITE}Направление пассажирской трамвайной остановки @@ -2984,14 +2981,14 @@ 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_PURCHASE_LAND :{BLACK}Покупка земли. При нажатом Shift - оценка стоимости покупки. +STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Опустить угол земли. Перетаскивание опускает первый выбранный угол и выравнивает выбранную область до новой высоты угла.{}При нажатом Ctrl - выбор диагональной области.{}При нажатом Shift - оценка стоимости строительства. +STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Поднять угол земли. Перетаскивание поднимает первый выбранный угол и выравнивает выбранную область до новой высоты угла.{}При нажатом Ctrl - выбор диагональной области.{}При нажатом Shift - оценка стоимости строительства. +STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Выровнять землю до высоты первого выбранного угла.{}При нажатом Ctrl - выбор диагональной области.{}При нажатом Shift - оценка стоимости выравнивания. +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Покупка земли.{}При нажатом Ctrl - выбор диагональной области.{}При нажатом Shift - оценка стоимости покупки. # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Выбор объекта -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Выберите создаваемый объект. При нажатом Shift - оценка стоимости постройки. +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Выберите создаваемый объект.{}При нажатом Ctrl они размещаются в диагональной области.{}При нажатом Shift - оценка стоимости постройки. STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Выберите класс объекта для строительства STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Предварительный просмотр объекта STR_OBJECT_BUILD_SIZE :{BLACK}Размер: {GOLD}{NUM} × {NUM} клеток @@ -3003,7 +3000,7 @@ STR_OBJECT_CLASS_TRNS :Передат STR_PLANT_TREE_CAPTION :{WHITE}Деревья STR_PLANT_TREE_TOOLTIP :{BLACK}Выберите тип деревьев для посадки. Если на участке уже есть деревья, будут добавлены несколько деревьев различного типа, независимо от выбранного. STR_TREES_RANDOM_TYPE :{BLACK}Деревья случайного типа -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Высадка деревьев случайного типа. При нажатом Shift - оценка стоимости высадки. +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Высадка деревьев случайного типа.{}При нажатом Ctrl - выбор диагональной области.{}При нажатом Shift - оценка стоимости высадки. STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Расставить по карте STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Разместить деревья на местности случайным образом STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Дерево @@ -3035,6 +3032,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Случ STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Создать город в случайном месте STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Множество различных городов STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Разместить на карте различные города случайным образом +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Расширить все города +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Увеличить размер всех городов STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Название города: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Введите название города @@ -3313,6 +3312,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Разм STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Выберите размер карты в клетках. Размер поля, доступного игрокам, будет немного меньше. STR_MAPGEN_BY :{BLACK}× STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Количество городов: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Названия городов: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Язык, который будет использоваться для выбора названий населённых пунктов STR_MAPGEN_DATE :{BLACK}Дата: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Кол-во предпр.: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Высочайшая вершина: @@ -3326,13 +3327,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Песч STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Увеличить площадь песчаного покрытия на 10% STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Уменьшить площадь песчаного покрытия на 10% STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Генератор ландшафта: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Тип ландшафта: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Количество морей и озёр: +STR_MAPGEN_SEA_LEVEL :{BLACK}Количество морей и озёр: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Количество рек: STR_MAPGEN_SMOOTHNESS :{BLACK}Грубость ландшафта: STR_MAPGEN_VARIETY :{BLACK}Разнообразие ландшафта: STR_MAPGEN_GENERATE :{WHITE}Создать +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Настройки NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Показать настройки NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Настройки ИИ +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Показать настройки ИИ +STR_MAPGEN_GS_SETTINGS :{BLACK}Настройки игровых скриптов +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Показать настройки игровых скриптов + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Английские +STR_MAPGEN_TOWN_NAME_FRENCH :Французские +STR_MAPGEN_TOWN_NAME_GERMAN :Немецкие +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Английские (дополн.) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Латино-американские +STR_MAPGEN_TOWN_NAME_SILLY :Английские (шуточные) +STR_MAPGEN_TOWN_NAME_SWEDISH :Шведские +STR_MAPGEN_TOWN_NAME_DUTCH :Нидерландские +STR_MAPGEN_TOWN_NAME_FINNISH :Финские +STR_MAPGEN_TOWN_NAME_POLISH :Польские +STR_MAPGEN_TOWN_NAME_SLOVAK :Словацкие +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Норвежские +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Венгерские +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Австрийские +STR_MAPGEN_TOWN_NAME_ROMANIAN :Румынские +STR_MAPGEN_TOWN_NAME_CZECH :Чешские +STR_MAPGEN_TOWN_NAME_SWISS :Швейцарские +STR_MAPGEN_TOWN_NAME_DANISH :Датские +STR_MAPGEN_TOWN_NAME_TURKISH :Турецкие +STR_MAPGEN_TOWN_NAME_ITALIAN :Итальянские +STR_MAPGEN_TOWN_NAME_CATALAN :Каталанские # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Края карты: @@ -3478,6 +3507,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Пред STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Перейти к предыдущему нормальному спрайту, пропуская изменяющие цвет, шрифтовые, псевдоспрайты. Переход из начала списка к последнему спрайту. STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Представление выбранного спрайта. Выравнивание не учитывается при прорисовке этого спрайта. STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Двигайте спрайт, изменяя смещение по осям X и Y. С помощью Ctrl+щелчка можно сдвигать спрайты на 8 единиц. + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Смещение в центре +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Спрайт в центре + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Перекрестие + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Сброс смещения STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Сбросить значения относительного смещения STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Смещение X: {NUM}; смещение Y: {NUM} (абсолютное) @@ -3492,18 +3528,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Внимание: {SILVER}{STRING} 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_FATAL_POPUP :{WHITE}В модуле NewGRF «{STRING}» произошла критическая ошибка:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}В модуле NewGRF «{STRING}» произошла ошибка:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} не будет работать с версией TTDPatch, сообщенной OpenTTD. -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :Файл {1:STRING} требует {STRING}-версию TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} сделан для использования совместно с {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Неверный параметр {1:STRING}: параметр {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} должен быть загружен перед {STRING}. -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} должен быть загружен после {STRING}. -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} требует OpenTTD версии {STRING} или выше. +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :Файл {1:STRING} требует TTD версии {2:STRING} +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} предполагается использовать совместно с {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Неверный параметр {1:STRING}: параметр {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} должен быть загружен перед {2:STRING}. +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} должен быть загружен после {2:STRING}. +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :Для {1:STRING} требуется OpenTTD версии {2:STRING} или выше STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :файл GRF, который им переводится. STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Загружено слишком много модулей NewGRF -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Загрузка {1:STRING} в качестве статического NewGRF с {STRING} может вызвать рассинхронизацию. +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Загрузка {1:STRING} в качестве статического NewGRF с {2:STRING} может вызвать рассинхронизацию STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Неверный спрайт (спрайт {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Неизвестное свойство у «Action 0» {4:HEX} (спрайт {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Попытка использования недопустимого идентификатора (спрайт {3:NUM}) @@ -3635,14 +3671,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Купить э STR_LOCAL_AUTHORITY_ACTION_BRIBE :Взятка местной администрации ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Провести малую рекламную кампанию для увеличения грузо- и пассажиропотока на ваших станциях.{}Она временно повысит рейтинг ваших станций, построенных рядом с центром города.{}Стоимость: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Провести среднюю рекламную кампанию для увеличения грузо- и пассажиропотока на ваших станциях.{}Она временно повысит рейтинг ваших станций, находящихся не очень далеко от центра города.{}Стоимость: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Провести большую рекламную кампанию для увеличения грузо- и пассажиропотока на ваших станциях.{}Она временно повысит рейтинг ваших станций на значительной площади в городе и окрестностях.{}Стоимость: {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} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Провести малую рекламную кампанию для увеличения грузо- и пассажиропотока на ваших станциях.{}Она временно повысит рейтинг ваших станций, построенных рядом с центром города.{}{POP_COLOUR}Стоимость: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Провести среднюю рекламную кампанию для увеличения грузо- и пассажиропотока на ваших станциях.{}Она временно повысит рейтинг ваших станций, находящихся не очень далеко от центра города.{}{POP_COLOUR}Стоимость: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Провести большую рекламную кампанию для увеличения грузо- и пассажиропотока на ваших станциях.{}Она временно повысит рейтинг ваших станций на значительной площади в городе и окрестностях.{}{POP_COLOUR}Стоимость: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Профинансировать реконструкцию городских дорог.{}Вызывает большие нарушения движения на срок до 6 месяцев.{}{POP_COLOUR}Стоимость: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Установить статую в честь вашей компании.{}Она добавит рейтинг вашим станциям.{}{POP_COLOUR}Стоимость: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Профинансировать строительство новых зданий.{}Это временно ускорит рост города.{}{POP_COLOUR}Стоимость: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Приобрести годовые эксклюзивные права на транспортные перевозки в городе.{}Городская администрация разрешит пользоваться ТОЛЬКО вашими станциями.{}{POP_COLOUR}Стоимость: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Дать взятку городской администрации для повышения рейтинга. Существует риск санкций, если факт подкупа раскроется.{}{POP_COLOUR}Цена: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}Задачи компании «{COMPANY}» @@ -3795,8 +3831,8 @@ STR_FINANCES_CAPTION :{WHITE}Фина STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 -STR_FINANCES_REVENUE_TITLE :{WHITE}Доход -STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Эксплуатационные расходы +STR_FINANCES_REVENUE_TITLE :{WHITE}Доходы +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Операционные расходы STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Капитальные расходы @@ -3815,15 +3851,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Суда STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Платёж по кредиту STR_FINANCES_SECTION_OTHER :{GOLD}Прочие расходы +STR_FINANCES_TOTAL_CAPTION :{WHITE}Всего STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Чистая прибыль +STR_FINANCES_PROFIT :{WHITE}Прибыль STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Баланс: STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Собственные средства STR_FINANCES_LOAN_TITLE :{WHITE}Взято в кредит STR_FINANCES_INTEREST_RATE :{WHITE}Проценты по кредиту: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Макс. сумма кредита: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Занять {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Взять деньги в кредит. Ctrl+щелчок - взять максимально возможную сумму. STR_FINANCES_REPAY_BUTTON :{BLACK}Отдать {CURRENCY_LONG} @@ -3924,7 +3963,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Прои 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 :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} ожидает{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Изменить производительность (кратно 8, до 2040) @@ -3954,6 +3993,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Упра STR_VEHICLE_LIST_REPLACE_VEHICLES :Замена транспорта STR_VEHICLE_LIST_SEND_FOR_SERVICING :Отправить на тех. обслуживание STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Прибыль в этом году: {CURRENCY_LONG} (в прошлом году: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Отправить в депо STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Отправить в гараж @@ -4045,6 +4086,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Макс STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Дальность: {GOLD}{COMMA} клет{P ка ки ок} STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Тип возд. судна: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Все типы грузов +STR_CARGO_TYPE_FILTER_FREIGHT :Груз +STR_CARGO_TYPE_FILTER_NONE :Нет + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Список железнодорожного транспорта - щёлкните для получения информации. Ctrl+щелчок скроет/покажет ТС. STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Список автотранспорта - щёлкните для получения информации. Ctrl+щелчок скроет/покажет выбранный автомобиль. @@ -4221,7 +4267,7 @@ STR_ENGINE_PREVIEW_SHIP :судно STR_ENGINE_PREVIEW_SHIP.gen :судна 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_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Цена: {0:CURRENCY_LONG} Масса: {1:WEIGHT_SHORT}{}Скорость: {2:VELOCITY} Мощность: {3: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_CAP_CAP_RUNCOST :{BLACK}Цена: {CURRENCY_LONG} Макс. скорость: {VELOCITY}{}Тип: {STRING}{}Ёмкость: {CARGO_LONG}, {CARGO_LONG}{}Стоимость обслуж.: {CURRENCY_LONG}/год STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Цена: {CURRENCY_LONG} Макс. скорость: {VELOCITY}{}Тип: {STRING}{}Ёмкость: {CARGO_LONG}{}Стоимость обслуж.: {CURRENCY_LONG}/год @@ -4384,12 +4430,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Масс STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Масса: {LTBLUE}{WEIGHT_SHORT} {BLACK}Мощность: {LTBLUE}{POWER}{BLACK} Макс. скорость: {LTBLUE}{VELOCITY} {BLACK}Макс. ТУ: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Прибыль в этом году: {LTBLUE}{CURRENCY_LONG} (в прошлом году: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Прибыль в этом году: {LTBLUE}{CURRENCY_LONG} (в прошлом году: {CURRENCY_LONG}) {BLACK}Мин. удельная мощн.: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Надёжность: {LTBLUE}{COMMA}% {BLACK}Поломок после ТО: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Построен в {LTBLUE}{NUM} г.{BLACK} Стоимость: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Ёмкость: {LTBLUE}отсутствует{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Ёмкость: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Ёмкость: {LTBLUE}{CARGO_LONG}{3:STRING} (×{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Ёмкость: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Ёмкость: {LTBLUE}{0:CARGO_LONG}{3:STRING} (×{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Ёмкость: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Выручка перевозки: {LTBLUE}{CURRENCY_LONG} @@ -4658,19 +4705,19 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Нача STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Выберите начальную дату для этого графика. Ctrl+щелчок равномерно распределит все транспортные средства, следующие по этому маршруту, если время движения по нему полностью рассчитано. STR_TIMETABLE_CHANGE_TIME :{BLACK}Изменить время -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Изменить время для выделенного задания +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Изменить время исполнения выделенного задания. Ctrl+щелчок устанавливает время для всех заданий. STR_TIMETABLE_CLEAR_TIME :{BLACK}Сбросить время -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Сбросить время в выделенном задании +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Сбросить время в выделенном задании. Ctrl+щелчок - сбросить время во всех заданиях. STR_TIMETABLE_CHANGE_SPEED :{BLACK}Изменить огранич. скорости -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Изменить ограничение скорости движения для выбранного задания +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Изменить ограничение скорости движения для выбранного задания. Ctrl+щелчок устанавливает скорость для всех заданий. STR_TIMETABLE_CLEAR_SPEED :{BLACK}Сбросить огранич. скорости -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Сбросить ограничение скорости движения для выделенного задания +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Сбросить ограничение скорости движения для выделенного задания. Ctrl+щелчок - сбросить время для всех заданий. STR_TIMETABLE_RESET_LATENESS :{BLACK}Сбросить счетчик опозд. -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Сбросить счётчик отклонения от графика, чтобы транспорт снова считался приходящим вовремя +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Сбросить счётчик опоздания, чтобы ТС считалось идущим по графику. Ctrl+щелчок сбросит счётчики у всей группы, так что последнее ТС будет идти по графику, а остальные - раньше графика. STR_TIMETABLE_AUTOFILL :{BLACK}Авторасчёт STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Заполнить график автоматически временем, затраченным на движение в следующей поездке. Ctrl+щелчок - не изменять время ожидания. @@ -4717,12 +4764,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Один STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Окно отладки ИИ / скрипта доступно только для сервера # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Конфигурация ИИ / скрипта +STR_AI_CONFIG_CAPTION_AI :{WHITE}Настройки ИИ +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Настройки игровых скриптов STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Игровой скрипт, который будет загружен в следующей игре STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Модули ИИ, которые будут загружены в следующей игре STR_AI_CONFIG_HUMAN_PLAYER :Человек STR_AI_CONFIG_RANDOM_AI :Случайный ИИ STR_AI_CONFIG_NONE :(нет) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Максимальное количество конкурентов: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Вверх STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Переместить этот модуль ИИ вверх по списку @@ -4730,12 +4779,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Вниз STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Переместить этот модуль ИИ вниз по списку STR_AI_CONFIG_GAMESCRIPT :{SILVER}Игровой скрипт +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Параметры STR_AI_CONFIG_AI :{SILVER}ИИ -STR_AI_CONFIG_CHANGE :{BLACK}Выбрать {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :ИИ -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Игровой скрипт +STR_AI_CONFIG_CHANGE_AI :{BLACK}ИИ +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Игровой скрипт STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Загрузить другой скрипт STR_AI_CONFIG_CONFIGURE :{BLACK}Конфигурация STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Настроить параметры скрипта @@ -4763,10 +4811,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Сним STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Снимок карты высот STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Снимок миникарты -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}Параметры {STRING} STR_AI_SETTINGS_CAPTION_AI :ИИ -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Игровой скрипт +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :игровых скриптов STR_AI_SETTINGS_CLOSE :{BLACK}Закрыть STR_AI_SETTINGS_RESET :{BLACK}Сброс STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4930,6 +4978,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... сл STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Невозможно создать предприятия... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Здесь нельзя создать {STRING}... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Построить это предприятие невозможно... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Не удалось разведать месторождение... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... слишком близко к другому предприятию STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... сначала постройте город STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... такой объект уже есть в городе @@ -4944,6 +4993,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... ле STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... можно строить только выше снеговой линии STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... можно строить только ниже снеговой линии +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Геологоразведка не принесла результатов; попробуйте снова. +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Нет подходящего места для геологоразведки. STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Нет подходящего места для {STRING.gen} STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Измените настройки создания карты для получения более подходящей карты @@ -5111,6 +5162,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Объе STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... штаб-квартира компании мешает STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Невозможно купить эту землю... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... вы и так уже владеете этим! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... достигнуто максимальное количество объектов # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Невозможно создать группу... @@ -5183,6 +5235,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Нево STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... транспортное средство уничтожено +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... не все ТС идентичны друг другу + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Все транспортные средства будут недоступны STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Измените конфигурацию модуля NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Нет доступных транспортных средств @@ -5209,6 +5263,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Нево STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... ТС не может достигнуть всех станций STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... ТС не может достигнуть этой станции STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... ТС с общим маршрутом не может достигнуть этой станции +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... не у всех ТС одинаковый маршрут +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... не у всех ТС одинаковый общий маршрут STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Невозможно использовать общий маршрут... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Невозможно создать индивидуальный маршрут... @@ -5216,6 +5272,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Нево STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... слишком далеко от предыдущей точки STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... дальность полёта воздушного судна недостаточна +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Железнодорожные станции отсутствуют +STR_ERROR_NO_BUS_STATION :{WHITE}Автобусные остановки отсутствуют +STR_ERROR_NO_TRUCK_STATION :{WHITE}Грузовые терминалы отсутствуют +STR_ERROR_NO_DOCK :{WHITE}Пристани отсутствуют +STR_ERROR_NO_AIRPORT :{WHITE}Аэропорты и вертолётные площадки отсутствуют +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Отсутствуют остановки с подходящим типом дороги +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Отсутствуют остановки с подходящим типом трамвайных путей +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Отсутствуют остановки, способные обслуживать сочленённые транспортные средства.{}Для такого транспорта требуются сквозные остановки; оконечные не подходят. +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Этот самолёт не может приземлиться на вертолётной площадке +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Этот вертолёт не может приземлиться в данном аэропорту +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Маршрутные точки отсутствуют +STR_ERROR_NO_BUOY :{WHITE}Буи отсутствуют + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Не удалось составить график движения для этого транспорта... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Транспорт может ждать только на станции diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index b309b58e6172a..5e8f262e94107 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -307,7 +307,7 @@ STR_QUANTITY_TOYS :{COMMA} igrač{ STR_QUANTITY_SWEETS :{COMMA} džak{P "" a ova} slatkiša STR_QUANTITY_COLA :{VOLUME_LONG} kole STR_QUANTITY_CANDYFLOSS :{WEIGHT_LONG} šećerne vune -STR_QUANTITY_BUBBLES :{COMMA} balon{P "" a a} +STR_QUANTITY_BUBBLES :{COMMA} mehurić{P "" a a} STR_QUANTITY_TOFFEE :{WEIGHT_LONG} karamele STR_QUANTITY_BATTERIES :{COMMA} baterij{P a e a} STR_QUANTITY_PLASTIC :{VOLUME_LONG} plastike @@ -358,7 +358,7 @@ STR_LITERS :{COMMA} lit{P r STR_ITEMS :{COMMA} komad{P "" a a} STR_CRATES :{COMMA} sanduk{P "" a a} -STR_COLOUR_DEFAULT :Osnovna +STR_COLOUR_DEFAULT :Podrazumevana ###length 17 STR_COLOUR_DARK_BLUE :Tamno plava STR_COLOUR_PALE_GREEN :Bledo zelena @@ -388,6 +388,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}ks STR_UNITS_POWER_METRIC :{COMMA}ks STR_UNITS_POWER_SI :{COMMA}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -413,45 +423,45 @@ STR_UNITS_HEIGHT_METRIC :{COMMA} m STR_UNITS_HEIGHT_SI :{COMMA} m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filtriraj po: -STR_LIST_FILTER_OSKTITLE :{BLACK}Unesite tekst za filter -STR_LIST_FILTER_TOOLTIP :{BLACK}Unesite ključnu reč kako bi se filtriralo spisak +STR_LIST_FILTER_TITLE :{BLACK}Pretraga: +STR_LIST_FILTER_OSKTITLE :{BLACK}Unesi jednu ili više ključnih reči za pretragu liste +STR_LIST_FILTER_TOOLTIP :{BLACK}Unesi jednu ili više ključnih reči za pretragu liste STR_TOOLTIP_GROUP_ORDER :{BLACK}Izaberi red sortiranja -STR_TOOLTIP_SORT_ORDER :{BLACK}Odaberite način sortiranja (opadajući/rastući) -STR_TOOLTIP_SORT_CRITERIA :{BLACK}Odaberite kriterijum za sortiranje -STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Izaberite način filtriranja +STR_TOOLTIP_SORT_ORDER :{BLACK}Odaberi način sortiranja (opadajući/rastući) +STR_TOOLTIP_SORT_CRITERIA :{BLACK}Odaberi kriterijum za sortiranje +STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Odaberi način filtriranja STR_BUTTON_SORT_BY :{BLACK}Sortiraj po STR_BUTTON_CATCHMENT :{BLACK}Pokrivenost STR_TOOLTIP_CATCHMENT :{BLACK}Uključi/isključi prikaz zahvaćenog područja STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Zatvori prozor -STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Naslov - povucite mišem da biste pomerili prozor +STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Naslov - povuci mišem radi pomeranja prozora STR_TOOLTIP_SHADE :{BLACK}Zamotaj prozor - prikazuje se samo naslov STR_TOOLTIP_DEBUG :{BLACK}Prikazuje NewGRF podatake o otklanjanju grešaka -STR_TOOLTIP_DEFSIZE :{BLACK}Menja veličinu prozora na podrazumevanu. Ctrl+Klik da sačuvate tekuću veličinu kao podrazumevanu -STR_TOOLTIP_STICKY :{BLACK}Markirajte ovaj prozor kao ne za zatvaranje tipkom 'Zatvaranje svih prozora'. Uz Ctrl+klik to stanje će biti zapamćeno. -STR_TOOLTIP_RESIZE :{BLACK}Pritisnite i povucite kako bi prozor promenio veličinu +STR_TOOLTIP_DEFSIZE :{BLACK}Menja veličinu prozora na podrazumevanu. Ctrl+klik čuva tekuću veličinu kao podrazumevanu +STR_TOOLTIP_STICKY :{BLACK}Markiraj ovaj prozor kao nezatvoriv tasterom 'Zatvaranje svih prozora'. Uz Ctrl+klik to stanje će biti zapamćeno kao podrazumevano +STR_TOOLTIP_RESIZE :{BLACK}Pritisni i povuci za promenu veličine prozora STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Izbor velikog/malog prozora STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST :{BLACK}Skrol - pomera spisak gore/dole STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Klizač - pomera spisak levo/desno -STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Uklanja građevinu i dr. na kvadratu tla. Ctrl obeležava dijagonalno područje. Shift prebacuje između izgradnje i prikaza procene troškova +STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Uklanja zgrade i ostalo na kvadratu tla. Ctrl dijagonalno obeležava područje. Shift prebacuje između izgradnje i prikaza procene troškova # Show engines button ###length VEHICLE_TYPES STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN :{BLACK}Prikaži skriveni vozovi STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE :{BLACK}Prikaži skrivena drumska vozila STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP :{BLACK}Prikaži skrivene brodove -STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT :{BLACK}Prikaži skrivene letilice +STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT :{BLACK}Prikaži skrivene letelice ###length VEHICLE_TYPES STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP :{BLACK}Omogućavanje ovog podešavanja znači da će se i skriveni vozevi biti prikazani. STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE_TOOLTIP :{BLACK}Omugućavanjem ovog dogmeta, sakrivena drumska vozila će takođe biti prikazan STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP_TOOLTIP :{BLACK}Omugućavanjem ovog dogmeta, sakriveni brod će takođe biti prikazan -STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Omugućavanjem ovog dogmeta, sakriveni avion će takođe biti prikazan +STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Omugućavanjem ovog dugmeta, sakriveni avion će takođe biti prikazan # Query window -STR_BUTTON_DEFAULT :{BLACK}Prvobitno +STR_BUTTON_DEFAULT :{BLACK}Podrazumevano STR_BUTTON_CANCEL :{BLACK}Otkaži STR_BUTTON_OK :{BLACK}OK STR_WARNING_PASSWORD_SECURITY :{YELLOW}Upozorenje: Administratori servera će moći da pročitaju sav tekst koji je ovde unesen. @@ -468,7 +478,7 @@ STR_MEASURE_AREA_HEIGHTDIFF :{BLACK}Područj # These are used in buttons -STR_SORT_BY_CAPTION_NAME :{BLACK}Imenu +STR_SORT_BY_CAPTION_NAME :{BLACK}Nazivu STR_SORT_BY_CAPTION_DATE :{BLACK}Datumu # These are used in dropdowns STR_SORT_BY_NAME :Nazivu @@ -477,10 +487,10 @@ STR_SORT_BY_TYPE :Vrsti STR_SORT_BY_TRANSPORTED :Prevezeno STR_SORT_BY_NUMBER :Broju STR_SORT_BY_PROFIT_LAST_YEAR :Zaradi prošle godine -STR_SORT_BY_PROFIT_THIS_YEAR :Dobit ove godine +STR_SORT_BY_PROFIT_THIS_YEAR :Zaradi ove godine STR_SORT_BY_AGE :Starosti STR_SORT_BY_RELIABILITY :Pouzdanosti -STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Ukupnoj nosivosti po vrsti tovara +STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Ukupnoj nosivosti po vrsti tereta STR_SORT_BY_MAX_SPEED :Najvećoj brzini STR_SORT_BY_MODEL :Modelu STR_SORT_BY_VALUE :Vrednosti @@ -506,8 +516,8 @@ STR_SORT_BY_RATING :Rejtingu STR_SORT_BY_NUM_VEHICLES :Broj vozila STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR :Ukupna zarada prošle godine STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR :Ukupna zarada ove godine -STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :Prosečna dobit prošle godine -STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR :Prosečna dobit ove godine +STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :Prosečna zarada prošle godine +STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR :Prosečna zarada ove godine # Group by options for vehicle list STR_GROUP_BY_NONE :Nijedan @@ -519,10 +529,10 @@ STR_GOTO_ORDER_VIEW_TOOLTIP :{BLACK}Otvori p # Tooltips for the main toolbar ###length 31 -STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}Pauziranje partije +STR_TOOLBAR_TOOLTIP_PAUSE_GAME :{BLACK}Pauziranje igre STR_TOOLBAR_TOOLTIP_FORWARD :{BLACK}Ubrzavanje igre STR_TOOLBAR_TOOLTIP_OPTIONS :{BLACK}Opcije -STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Čuvanje pozicije, napuštanje partije, izlaz +STR_TOOLBAR_TOOLTIP_SAVE_GAME_ABANDON_GAME :{BLACK}Čuvanje pozicije, napuštanje igre, izlaz STR_TOOLBAR_TOOLTIP_DISPLAY_MAP :{BLACK}Prikazuje kartu, dodatne poglede, spisak znakova STR_TOOLBAR_TOOLTIP_DISPLAY_TOWN_DIRECTORY :{BLACK}Prikaži popis naselja STR_TOOLBAR_TOOLTIP_DISPLAY_SUBSIDIES :{BLACK}Prikaži subvencije @@ -535,9 +545,9 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_GRAPHS :{BLACK}Prikaži STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Prikaži tabele lige preduzeća STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Finansiranje izgradnje nove fabrike, spisak svih fabrika STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Prikaži spisak svih vozova preduzeća. Ctrl+klik uključuje prikaz spiska grupe/vozila -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Prikaži spisak svih drumskih vozila preduzeća. Ctrl+Klik uključuje otvaranje spiska grupe/vozila -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Prikaži spisak svih brodova preduzeća. Ctrl+Klik uključuje otvaranje spiska grupe/vozila -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Prikaži spisak svih letelica preduzeća. Ctrl+Klik uključuje otvaranje spiska grupe/vozila +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Prikaži spisak svih drumskih vozila preduzeća. Ctrl+klik uključuje otvaranje spiska grupe/vozila +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Prikaži spisak svih brodova preduzeća. Ctrl+klik uključuje otvaranje spiska grupe/vozila +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Prikaži spisak svih letelica preduzeća. Ctrl+klik uključuje otvaranje spiska grupe/vozila STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Približi pogled STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Udalji pogled STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Izgradnja železničke pruge @@ -554,10 +564,10 @@ STR_TOOLBAR_TOOLTIP_SWITCH_TOOLBAR :{BLACK}Zamenjuj # Extra tooltips for the scenario editor toolbar STR_SCENEDIT_TOOLBAR_TOOLTIP_SAVE_SCENARIO_LOAD_SCENARIO :{BLACK}Čuvanje scenarija, učitavanje scenarija, napuštanje editora, izlaz STR_SCENEDIT_TOOLBAR_OPENTTD :{YELLOW}OpenTTD -STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR :{YELLOW}Editor scenarija +STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR :{YELLOW}Uređivač scenarija STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD :{BLACK}Pomeranje datuma početka za jednu godinu unazad STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD :{BLACK}Pomeranje datuma početka za jednu godinu unapred -STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}Kliknite za unos početne godine +STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE :{BLACK}Klikni za unos početne godine STR_SCENEDIT_TOOLBAR_TOOLTIP_DISPLAY_MAP_TOWN_DIRECTORY :{BLACK}Prikazuje kartu, popis naselja STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Oblikovanje reljefa STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Stvaranje naselja @@ -566,24 +576,25 @@ STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Izgradnj STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Igradnja tramvajskog sistema STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Sadnja drveća. Shift prebacuje između sadnje i prikaza procene troškova STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Postavljanje znaka -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Postavlja objekat. Shift prebacuje između postavljanja i prikaza procene troškova +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Postavlja objekat. Ctrl dijagonalno obeležava područje. Shift prebacuje između postavljanja i prikaza procene troškova # Scenario editor file menu ###length 7 STR_SCENEDIT_FILE_MENU_SAVE_SCENARIO :Sačuvaj scenario STR_SCENEDIT_FILE_MENU_LOAD_SCENARIO :Učitaj scenario STR_SCENEDIT_FILE_MENU_SAVE_HEIGHTMAP :Sačuvaj elevacionu kartu -STR_SCENEDIT_FILE_MENU_LOAD_HEIGHTMAP :Učitaj elevacionu kartu +STR_SCENEDIT_FILE_MENU_LOAD_HEIGHTMAP :Učitaj visinsku kartu STR_SCENEDIT_FILE_MENU_QUIT_EDITOR :Napusti editor STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Izađi # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Opcije STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Podešavanja -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Podešavanja VI/Skripte partije -STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF podešavanja +STR_SETTINGS_MENU_AI_SETTINGS :Podešavanja VI +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Podešavanja skripte +STR_SETTINGS_MENU_NEWGRF_SETTINGS :Podešavanja NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opcije transparentnosti STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Prikazana imena naselja STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED :Prikazana imena stanica @@ -598,8 +609,8 @@ STR_SETTINGS_MENU_TRANSPARENT_SIGNS :Transparentni z # File menu ###length 5 STR_FILE_MENU_SAVE_GAME :Sačuvaj igru -STR_FILE_MENU_LOAD_GAME :Učitaj partiju -STR_FILE_MENU_QUIT_GAME :Napusti partiju +STR_FILE_MENU_LOAD_GAME :Učitaj igru +STR_FILE_MENU_QUIT_GAME :Napusti igru STR_FILE_MENU_SEPARATOR : STR_FILE_MENU_EXIT :Izađi @@ -623,10 +634,10 @@ STR_SUBSIDIES_MENU_SUBSIDIES :Subvencije ###length 6 STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH :Grafikon operativnog profita STR_GRAPH_MENU_INCOME_GRAPH :Grafikon prihoda -STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH :Grafikon dostavljenog tovara +STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH :Grafikon dostavljenog tereta STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH :Grafikon istorije učinka STR_GRAPH_MENU_COMPANY_VALUE_GRAPH :Grafikon vrednosti preduzeća -STR_GRAPH_MENU_CARGO_PAYMENT_RATES :Stope naplate tovara +STR_GRAPH_MENU_CARGO_PAYMENT_RATES :Stope naplate tereta # Company league menu ###length 3 @@ -681,11 +692,11 @@ STR_NEWS_MENU_DELETE_ALL_MESSAGES :Obriši sve por STR_ABOUT_MENU_LAND_BLOCK_INFO :Podaci o zemljištu STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Uključi/isključi konzolu -STR_ABOUT_MENU_AI_DEBUG :Korekcija veštačke inteligencije / skripte igre +STR_ABOUT_MENU_AI_DEBUG :Korekcija VI / skripte igre STR_ABOUT_MENU_SCREENSHOT :Sačuvaj sliku STR_ABOUT_MENU_SHOW_FRAMERATE :Prikaži brzinu smenjivaja slika STR_ABOUT_MENU_ABOUT_OPENTTD :O OpenTTD-u -STR_ABOUT_MENU_SPRITE_ALIGNER :Poravnjavanje sprajta +STR_ABOUT_MENU_SPRITE_ALIGNER :Poravnavanje sprajta STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Uključi/isključi granične linije STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Uključi/Isključi bojenje nesređenih blokova @@ -778,25 +789,25 @@ STR_GRAPH_Y_LABEL_NUMBER :{TINY_FONT}{COM STR_GRAPH_OPERATING_PROFIT_CAPTION :{WHITE}Grafikon operativnog profita STR_GRAPH_INCOME_CAPTION :{WHITE}Grafikon prihoda -STR_GRAPH_CARGO_DELIVERED_CAPTION :{WHITE}Isporučene jedinice tovara -STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION :{WHITE}Rejting učinka preduzeća (najveći je 1000) +STR_GRAPH_CARGO_DELIVERED_CAPTION :{WHITE}Isporučene jedinice tereta +STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION :{WHITE}Ocena učinka preduzeća (najveći je 1000) STR_GRAPH_COMPANY_VALUES_CAPTION :{WHITE}Vrednosti preduzeća -STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Stope prihoda od tovara +STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Stope prihoda od tereta STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL :{TINY_FONT}{BLACK}Dana u tranzitu -STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Isplata za dostavu 10 jedinica (ili 10 hiljada litara) tovara na razdaljinu od 20 kvadrata +STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Isplata za dostavu 10 jedinica (ili 10 hiljada litara) tereta na razdaljinu od 20 kvadrata STR_GRAPH_CARGO_ENABLE_ALL :{TINY_FONT}{BLACK}Prikaži sve STR_GRAPH_CARGO_DISABLE_ALL :{TINY_FONT}{BLACK}Sakri sve -STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}Prikazuje sve vrste tovara na grafikonu prihoda -STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Sakrij sve vrste tovara na grafikonu prihoda -STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Uključi/Isključi grafikone po vrsti tovara +STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}Prikazuje sve vrste tereta na grafikonu prihoda +STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Sakrij sve vrste tereta na grafikonu prihoda +STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Uključi/Isključi grafikone po vrsti tereta STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLACK}{STRING} STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Prikaži detaljne ocene učinka # Graph key window STR_GRAPH_KEY_CAPTION :{WHITE}Legenda grafikona preduzeća -STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP :{BLACK}Kliknite ovde za uključenje/isključenje prikaza preduzeća na grafikonu +STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP :{BLACK}Klikni ovde za uključenje i isključenje prikaza preduzeća na grafikonu # Company league window STR_COMPANY_LEAGUE_TABLE_CAPTION :{WHITE}Tabela lige preduzeća @@ -822,7 +833,7 @@ STR_PERFORMANCE_DETAIL_SELECT_COMPANY_TOOLTIP :{BLACK}Prikazuj ###length 10 STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vozila: STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stanice: -STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Najmanja dobit: +STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Najmanja zarada: STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Najmanji prihod: STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Najviši prihod: STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Dostavljeno: @@ -832,11 +843,11 @@ STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Zajam: STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Ukupno: ###length 10 -STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP :{BLACK}Broj vozila koja su imala dobit prošle godine. Ovo uključuje drumska, železnička vozila, brodove i letilice +STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP :{BLACK}Broj vozila koja su imala zaradu prošle godine. Ovo uključuje drumska, železnička vozila, brodove i letelice STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP :{BLACK}Broj nedavno opsluženih stanica. Posebno se broji svaki deo stanice (npr. železničko, autobusko stajalište ili aerodrom) -STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP :{BLACK}Dobit vozila sa najmanjim prihodom (samo vozila starijih od 2 godine) -STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Zarađen novac u tromesečju sa najmanjom dobiti u proteklih 12 tromesečja -STR_PERFORMANCE_DETAIL_MAX_INCOME_TOOLTIP :{BLACK}Zarađen novac u tromesečju sa najvećom dobiti u proteklih 12 tromesečja +STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP :{BLACK}Zarada vozila sa najmanjim prihodom (samo vozila starijih od 2 godine) +STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Zarađen novac u tromesečju sa najmanjom zaradom u proteklih 12 tromesečja +STR_PERFORMANCE_DETAIL_MAX_INCOME_TOOLTIP :{BLACK}Zarađen novac u tromesečju sa najvećom zaradom u proteklih 12 tromesečja STR_PERFORMANCE_DETAIL_DELIVERED_TOOLTIP :{BLACK}Jedinica tereta dostavljenih u proteklih četiri tromesečja STR_PERFORMANCE_DETAIL_CARGO_TOOLTIP :{BLACK}Broj vrsta tereta dostavljenih u proteklom tromesečju STR_PERFORMANCE_DETAIL_MONEY_TOOLTIP :{BLACK}Količina novca koje ovo preduzeće ima u banci @@ -862,19 +873,19 @@ STR_MUSIC_TRACK :{TINY_FONT}{BLA STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Naziv STR_MUSIC_SHUFFLE :{TINY_FONT}{BLACK}Puštaj nasumično STR_MUSIC_PROGRAM :{TINY_FONT}{BLACK}Program -STR_MUSIC_TOOLTIP_SKIP_TO_PREVIOUS_TRACK :{BLACK}Skoči na prethodnu numeru u izboru -STR_MUSIC_TOOLTIP_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Skoči na sledeću numeru u izboru +STR_MUSIC_TOOLTIP_SKIP_TO_PREVIOUS_TRACK :{BLACK}Skoči na prethodnu numeru u odabiru +STR_MUSIC_TOOLTIP_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Skoči na sledeću numeru u odabiru STR_MUSIC_TOOLTIP_STOP_PLAYING_MUSIC :{BLACK}Prekini muziku STR_MUSIC_TOOLTIP_START_PLAYING_MUSIC :{BLACK}Pusti muziku -STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Pomerajte klizače za promenu jačine muzike i zvučnih efekata +STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Pomeranjem klizača porešava se jačina muzike i zvučnih efekata STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Izaberi program 'sve numere' STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC :{BLACK}Izaberi program 'stari zvuk' STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC :{BLACK}Izaberi program 'novi zvuk' STR_MUSIC_TOOLTIP_SELECT_EZY_STREET_STYLE :{BLACK}Izbor programa 'lagane stvari' STR_MUSIC_TOOLTIP_SELECT_CUSTOM_1_USER_DEFINED :{BLACK}Izaberi program 'Lični raspored 1' (korisnički-definisan) STR_MUSIC_TOOLTIP_SELECT_CUSTOM_2_USER_DEFINED :{BLACK}Izaberi program 'Lični raspored 2' (korisnički-definisan) -STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Uključi/isključi nasumičan izbor pri puštanju -STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Prikaži prozor za izbor muzičkih numera +STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Uključi/isključi nasumičan redosled pri puštanju +STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Prikaži prozor za odabir muzičkih numera # Playlist window STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE} Muzički program - '{STRING}' @@ -884,9 +895,9 @@ STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLA STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Obriši STR_PLAYLIST_CHANGE_SET :{BLACK}Promeni set STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Obriši tekući program (samo korisnički-definisani programi) -STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Promenite izbor muzike na drugi instalirani skup +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Promeni odabir muzike na drugi instalirani skup STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Klik na numeru je dodaje u tekući program (samo za korisnički-definisane programe) -STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Pritisnite na muzičku numeru kako biste je uklonili sa trenutnog rasporeda (samo za Custom1 ili Custom2) +STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Klik na muzičku numeru radi uklanjanja sa trenutnog rasporeda (samo za Custom1 ili Custom2) # Highscore window STR_HIGHSCORE_TOP_COMPANIES_WHO_REACHED :{BIG_FONT}{BLACK}Najbolja preduzeća koja su dostigla {NUM} @@ -930,14 +941,14 @@ STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP :{BLACK}Prikazuj STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Prikazuje putne rute na karti STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP :{BLACK}Prikazuje vegetaciju na karti STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Prikazuje vlasništva na karti -STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Klikom na industriju se prikazuju/ne prikazuju njene fabrike. Ctrl+Klik prikazuje fabrike samo odabrane. Sa ponovnim Ctrl+Klik prikazuju se fabrike svih industrija -STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Klikom na preduzeće se prikazuje/ne prikazuje njeno vlasništvo. Ctrl+Klik prikazuje vlasništvo samo odabranog. Sa ponovnim Ctrl+Klik prikazuju se vlasništva svih preduzeća -STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Klikom na teret se prikazuje/neprikazuje vlasnik tereta. Ctrl+Klik onemogućava sve terete osim odabranog. Sa ponovnim Ctrl+Klik omogućava sve terete. +STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Klikom na vrstu se uključuje i isključuje prikaz njenih fabrika. Ctrl+klik prikazuje fabrike samo odabrane vrste. Ponovni Ctrl+klik prikazuje sve vrste fabrika +STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Klikom na preduzeće se uključuje i isključuje prikaz njegovog vlasništva. Ctrl+klik prikazuje vlasništvo samo odabranog. Ponovni Ctrl+klik prikazuju se vlasništva svih preduzeća +STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Klikom na teret se uključuje i isključuje prikaz vlasnika tereta. Ctrl+klik onemogućava sve terete osim odabranog. Ponovni Ctrl+klik omogućava sve terete STR_SMALLMAP_LEGENDA_ROADS :{TINY_FONT}{BLACK}Putevi STR_SMALLMAP_LEGENDA_RAILROADS :{TINY_FONT}{BLACK}Pruge STR_SMALLMAP_LEGENDA_STATIONS_AIRPORTS_DOCKS :{TINY_FONT}{BLACK}Stanice/Aerodromi/Pristaništa -STR_SMALLMAP_LEGENDA_BUILDINGS_INDUSTRIES :{TINY_FONT}{BLACK}Građevine/Industrije +STR_SMALLMAP_LEGENDA_BUILDINGS_INDUSTRIES :{TINY_FONT}{BLACK}Građevine/Fabrike STR_SMALLMAP_LEGENDA_VEHICLES :{TINY_FONT}{BLACK}Vozila STR_SMALLMAP_LEGENDA_TRAINS :{TINY_FONT}{BLACK}Vozovi STR_SMALLMAP_LEGENDA_ROAD_VEHICLES :{TINY_FONT}{BLACK}Drumska vozila @@ -960,7 +971,7 @@ STR_SMALLMAP_LEGENDA_ROCKS :{TINY_FONT}{BLA STR_SMALLMAP_LEGENDA_WATER :{TINY_FONT}{BLACK}Voda STR_SMALLMAP_LEGENDA_NO_OWNER :{TINY_FONT}{BLACK}Nema vlasnika STR_SMALLMAP_LEGENDA_TOWNS :{TINY_FONT}{BLACK}Naselja -STR_SMALLMAP_LEGENDA_INDUSTRIES :{TINY_FONT}{BLACK}Industrije +STR_SMALLMAP_LEGENDA_INDUSTRIES :{TINY_FONT}{BLACK}Fabrike STR_SMALLMAP_LEGENDA_DESERT :{TINY_FONT}{BLACK}Pustinja STR_SMALLMAP_LEGENDA_SNOW :{TINY_FONT}{BLACK}Sneg @@ -975,7 +986,7 @@ STR_SMALLMAP_ENABLE_ALL :{BLACK}Sva prik STR_SMALLMAP_SHOW_HEIGHT :{BLACK}Prikaži visine STR_SMALLMAP_TOOLTIP_DISABLE_ALL_INDUSTRIES :{BLACK}Sakrij sve fabrike na karti STR_SMALLMAP_TOOLTIP_ENABLE_ALL_INDUSTRIES :{BLACK}Prikaži na karti sve fabrike -STR_SMALLMAP_TOOLTIP_SHOW_HEIGHT :{BLACK}Promena prikaza elevacije +STR_SMALLMAP_TOOLTIP_SHOW_HEIGHT :{BLACK}Promena prikaza uzvišenja STR_SMALLMAP_TOOLTIP_DISABLE_ALL_COMPANIES :{BLACK}Uklanja prikaz vlasništva preduzeća sa karte STR_SMALLMAP_TOOLTIP_ENABLE_ALL_COMPANIES :{BLACK}Prikazuje vlasništvo preduzeća na karti STR_SMALLMAP_TOOLTIP_DISABLE_ALL_CARGOS :{BLACK}Ne prikazuje nijedan teret na mapi @@ -987,7 +998,7 @@ STR_STATUSBAR_COMPANY_NAME :{SILVER}- - {C STR_STATUSBAR_PAUSED :{YELLOW}* * PAUZA * * STR_STATUSBAR_PAUSED_LINK_GRAPH :{ORANGE}* * PAUZIRANO (čeka se dopuna grafa) * * STR_STATUSBAR_AUTOSAVE :{RED}AUTO-ČUVANJE -STR_STATUSBAR_SAVING_GAME :{RED}* * ČUVAM PARTIJU * * +STR_STATUSBAR_SAVING_GAME :{RED}* * ČUVANJE IGRE * * STR_STATUSBAR_SPECTATOR :{WHITE}(posmatrač) @@ -1005,13 +1016,13 @@ STR_NEWS_FIRST_TRUCK_ARRIVAL :{BIG_FONT}{BLAC STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL :{BIG_FONT}{BLACK}Građani proslavljaju . . .{}Dolazak prvog tramvaja na stanicu {STATION}! STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL :{BIG_FONT}{BLACK}Građani proslavljaju . . .{}Dolazak prvog teretnog tamvaja na stanicu {STATION}! STR_NEWS_FIRST_SHIP_ARRIVAL :{BIG_FONT}{BLACK}Građani proslavljaju . . .{}Dolazak prvog broda na pristanište {STATION}! -STR_NEWS_FIRST_AIRCRAFT_ARRIVAL :{BIG_FONT}{BLACK}Građani proslavljaju . . .{}Dolazak prve letilice na aerodrom {STATION}! +STR_NEWS_FIRST_AIRCRAFT_ARRIVAL :{BIG_FONT}{BLACK}Građani proslavljaju . . .{}Dolazak prve letelice na aerodrom {STATION}! STR_NEWS_TRAIN_CRASH :{BIG_FONT}{BLACK}Sudar vozova!{}{COMMA} {P "" su je} poginu{P o la lo} u eksploziji nakon sudara STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER :{BIG_FONT}{BLACK}Saobraćajna nesreća!{}Vozač je poginuo u eksploziji nakon sudara sa vozom STR_NEWS_ROAD_VEHICLE_CRASH :{BIG_FONT}{BLACK}Saobraćajna nesreća!{}{COMMA} {P "" je su} poginu{P o la lo} u eksploziji nakon sudara sa vozom STR_NEWS_AIRCRAFT_CRASH :{BIG_FONT}{BLACK}Avionska nesraća!{}{COMMA} {P "" su je} poginu{P o la lo} u eksploziji kod {STATION} -STR_NEWS_PLANE_CRASH_OUT_OF_FUEL :{BIG_FONT}{BLACK}Avionska nesreća!{}Letilici je nestalo goriva, {COMMA} {P "" su je} poginu{P o la lo} u padu! +STR_NEWS_PLANE_CRASH_OUT_OF_FUEL :{BIG_FONT}{BLACK}Avionska nesreća!{}Letelici je nestalo goriva, {COMMA} {P "" su je} poginu{P o la lo} u padu! STR_NEWS_DISASTER_ZEPPELIN :{BIG_FONT}{BLACK}Cepelin se srušio kod {STATION}! STR_NEWS_DISASTER_SMALL_UFO :{BIG_FONT}{BLACK}Drumskom vozilo uništeno pri sudaru sa 'NLO'! @@ -1033,7 +1044,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(vlasnik) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{STRING} je sponzorisao izgradnju novog naselja {TOWN}! -STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Novi grad nazvan {TOWN} je sagrađen! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Novo naselje nazvano {TOWN} je sagrađeno! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}Nov{G i a o} {STRING} je u izgradnji kod naselja {TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}Nov{G i a o} {STRING} je posađen{G 0 "" a o} kod naselja {TOWN}! @@ -1042,9 +1053,9 @@ STR_NEWS_INDUSTRY_CLOSURE_GENERAL :{BIG_FONT}{BLAC STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS :{BIG_FONT}{BLACK}Problem sa zalihama je prouzrokovao da {STRING} objavi prestanak sa daljim radom! STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES :{BIG_FONT}{BLACK}Nedostatak obližnjeg drveća je prouzrokovao da {STRING} objavi prestanak sa daljim radom! -STR_NEWS_EURO_INTRODUCTION :{BIG_FONT}{BLACK}Evropska Monetarna Unija!{}{}Euro je uveden kao jedina valuta za uobičajene transakcije u vašoj zemlji! -STR_NEWS_BEGIN_OF_RECESSION :{BIG_FONT}{BLACK}Svetska recesija!{}{}Finansijski eksperti se plaše najgoreg dok ekonomija slabi sve više! -STR_NEWS_END_OF_RECESSION :{BIG_FONT}{BLACK}Recesija završena!{}{}Preokret u trgovini pruža podršku industrijama dok ekonomija jača! +STR_NEWS_EURO_INTRODUCTION :{BIG_FONT}{BLACK}Evropska Monetarna Unija!{}{}Evro je uveden kao jedina valuta za uobičajene transakcije u vašoj zemlji! +STR_NEWS_BEGIN_OF_RECESSION :{BIG_FONT}{BLACK}Svetska recesija!{}{}Finansijski stručnjaci se plaše najgoreg dok privreda sve više slabi! +STR_NEWS_END_OF_RECESSION :{BIG_FONT}{BLACK}Recesija završena!{}{}Preokret u trgovini pruža podršku fabrikama dok privreda jača! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL :{BIG_FONT}{BLACK}{INDUSTRY} povećava proizvodnju! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_COAL :{BIG_FONT}{BLACK}Pronađena nova ležišta uglja u {INDUSTRY}!{}Očekuje se duplo veća proizvodnja! @@ -1071,10 +1082,10 @@ STR_NEWS_PLANE_USES_TOO_SHORT_RUNWAY :{WHITE}{VEHICLE STR_NEWS_VEHICLE_IS_GETTING_OLD :{WHITE}{VEHICLE} zastareva STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD :{WHITE}{VEHICLE} previše zastareva -STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND :{WHITE}{VEHICLE} previše zastareva i hitno bi ga/je trebalo zameniti +STR_NEWS_VEHICLE_IS_GETTING_VERY_OLD_AND :{WHITE}{VEHICLE} previše zastareva i hitno bi ga treba zameniti STR_NEWS_TRAIN_IS_STUCK :{WHITE}{VEHICLE} ne može za dalje da pronađe put STR_NEWS_VEHICLE_IS_LOST :{WHITE}{VEHICLE} se izgubio -STR_NEWS_VEHICLE_IS_UNPROFITABLE :{WHITE}{VEHICLE} je prošle godine imao dobit od {CURRENCY_LONG} +STR_NEWS_VEHICLE_IS_UNPROFITABLE :{WHITE}{VEHICLE} je prošle godine imao zaradu od {CURRENCY_LONG} STR_NEWS_AIRCRAFT_DEST_TOO_FAR :{WHITE}{VEHICLE} ne može da stigne do sledeće destinacije, izvan dometa je STR_NEWS_ORDER_REFIT_FAILED :{WHITE}Neuspešna primena naredbe preuređivanja {VEHICLE} @@ -1093,23 +1104,23 @@ STR_NEWS_STATION_NOW_ACCEPTS_CARGO_AND_CARGO :{WHITE}{STATION STR_NEWS_OFFER_OF_SUBSIDY_EXPIRED :{BIG_FONT}{BLACK}Ponuda subvencije istekla:{}{}Prevoz {STRING.gen} iz {STRING} u {STRING} se više neće stimulisati STR_NEWS_SUBSIDY_WITHDRAWN_SERVICE :{BIG_FONT}{BLACK}Subvencija povučena:{}{}Usluga prevoza {STRING.gen} između stanica {STRING} i {STRING} više nije u opticaju -STR_NEWS_SERVICE_SUBSIDY_OFFERED :{BIG_FONT}{BLACK}Ponuda subvencije:{}{}Preduzeće koje prvo preveze {STRING.aku} od {STRING} do {STRING} stiče pravo na subvenciju u trajanju od {NUM} godina! +STR_NEWS_SERVICE_SUBSIDY_OFFERED :{BIG_FONT}{BLACK}Ponuda subvencije:{}{}Prvi {STRING} od {STRING} do {STRING} stiče pravo na subvenciju u trajanju od {NUM} godina! ###length 4 -STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF :{BIG_FONT}{BLACK}Subvencija odobrena preduzeću {STRING}!{}{}Za prevoz {STRING.gen} između stanica {STRING} i {STRING} zarada će vredeti 50% više u narednih {NUM} godina! -STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLACK}Subvencija odobrena preduzeću {STRING}!{}{}Za prevoz {STRING.gen} između stanica {STRING} i {STRING} zarada će vredeti dvostruko narednih {NUM} godina! -STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}Subvencija odobrena preduzeću {STRING}!{}{}Za prevoz {STRING.gen} između stanica {STRING} i {STRING} zarada će vredeti trostruko narednih {NUM} godina! -STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE :{BIG_FONT}{BLACK}Subvencija odobrena preduzeću {STRING}!{}{}Za prevoz {STRING.gen} između stanica {STRING} i {STRING} zarada će vredeti četvorostruko narednih {NUM} godina! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_HALF :{BIG_FONT}{BLACK}Subvencija odobrena preduzeću {STRING}!{}{}{STRING} od {STRING} do {STRING} će biti plaćena 50% više {NUM} godin{P e a a}! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_DOUBLE :{BIG_FONT}{BLACK}Subvencija odobrena preduzeću {STRING}!{}{}{STRING} od {STRING} do {STRING} će biti plaćena dvostruko {NUM} godin{P e a a}! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_TRIPLE :{BIG_FONT}{BLACK}Subvencija odobrena preduzeću {STRING}!{}{}{STRING} od {STRING} do {STRING} će biti plaćena trostruko {NUM} godin{P e a a}! +STR_NEWS_SERVICE_SUBSIDY_AWARDED_QUADRUPLE :{BIG_FONT}{BLACK}Subvencija odobrena preduzeću {STRING}!{}{}{STRING} od {STRING} do {STRING} će biti plaćena četvorostruko {NUM} godin{P e a a}! STR_NEWS_ROAD_REBUILDING :{BIG_FONT}{BLACK}{TOWN} - haos na ulicama!{}{}Program rekonstrukcije puteva sponzorisan od strane preduzeća {STRING} donosi vozačima 6 meseci agonije! STR_NEWS_EXCLUSIVE_RIGHTS_TITLE :{BIG_FONT}{BLACK}Prevoznički monopol! -STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLACK}Vlasti grada {TOWN} su potpisale ugovor sa preduzećem {STRING} o ekskluzivnom pravu prevoza na godinu dana! +STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLACK}Vlasti naselja {TOWN} su potpisale ugovor sa preduzećem {STRING} o ekskluzivnom pravu prevoza na godinu dana! # Extra view window STR_EXTRA_VIEWPORT_TITLE :{WHITE}Pogled{COMMA} STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK} Kopiraj u prozor za pogled STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Premešta pogled na trenutnu poziciju glavnog pogleda -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Promenite glavni prikaz -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopirajte lokaciju prozora za prikaz u glavnom prikazu +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Promeni glavni prikaz +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopiraj lokaciju prozora za prikaz u glavnom prikazu # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opcije @@ -1119,13 +1130,13 @@ STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Izbor va ###length 42 STR_GAME_OPTIONS_CURRENCY_GBP :Britanska funta (GBP) STR_GAME_OPTIONS_CURRENCY_USD :Dolar (USD) -STR_GAME_OPTIONS_CURRENCY_EUR :Euro (EUR) +STR_GAME_OPTIONS_CURRENCY_EUR :Evro (EUR) STR_GAME_OPTIONS_CURRENCY_JPY :Japanski jen (JPY) STR_GAME_OPTIONS_CURRENCY_ATS :Austrijski šiling (ATS) STR_GAME_OPTIONS_CURRENCY_BEF :Belgijski franak (BEF) STR_GAME_OPTIONS_CURRENCY_CHF :Švajcarski franak (CHF) STR_GAME_OPTIONS_CURRENCY_CZK :Češka kruna (CZK) -STR_GAME_OPTIONS_CURRENCY_DEM :Nemačka Marka (DEM) +STR_GAME_OPTIONS_CURRENCY_DEM :Nemačka marka (DEM) STR_GAME_OPTIONS_CURRENCY_DKK :Danska kruna (DKK) STR_GAME_OPTIONS_CURRENCY_ESP :Španska pezeta (ESP) STR_GAME_OPTIONS_CURRENCY_FIM :Finska marka (FIM) @@ -1147,7 +1158,7 @@ STR_GAME_OPTIONS_CURRENCY_BRL :Brazilski real STR_GAME_OPTIONS_CURRENCY_EEK :Estonska kruna (EEK) STR_GAME_OPTIONS_CURRENCY_LTL :Litvanski litas (LTL) STR_GAME_OPTIONS_CURRENCY_KRW :Južnokorejski von (KRW) -STR_GAME_OPTIONS_CURRENCY_ZAR :Južnoafrički Rand (ZAR) +STR_GAME_OPTIONS_CURRENCY_ZAR :Južnoafrički rand (ZAR) STR_GAME_OPTIONS_CURRENCY_CUSTOM :Sopstvena... STR_GAME_OPTIONS_CURRENCY_GEL :Gruzijski lari (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Iranski rijal (IRR) @@ -1160,36 +1171,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indijska rupija STR_GAME_OPTIONS_CURRENCY_IDR :Indonezijska rupija (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malezijski ringit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Levom stranom -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Desnom stranom - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Imena naselja: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Izaberi stil imena naselja - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Engleska (Originalna) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francuska -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Nemačka -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Engleska (Dodatna) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latinoamerička -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Šašava -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Švedska -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holandska -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finska -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Poljska -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovačka -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norveška -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Mađarska -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austrijanska -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumunska -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Češka -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Švajcarska -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danska -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turska -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italijanska -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalonska - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Auto čuvanje pozicije STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Izbor vremenskog intervala između dve automatski sačuvane pozicije @@ -1202,59 +1183,58 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_6_MONTHS :Svakih 6 meseci STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS :Svakih 12 meseci STR_GAME_OPTIONS_LANGUAGE :{BLACK}Jezik -STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Odaberite jezik koji će se koristiti +STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Odaberi jezik za interfejs STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM}% završeno) STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Ceo ekran -STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Pritisnite ovde kako biste igrali OpenTTD na celom ekranu +STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Označi ovde za igranje OpenTTD preko celog ekrana STR_GAME_OPTIONS_RESOLUTION :{BLACK}Veličina ekrana -STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}Odaberite željenu veličinu ekrana +STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}Odaberi željenu veličinu ekrana STR_GAME_OPTIONS_RESOLUTION_OTHER :drugo STR_GAME_OPTIONS_RESOLUTION_ITEM :{NUM}x{NUM} STR_GAME_OPTIONS_VIDEO_ACCELERATION :{BLACK}Hardversko ubrzanje -STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP :{BLACK}Označavanje ove opcije čini da OpenTTD pokuša da koristi hardversko ubrzanje. Promena ovog podešavanja će imati efekta tek nakon ponvnog pokretanja igre +STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP :{BLACK}Označi ovde da OpenTTD pokuša da koristi hardversko ubrzanje. Promena ovog podešavanja će imati efekta tek nakon ponvnog pokretanja igre STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Podešavanje će imati efekta tek nakon ponovnog pokretanja igre STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync -STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Štikliranjem se uključuje v-sync. Promena ovog podešavanja će biti vidljiva tek nakon ponovnog pokretanja igre. Radi jedino sa uključenim hardverskim ubrzanjem. +STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Označi ovde da uključiš v-sync. Promena ovog podešavanja će biti vidljiva tek nakon ponovnog pokretanja igre. Radi jedino sa uključenim hardverskim ubrzanjem. +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Trenutni pokretač: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Veličina interfejsa -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Izaberite većinu elementa koja će se koristiti +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Veličina interfejsa +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Povuci klizač da podesiš veličinu interfejsa. Držanjem Ctrl podešavanje se vrši kontinualno +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Automatski detektuj veličinu +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Označi ovde za automatsko prepoznavanje veličine interfejsa -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(automatska detekcija) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normalna veličina -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Uvećavajte veličinu dva puta -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Uvećavajte veličinu četiri puta +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Povećanje okvira +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Označi ovde da veličina okvira povećava sa veličinom prozora -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Veličina fonta -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Izaberi veličinu fonta za interfejs - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(automatska detekcija) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Uobičajen -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dvostruka veličina -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Četvorostruka veličina +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafike STR_GAME_OPTIONS_REFRESH_RATE :{BLACK}Frekvencija osvežavanja ekrana -STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP :{BLACK}Odaberite frekvenciju osvežavanja ekrana +STR_GAME_OPTIONS_REFRESH_RATE_TOOLTIP :{BLACK}Odaberi frekvenciju osvežavanja ekrana STR_GAME_OPTIONS_REFRESH_RATE_ITEM :{NUM}Hz STR_GAME_OPTIONS_REFRESH_RATE_WARNING :{WHITE}Frekvencije osvežavanja veće od 60Hz mogu uticati na performanse. STR_GAME_OPTIONS_BASE_GRF :{BLACK}Osnovni skup grafika -STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Odaberite željeni skup osnovnih grafika +STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Odaberi željeni skup osnovnih grafika STR_GAME_OPTIONS_BASE_GRF_STATUS :{RED}{NUM} datotek{P a e a} nedostaj{P e u e}/neispravn{P a o o} STR_GAME_OPTIONS_BASE_GRF_DESCRIPTION_TOOLTIP :{BLACK}Dodatni podaci o osnovnom skupu grafika STR_GAME_OPTIONS_BASE_SFX :{BLACK}Osnovni skup zvukova -STR_GAME_OPTIONS_BASE_SFX_TOOLTIP :{BLACK}Odaberite željeni skup osnovnih zvukova +STR_GAME_OPTIONS_BASE_SFX_TOOLTIP :{BLACK}Odaberi željeni skup osnovnih zvukova STR_GAME_OPTIONS_BASE_SFX_DESCRIPTION_TOOLTIP :{BLACK}Dodatni podaci o osnovnom skupu zvukova STR_GAME_OPTIONS_BASE_MUSIC :{BLACK}Osnovni skup muzike -STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP :{BLACK}Odaberite željeni skup osnovne muzike +STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP :{BLACK}Odaberi željeni skup osnovne muzike STR_GAME_OPTIONS_BASE_MUSIC_STATUS :{RED}{NUM} oštećen{P a e ih} datotek{P a e a} STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP :{BLACK}Dodatni podaci o osnovnom skupu muzike @@ -1263,31 +1243,29 @@ STR_ERROR_FULLSCREEN_FAILED :{WHITE}Neuspeš # Custom currency window -STR_CURRENCY_WINDOW :{WHITE}Sopstvena moneta +STR_CURRENCY_WINDOW :{WHITE}Sopstvena valuta STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Devizni kurs: {ORANGE}{CURRENCY_LONG} = £ {COMMA} -STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Smanjite vrednost vaše monete u odnosu na jednu funtu (£) -STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Povećajte vrednost vaše monete u odnosu na jednu funtu (£) -STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP :{BLACK}Postavite vrednost vaše monete u odnosu na jednu funtu (£) +STR_CURRENCY_DECREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Smanji vrednost svoje valute u odnosu na jednu funtu (£) +STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}Povećaj vrednost svoje valute u odnosu na jednu funtu (£) +STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP :{BLACK}Postavi vrednost svoje valute u odnosu na jednu funtu (£) STR_CURRENCY_SEPARATOR :{LTBLUE}Razdelnik: {ORANGE}{STRING} -STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP :{BLACK}Postavite razdelnik za vašu monetu +STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP :{BLACK}Postavi razdelnik za svoju valutu STR_CURRENCY_PREFIX :{LTBLUE}Prefiks: {ORANGE}{STRING} -STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP :{BLACK}Postavite prefiks za vašu monetu +STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP :{BLACK}Postavi prefiks za svoju valutu STR_CURRENCY_SUFFIX :{LTBLUE}Sufiks: {ORANGE}{STRING} -STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP :{BLACK}Postavite sufiks za vašu monetu +STR_CURRENCY_SET_CUSTOM_CURRENCY_SUFFIX_TOOLTIP :{BLACK}Postavi sufiks za svoju valutu -STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Prelazak na Euro: {ORANGE}{NUM} -STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Prelazak na Euro: {ORANGE}nikada -STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Odredite godinu za prelazak na euro -STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Raniji prelazak na euro -STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Kasniji prelazak na euro +STR_CURRENCY_SWITCH_TO_EURO :{LTBLUE}Prelazak na Evro: {ORANGE}{NUM} +STR_CURRENCY_SWITCH_TO_EURO_NEVER :{LTBLUE}Prelazak na Evro: {ORANGE}nikada +STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Odredi godinu za prelazak na Evro +STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Raniji prelazak na Evro +STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Kasniji prelazak na Evro STR_CURRENCY_PREVIEW :{LTBLUE}Primer: {ORANGE}{CURRENCY_LONG} -STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 funti (£) u vašoj moneti -STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Promena parametara sopstvene monete - -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Najveći broj suparnika: {ORANGE}{COMMA} +STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 funti (£) u svojoj valuti +STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Promena parametara sopstvene valute STR_NONE :Nijedan STR_FUNDING_ONLY :Samo finansiranje @@ -1338,6 +1316,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Umereni klimatski pojas +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subpolarni klimatski pojas +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Suptropski klimatski pojas +STR_CLIMATE_TOYLAND_LANDSCAPE :Zemlja igračaka + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Ravničarski STR_TERRAIN_TYPE_FLAT :Brdski @@ -1348,15 +1332,16 @@ STR_TERRAIN_TYPE_CUSTOM :Posebna visina STR_TERRAIN_TYPE_CUSTOM_VALUE :Posebna visina ({NUM}) ###length 4 +STR_CITY_APPROVAL_LENIENT :Blag STR_CITY_APPROVAL_TOLERANT :Tolerantan STR_CITY_APPROVAL_HOSTILE :Neprijateljski -STR_CITY_APPROVAL_PERMISSIVE :Popustljiv +STR_CITY_APPROVAL_PERMISSIVE :Popustljivo (bez uticaja na aktivnosti preduzeća) STR_WARNING_NO_SUITABLE_AI :{WHITE}Nisu dostupne odgovarajuće VI...{}Možete preuzeti nekoliko VI preko sistema za preuzimanje dodataka # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Podešavanja -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtriraj po: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Pretraga: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Proširi sve STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Skupi sve STR_CONFIG_SETTING_RESET_ALL :{BLACK}Resetuj sve vrednosti @@ -1369,7 +1354,7 @@ STR_CONFIG_SETTING_TYPE_GAME_INGAME :Podešavanja ig STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Podešavanja preduzeća (čuvaju se prilikom snimanja; utiču samo na nove igre) STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Podešavanja preduzeća (čuvaju se prilikom snimanja; utiču samo tekuće preduzeće) STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_CAPTION :{WHITE}Oprez! -STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT :{WHITE}Ovo će resetovati sva podešavanja igre na početne vrednosti{}Da li ste sigurni da želite da nastavite? +STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT :{WHITE}Ovo će resetovati sva podešavanja igre na početne vrednosti{}Da li sigurno želiš da nastaviš? STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}Kategorija: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Vrsta: @@ -1382,11 +1367,11 @@ STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_NEW :Podešavanja sa STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT :{BLACK}Ograničava donju listu na određen tip podešavanja STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL :Tipovi svih podešavanja -STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT :Podešavanja klijenta (nisu uskladištena u sačuvanoj igri; utiču na sve partije) -STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :Podešavanja igre (biće uskladištena u sačuvanoj igri; ima efekta samo na nove partije) -STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Podešavanja igre (biće uskladištena u sačuvanoj igri; ima efekta samo na nove partije) -STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Kompanijska podešavanja (biće uskladištena u sačuvanoj igri; ima efekta samo na nove partije) -STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Podešavanja kompanije (uskladištena u sačuvanoj igri; utiču samo na trenutnu kompaniju) +STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT :Podešavanja klijenta (nisu uskladištena u sačuvanoj igri; utiču na sve igre) +STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :Podešavanja igre (biće uskladištena u sačuvanoj igri; ima efekta samo na nove igre) +STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Podešavanja igre (biće uskladištena u sačuvanoj igri; ima efekta samo na nove igre) +STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Podešavanja preduzeća (biće uskladištena u sačuvanoj igri; ima efekta samo na nove igre) +STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Podešavanja preduzeća (uskladištena u sačuvanoj igri; utiču samo na trenutno preduzeće) STR_CONFIG_SETTINGS_NONE :{WHITE}- Nema - ###length 3 @@ -1416,6 +1401,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Desno STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Najveći zajam na početku: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Najveći iznos koji preduzeće može da pozajmi (ne uzimajući u obzir inflaciju) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Kamatna stopa: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Kamatna stopa na zajam; ako je omogućena, kontroliše inflaciju @@ -1451,8 +1437,8 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Ako je uključe STR_CONFIG_SETTING_DISASTERS :Katastrofe: {STRING} STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Uključuje i isključuje katastrofe koje s vremena na vreme mogu blokirati ili uništiti vozila i infrastrukturu -STR_CONFIG_SETTING_CITY_APPROVAL :Stav gradskog odbora u pogledu restrukturiranja zone: {STRING} -STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Izbor koliko će buka i zagađenje koje proizvode kompanije uticati na njihov gradski rejting i dalje građevinske akcije u toj zoni +STR_CONFIG_SETTING_CITY_APPROVAL :Stav lokalnih vlasti: {STRING} +STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Odaberi koliko će buka i zagađenje koje proizvode preduzeća uticati na njihovu ocenu i dalje građevinske akcije u tom naselju STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :Ograničenje visine mape: {STRING} STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_HELPTEXT :Podešava maksimalnu visinu terena mape. Sa "(automatski)" će prikladna vrednost biti odabrana nakon generisanja terena @@ -1467,8 +1453,8 @@ STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Dozvoli iskopav STR_CONFIG_SETTING_CATCHMENT :Realističnije veličine prihvatnih površina: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Drugačije veličine podnožja za različite vrste stanica i aerodroma -STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Kompanijeske stanice mogu da usluže industriej sa povezanim neutralnim stanicama: {STRING} -STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Kada je uključeno, industrije sa povezanim stanicama (kao što su naftne platforme) mogu biti uslužene od strane kompanijskih stanica koje su izgrađene u blizini. Kada je isključeno, ove industrije mogu biti uslužene samo od strane njihovih stanica. Nijedna kompanija u blizini neće moći da usluži industriju, niti će povezane stanice služiti bilo čemu osim inudtriji. +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Stanice preduzeća mogu da usluže fabrike sa povezanim neutralnim stanicama: {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Kada je uključeno, fabrike sa povezanim stanicama (kao što su naftne platforme) mogu biti uslužene od strane stanica preduzeća koje su izgrađene u blizini. Kada je isključeno, ove fabrike mogu biti uslužene samo od strane njihovih stanica. Nijedno preduzeće u blizini neće moći da usluži fabriku, niti će povezane stanice služiti bilo čemu osim fabrici. STR_CONFIG_SETTING_EXTRADYNAMITE :Dozvoljeno uklanjanje više gradskih kolovoza, mostova i tunela: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Olakšava uklanjanje infrastrukture i zgrada u gradskom vlasništvu @@ -1497,7 +1483,7 @@ STR_CONFIG_SETTING_FORBID_90_DEG :Zabranjeno okre STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Okretanje za 90 stepeni se dešava kada se uspravna pruga nalazi odmah posle vodoravne pruge na susednoj pločici i time čini da voz skreće pod 90 stepeni kad prelazi sa pločice na pločicu, umesto uobičajenih 45 stepeni kod drugih kombinacija pruge. Ovo takođe važi i za radijus zaokreta brodova STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Dozvoljeno sjedinjavanje udaljenih stanica: {STRING} -STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Dozvoljava dodavanje delova stanici bez da oni dodiruju postojeće delove stanice. Zahteva Ctrl+Klik kod postavljanja novih delova +STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Dozvoljava dodavanje delova stanici bez da oni dodiruju postojeće delove stanice. Zahteva Ctrl+klik kod postavljanja novih delova STR_CONFIG_SETTING_INFLATION :Inflacija: {STRING} STR_CONFIG_SETTING_INFLATION_HELPTEXT :Omogućuje inflaciju tako da troškovi rastu malo brže od isplata @@ -1511,18 +1497,18 @@ STR_CONFIG_SETTING_MAX_BRIDGE_HEIGHT_HELPTEXT :Maksimalna visi STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH :Najveća dužina tunela: {STRING} STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT :Maksimalna dužina za iskopavanje tunela -STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD :Metod izgradnje finansiranih primarnih industrija: {STRING} -STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :Način izgradnje primarnih industrija. 'nikakav' znači da finansiranje nije moguće, 'istraživački' znači da jeste moguće ali se izgradnja odvija na slučajnom mestu na karti i može da ne uspe, 'uobičajen' znači da preduzeća mogu da postave primarnu industriju na bilo koju poziciju na karti +STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD :Metod izgradnje finansiranih primarnih fabrika: {STRING} +STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :Način izgradnje primarnih fabrika. 'Nikakav' znači da finansiranje nije moguće, 'istraživački' znači da jeste moguće ali se izgradnja odvija na slučajnom mestu na karti i može da ne uspe, 'uobičajen' znači da preduzeća mogu da postave primarnu fabriku na bilo koju poziciju na karti ###length 3 STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NONE :nikakav STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NORMAL :uobičajen STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_PROSPECTING :istraživački -STR_CONFIG_SETTING_INDUSTRY_PLATFORM :Ravna površina oko industrija: {STRING} -STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :Količina ravne površine u okružini jedne industrije. Ovo osigurava da će u okolini industrije biti dovoljno slobodnog mesta za konstrukciju pruga, i tako dalje. +STR_CONFIG_SETTING_INDUSTRY_PLATFORM :Ravno područje oko fabrika: {STRING} +STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :Količina ravnog područja u okolini jedne fabrike. Ovo osigurava da će u okolini fabrike biti dovoljno slobodnog mesta za konstrukciju pruga, i tako dalje. -STR_CONFIG_SETTING_MULTIPINDTOWN :Dozvoljeno više industrija iste vrste na teritoriji jednog naselja: {STRING} -STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :Naselje uobičajeno ne dozvoljava više industrija iste vrste. Sa ovim podešavanjem će biti dozvoljeno više industrija iste vrste na teritoriji jednog naselja +STR_CONFIG_SETTING_MULTIPINDTOWN :Dozvoljeno više fabrika iste vrste na teritoriji jednog naselja: {STRING} +STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :Naselje uobičajeno ne dozvoljava više fabrika iste vrste. Sa ovim podešavanjem će biti dozvoljeno više fabrika iste vrste na teritoriji jednog naselja STR_CONFIG_SETTING_SIGNALSIDE :Prikaži signale: {STRING} STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :Odaberi na kojoj strani koloseka se postavlja signalizacija @@ -1556,7 +1542,7 @@ STR_CONFIG_SETTING_BRIBE :Dozvoljeno podm STR_CONFIG_SETTING_BRIBE_HELPTEXT :Dozvoljava preduzećima da pokušaju da podmite lokalne vlasti. Ako inspektor primeti podmićivanje, preduzeće neće moći da deluje u naselju sledećih šest meseci STR_CONFIG_SETTING_ALLOW_EXCLUSIVE :Dozvoljena kupovina ekskluzivnih prava prevoza: {STRING} -STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Ako preduzeće kupi ekskluzivna prava prevoza u naselju, protivničke stanice neće primati nikakav tovar ni putnike cele godine +STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Ako preduzeće kupi ekskluzivna prava prevoza u naselju, protivničke stanice neće primati nikakav teret ni putnike cele godine STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS :Dozvoljeno finansiranje zgrada: {STRING} STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT :Dozvoljava preduzećima da naselju daju novac za gradnju novih kuća @@ -1567,7 +1553,7 @@ STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT :Dozvoljava pred STR_CONFIG_SETTING_ALLOW_GIVE_MONEY :Dozvoljeno slanje novca drugim preduzećima: {STRING} STR_CONFIG_SETTING_ALLOW_GIVE_MONEY_HELPTEXT :Dozvoljava prenos novca između preduzeća u modu za više igrača -STR_CONFIG_SETTING_FREIGHT_TRAINS :Množilac težine tovara za simulaciju opterećenja vozova: {STRING} +STR_CONFIG_SETTING_FREIGHT_TRAINS :Množilac težine tereta za simulaciju opterećenja vozova: {STRING} STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :Podesi uticaj nošenje tereta u vozovima. Veća vrednost čini nošenje tereta zahtevniji za vozove, posebno na brdima STR_CONFIG_SETTING_PLANE_SPEED :Faktor brzine aviona: {STRING} @@ -1590,8 +1576,8 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Promena STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Održavanje infrastrukture: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Ako je omogućeno, infrastruktura će imati troškove održavanja. Trošak raste brže sa porastom veličine putne mreže i time više pogađa veća preduzeća od manjih -STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Početna boja kompanije: {STRING} -STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Izaberi početnu boju za kompaniju +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Početna boja preduzeća: {STRING} +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Izaberi početnu boju za preduzeće STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Nezastarevanje aerodroma: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Omogućavanje ovog podešavanja čini svaki tip aerodroma zauvek pristupan nakon njegovog uvođenja @@ -1628,8 +1614,8 @@ STR_CONFIG_SETTING_ERRMSG_DURATION :Trajanje poruke STR_CONFIG_SETTING_ERRMSG_DURATION_HELPTEXT :Trajanje prikazivanja poruka o greškama u crvenom prozoru. Neke (kritične) poruke o greškama se ne zatvaraju automatski posle ovog vremena nego moraju da se zatvore ručno STR_CONFIG_SETTING_ERRMSG_DURATION_VALUE :{COMMA} sekund{P a e i} -STR_CONFIG_SETTING_HOVER_DELAY :Prikaži poruke u balončićima: {STRING} -STR_CONFIG_SETTING_HOVER_DELAY_HELPTEXT :Odgoda pre prikaza objašnjenja alata kada se miš postavi iznad nekog elementa interfejsa. Alternativno, objašnjenja alata se mogu vezati uz desnu dugmetom na mišu kada je ova vrednost postavljena na 0. +STR_CONFIG_SETTING_HOVER_DELAY :Prikaži poruke u ispod strelice miša: {STRING} +STR_CONFIG_SETTING_HOVER_DELAY_HELPTEXT :Kašnjenje pre prikaza objašnjenja alata kada se miš postavi iznad nekog elementa interfejsa. Alternativno, objašnjenja alata se mogu vezati uz desnu dugmetom na mišu kada je ova vrednost postavljena na 0. STR_CONFIG_SETTING_HOVER_DELAY_VALUE :Lebdi na {COMMA} milisekund{P 0 u i i} ###setting-zero-is-special STR_CONFIG_SETTING_HOVER_DELAY_DISABLED :Desni klik @@ -1642,6 +1628,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Širina linije STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Prikaži naziv NewGRF-a u prozoru vozila: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Ispiši naziv NewGRF-a iz kojeg je odabrano vozilo došlo u prozoru za kupovinu vozila +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Prikaži spisak tereta koje vozila mogu prevoziti u spisku {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Ako je omogućeno, prenosivi teret vozila će se pojaviti iznad njega u listama vozila STR_CONFIG_SETTING_LANDSCAPE :Reljef:{STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Tereni definišu osnovne scenarije za igru sa različitim teretima i zahtevima za rast gradova. NewGRF-ovi i skripte igre omogućavaju detaljnije kontrole i postavke. @@ -1655,25 +1643,25 @@ STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis STR_CONFIG_SETTING_TERRAIN_TYPE :Vrsta terena: {STRING} STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(Samo TerraGenesis) Brdovitost terena -STR_CONFIG_SETTING_INDUSTRY_DENSITY :Gustoća industrije: {STRING} -STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Odaberite koliko industrije treba da se generiše i koji nivo treba da se održava tokom igre +STR_CONFIG_SETTING_INDUSTRY_DENSITY :Gustina fabrika: {STRING} +STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Odaberi koliko fabrika treba da se generiše i koji će se nivo održati tokom igre STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Najveće rastojanje od ivice za Rafinerije Nafte: {STRING} STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Rafinerije nafte se grade samo u blizini ivice karte, to jest uz obalu za otočne karte STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Nivo snežnog pokrivača: {STRING} -STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Određuje na kojoj visini počinje sneg u subarktičkoj klimi. Sneg takođe utiče na stvaranje industrija i uslove rasta gradova. Može se promeniti samo kroz Editor scenarija ili se drugačije izračunava kroz "pokrivenost snega" +STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Određuje na kojoj visini počinje sneg u subarktičkoj klimi. Sneg takođe utiče na stvaranje fabrika i uslove rasta naselja. Može se promeniti samo kroz Uređivač scenarija ili se drugačije izračunava kroz "pokrivenost snega" STR_CONFIG_SETTING_SNOW_COVERAGE :Pokrivenost snegom: {STRING} -STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :Kontroliše približnu veličinu snega u subarktičkoj klimi. Sneg takođe utiče na generisanje industrija i na uslove za rast gradova. Podešavanje se koristi samo kod generisanja mape. Zemlja odmah iznad nivoa mora je uvek bez snega +STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT :Kontroliše približnu veličinu snega u subarktičkoj klimi. Sneg takođe utiče na generisanje fabrika i na uslove za rast naselja. Podešavanje se koristi samo kod generisanja mape. Zemlja odmah iznad nivoa mora je uvek bez snega STR_CONFIG_SETTING_SNOW_COVERAGE_VALUE :{NUM}% STR_CONFIG_SETTING_DESERT_COVERAGE :Pokrivenost pustinjom: {STRING} -STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT :Kontroliše približnu veličinu pustinje u tropskoj klimi. Pustinja takođe utiče na generisanje industrija. Podešavanje se koristi samo kod generisanja mape +STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT :Kontroliše približnu veličinu pustinje u tropskoj klimi. Pustinja takođe utiče na genersianje fabrika. Podešavanje se koristi samo kod generisanja mape STR_CONFIG_SETTING_DESERT_COVERAGE_VALUE :{NUM}% STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Vrste terena (samo za TerraGenesis) : {STRING} -STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT :(Samo TerraGenesis) Odaberite učestalost brda: Blaži tereni imaju rjeđa, ali šira brda. Teži tereni imaju mnogo brda koja bi mogla da izgledaju kao da se ponavljaju +STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT :(Samo TerraGenesis) Odaberi učestalost brda: blaži tereni imaju ređa, ali šira brda, dok grublji tereni imaju mnogo brda koja bi mogla da izgledaju kao da se ponavljaju ###length 4 STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :Ravnomerna STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_SMOOTH :Malo valovita @@ -1681,20 +1669,24 @@ STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_ROUGH :Valovita STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :Vrlo valovita STR_CONFIG_SETTING_VARIETY :Raznolikost distribucije: {STRING} -STR_CONFIG_SETTING_VARIETY_HELPTEXT :(Samo TerraGenesis) Odredite da li će karta sadržavati i planinska i ravna područja. Kako ovo čini kartu još ravnijom, ostale bi postavke trebale biti postavljene na planinske. +STR_CONFIG_SETTING_VARIETY_HELPTEXT :(Samo TerraGenesis) Odredi da li će karta sadržavati i planinska i ravna područja. Pošto ovo čini kartu još ravnijom, ostali parametri bi trebali biti postavljeni na planinske. STR_CONFIG_SETTING_RIVER_AMOUNT :Količina reka: {STRING} -STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT :Izaberite količinu generiranih reka +STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT :Izaberi količinu generisanih reka STR_CONFIG_SETTING_TREE_PLACER :Posađivanje drveća: {STRING} -STR_CONFIG_SETTING_TREE_PLACER_HELPTEXT :Odaberite distribuciju drveća ma karti: 'Originalno' sadi drveće ravnomerno, 'Poboljšano2 sadi drveće u grupama +STR_CONFIG_SETTING_TREE_PLACER_HELPTEXT :Odaberi distribuciju drveća ma karti: 'Originalno' sadi drveće ravnomerno, 'Poboljšano' sadi drveće u grupama ###length 3 STR_CONFIG_SETTING_TREE_PLACER_NONE :Nikakav STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :Originalni STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Unapređen STR_CONFIG_SETTING_ROAD_SIDE :Drumskih vozila: {STRING} -STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Odaberite stranu saobraćaja +STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Odaberi stranu saobraćaja + +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Levom stranom +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Desnom stranom STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Orijentacija elevacione karte: {STRING} ###length 2 @@ -1707,7 +1699,7 @@ STR_CONFIG_SETTING_EDGES_NOT_EMPTY :{WHITE}Jedan il STR_CONFIG_SETTING_EDGES_NOT_WATER :{WHITE}Jedan ili više sektora na jednoj od ivica nije voda STR_CONFIG_SETTING_STATION_SPREAD :Maksimalna rasprostranjenost stanice: {STRING} -STR_CONFIG_SETTING_STATION_SPREAD_HELPTEXT :Maksimalna površina na kojoj mogu biti delovi jedne stanice. Imajte na umur da će visoke vrednosti usporiti igru +STR_CONFIG_SETTING_STATION_SPREAD_HELPTEXT :Maksimalna površina na kojoj mogu biti delovi jedne stanice. Treba imati na umu da će visoke vrednosti usporiti igru STR_CONFIG_SETTING_SERVICEATHELIPAD :Automatsko servisiranje helikoptera na heliodromima: {STRING} STR_CONFIG_SETTING_SERVICEATHELIPAD_HELPTEXT :Servisiraj helikoptere posle svakog sletanja, čak i kada nema depoa na aerodromu @@ -1722,15 +1714,21 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Zelena STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Tamno zelena STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Ljubičasta +STR_CONFIG_SETTING_LINKGRAPH_COLOURS :Boje za prikaz toka tereta: {STRING} +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_HELPTEXT :Postavi šemu boja koja se koristi za prikaz toka tereta. ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :Zelena i crvena (original) +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Zelena i plava +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Sivo i crveno +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :Nijanse sive STR_CONFIG_SETTING_SCROLLMODE :Ponašanje listanja pogleda: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Ponašanje prilikom skrolovanje mape ###length 4 -STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Pomerite pogled sa desnim tasterom miša, položaj miša zaključan -STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Pomerite mapu sa desnim tasterom miša, zaključajte položaj miša -STR_CONFIG_SETTING_SCROLLMODE_RMB :Pomerite mapu pomoću desne tipke miša -STR_CONFIG_SETTING_SCROLLMODE_LMB :Pomerite mapu pomoću levog miša +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Pomeranje pogleda desnim tasterom miša, položaj miša zaključan +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Pomeranje mape desnim tasterom miša, položaj miša zaključan +STR_CONFIG_SETTING_SCROLLMODE_RMB :Pomeranje mape pomoću desnog tastera miša +STR_CONFIG_SETTING_SCROLLMODE_LMB :Pomeranje mape pomoću levog tastera miša STR_CONFIG_SETTING_SMOOTH_SCROLLING :Ravnomeran prelaz prozora: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Odredi kako se glavni prikaz pomiče na određeno mesto kada se klikne na malu kartu ili kada se daje naredba za pomicanje na određeni objekat na karti. Ako je omogućeno, prikaz se pomiče glatko, ako je onemogućeno, prikaz izravno skače na ciljano mesto @@ -1759,7 +1757,7 @@ STR_CONFIG_SETTING_SCROLLWHEEL_SCROLL :Pomeranje teren STR_CONFIG_SETTING_SCROLLWHEEL_OFF :Nikakva STR_CONFIG_SETTING_OSK_ACTIVATION :Tastatura na ekranu: {STRING} -STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT :Odaberite način upotrebe tastature na ekranu za unos teksta u polja korištenjem samo pokazivača. Ovo je namenjeno malim uređajima bez fizičke tastature +STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT :Odaberi način upotrebe tastature na ekranu za unos teksta u polja korištenjem samo pokazivača. Ovo je namenjeno malim uređajima bez fizičke tastature ###length 4 STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :Onemogućeno STR_CONFIG_SETTING_OSK_ACTIVATION_DOUBLE_CLICK :Dupli klik @@ -1774,27 +1772,27 @@ STR_CONFIG_SETTING_USE_RELAY_SERVICE_ASK :Pitaj STR_CONFIG_SETTING_USE_RELAY_SERVICE_ALLOW :Dozvoli STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU :Oponašanje desnog klika: {STRING} -STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT :Odaberite metodu imitiranja klika na desnu dirku miša +STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT :Odaberi metodu imitiranja klika na desni taster miša ###length 3 -STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Klik -STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+Klik +STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+klik +STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_CONTROL :Ctrl+klik STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_OFF :Nikakvo STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE :Zatvori prozor pomoću desnog klika: {STRING} STR_CONFIG_SETTING_RIGHT_MOUSE_WND_CLOSE_HELPTEXT :Zatvara prozor tako što klikne desnim klikom unutar nje. Onemogućava dodir sa desnim tasterom miša! STR_CONFIG_SETTING_AUTOSAVE :Autočuvanje: {STRING} -STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Izbor vremenskog intervala između dve automatski sačuvane pozicije +STR_CONFIG_SETTING_AUTOSAVE_HELPTEXT :Odabir vremenskog intervala između dve automatski sačuvane igre -STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :Koristiti {STRING} oblik datuma u nazivima sačuvanih partija -STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT :Format datuma u imenima fajlova sačuvanih partija +STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES :Koristiti {STRING} oblik datuma u nazivima sačuvanih igara +STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_HELPTEXT :Format datuma u imenima fajlova sačuvanih igara ###length 3 STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_LONG :dugačak (31st Dec 2008) STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_SHORT :kratak (31-12-2008) STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_ISO :ISO (2008-12-31) -STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME :Pauzirati odmah po pokretanju nove partije : {STRING} -STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Kada je omogućeno, igra će se automatski pauzirati kada počinjete novu partiju, omogućavajući bolje proučavanje karte +STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME :Pauzirati odmah po pokretanju nove igre: {STRING} +STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Kada je omogućeno, igra će se automatski pauzirati kada počinjete novu igru, omogućavajući bolje proučavanje karte STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL :Tokom pauze dozvoljene su: {STRING} STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_HELPTEXT :Odabir akcija koje mogu biti vršene za vreme pauze @@ -1808,7 +1806,7 @@ STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS :Koristiti napre STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :Omogući upotrebu naprednih lista vozila za grupisanje vozila STR_CONFIG_SETTING_LOADING_INDICATORS :Koristiti pokazatelj utovarivanja: {STRING} -STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :Izbor da li će biti prikazani indikatori utovara i istovara iznad vozila +STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :Odaberi da li će se prikazati indikatori utovara i istovara iznad vozila STR_CONFIG_SETTING_TIMETABLE_IN_TICKS :Prikazati red vožnje u diskretnim otkucajima: {STRING} STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT :Prikaži vreme putovanja u redu vožnje u diskretnim otkucajima umesto u danima @@ -1816,11 +1814,11 @@ STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT :Prikaži vreme STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :Prikazivanje polaska i dolaska u rasporedima: {STRING} STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Prikazivanje očekivanog vremena dolaska i odlaska u rasporedima -STR_CONFIG_SETTING_QUICKGOTO :Zadržati aktivno 'Idi do' dugme: {STRING} -STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT :Pred-odaberi kursor naredbe "otiđi na" kod otvaranja prozora s naredbama +STR_CONFIG_SETTING_QUICKGOTO :Brzo kreiranje naredbi vozila: {STRING} +STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT :Označi kursor naredbe "idi do" kod otvaranja prozora sa naredbama -STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE :Podešena vrsta pruge (posle učitavanja/nove partije): {STRING} -STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :Vrsta željeznice koja će biti odabrana prilikom pokretanja ili učitavanja igre. "Prva dostupna" odabire najstariju vrstu, "zadnja dostupna" odabire najnoviju vrstu, "najčešće korištena" odabire vrstu koja je trenutno najviše u upotrebi +STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE :Podrazumevana vrsta pruge (posle učitavanja/nove igre): {STRING} +STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :Vrsta železnice koja će biti odabrana prilikom pokretanja ili učitavanja igre. "Prva dostupna" odabira najstariju vrstu, "poslednja dostupna" odabire najnoviju vrstu, "najčešće korišćena" odabira vrstu koja je trenutno najviše u upotrebi ###length 3 STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST :Prva dostupna STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_LAST :Zadnja dostupna @@ -1848,7 +1846,7 @@ STR_CONFIG_SETTING_SOUND_NEWS :Novinski naslov STR_CONFIG_SETTING_SOUND_NEWS_HELPTEXT :Reprodukuj zvučne efekte prilikom prikazivanja novinskih naslova STR_CONFIG_SETTING_SOUND_NEW_YEAR :Kraj godine: {STRING} -STR_CONFIG_SETTING_SOUND_NEW_YEAR_HELPTEXT :Reprodukuj zvučne efekte prilikom ispisa rezultata poslovanja kompanije na kraju svake godine +STR_CONFIG_SETTING_SOUND_NEW_YEAR_HELPTEXT :Reprodukuj zvučne efekte prilikom ispisa rezultata poslovanja preduzeća na kraju svake godine STR_CONFIG_SETTING_SOUND_CONFIRM :Izgradnja: {STRING} STR_CONFIG_SETTING_SOUND_CONFIRM_HELPTEXT :Reprodukuj zvučne efekte pri uspešnoj izgradnji i sličnim akcijama @@ -1862,8 +1860,8 @@ STR_CONFIG_SETTING_SOUND_DISASTER_HELPTEXT :Reprodukuj zvu STR_CONFIG_SETTING_SOUND_VEHICLE :Vozila: {STRING} STR_CONFIG_SETTING_SOUND_VEHICLE_HELPTEXT :Reprodukuj zvučne efekte vozila -STR_CONFIG_SETTING_SOUND_AMBIENT :Okruženje: {STRING} -STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT :Reprodukuj ambijentalne zvučne efekte za teren, industrije i gradove +STR_CONFIG_SETTING_SOUND_AMBIENT :Ambijent: {STRING} +STR_CONFIG_SETTING_SOUND_AMBIENT_HELPTEXT :Reprodukuj ambijentalne zvučne efekte za teren, fabrike i naselja STR_CONFIG_SETTING_MAX_TRAINS :Najviše vozova po preduzeću: {STRING} STR_CONFIG_SETTING_MAX_TRAINS_HELPTEXT :Najveći broj vozova koje preduzeće može da ima @@ -1871,8 +1869,8 @@ STR_CONFIG_SETTING_MAX_TRAINS_HELPTEXT :Najveći broj v STR_CONFIG_SETTING_MAX_ROAD_VEHICLES :Najviše drumskih vozila po preduzeću: {STRING} STR_CONFIG_SETTING_MAX_ROAD_VEHICLES_HELPTEXT :Najveći broj drumskih vozila koje preduzeće može da ima -STR_CONFIG_SETTING_MAX_AIRCRAFT :Najviše letilica po preduzeću: {STRING} -STR_CONFIG_SETTING_MAX_AIRCRAFT_HELPTEXT :Najveći broj letilica koje preduzeće može da ima +STR_CONFIG_SETTING_MAX_AIRCRAFT :Najviše letelica po preduzeću: {STRING} +STR_CONFIG_SETTING_MAX_AIRCRAFT_HELPTEXT :Najveći broj letelica koje preduzeće može da ima STR_CONFIG_SETTING_MAX_SHIPS :Najviše brodova po preduzeću: {STRING} STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :Najveći broj brodova koje preduzeće može da ima @@ -1884,20 +1882,20 @@ STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Računar ne mo STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Omogućavanje ovog podešavanja znači da računar ne može da stvara drumska vozila STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Računar ne može da koristi vazdušni prevoz: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Omogućavanje ovog podešavanja znači da računar ne može da stvara letilice +STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Omogućavanje ovog podešavanja znači da računar ne može da stvara letelice STR_CONFIG_SETTING_AI_BUILDS_SHIPS :Računar ne može da koristi vodni prevoz: {STRING} STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :Omogućavanje ovog podešavanja znači da računar ne može da stvara brodove STR_CONFIG_SETTING_AI_PROFILE :Podrazumevani profil podešavanja: {STRING} -STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Odaberi koji profil podešavanja se koristi za proizvoljne VI ili za početne vrednosti kada se dodaje nova AI ili skript +STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Odaberi koji profil podešavanja se koristi za proizvoljne VI ili za početne vrednosti kada se dodaje nova VI ili skripta ###length 3 STR_CONFIG_SETTING_AI_PROFILE_EASY :Lak STR_CONFIG_SETTING_AI_PROFILE_MEDIUM :Srednji STR_CONFIG_SETTING_AI_PROFILE_HARD :Težak -STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Dozvoljena VI u mrežnoj partiji: {STRING} -STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Dozvoljava računarskoj VI da učestvuje u mrežnoj partiji +STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Dozvoljena VI u mrežnoj igri: {STRING} +STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Dozvoljava računarskoj VI da učestvuje u mrežnoj igri STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :Suspendovanje #opkodova pre skripti: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Najveći broj koraka računanja koje skript može da izvede u jednom krugu @@ -1909,13 +1907,13 @@ STR_CONFIG_SETTING_SERVINT_ISPERCENT :Intervali servi STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Da li se intervali servisiranja vozila okidaju vremenom proteklim od prošlog servisiranja ili padom pouzdanosti za određeni procenat u odnosu na najveću pouzdanost STR_CONFIG_SETTING_SERVINT_TRAINS :Podrazumevani servisni interval za vozove: {STRING} -STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :Podrazumevani servisni interval za nove vozove, ako nema zadanog servisnog intervala za vozilo +STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :Podrazumevani servisni interval za nove vozove, ukoliko nema zadatog servisnog intervala za vozilo STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES :Podrazumevani servisni interval za drumska vozila: {STRING} -STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES_HELPTEXT :Postavite podrazumevani servisni interval za drumska vozila, ako nema zadanog servisnog intervala za vozilo -STR_CONFIG_SETTING_SERVINT_AIRCRAFT :Podrazumevani servisni interval za letilice: {STRING} -STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT :Postavite podrazumevani servisni interval za avione, ako nema zadanog servisnog intervala za vozilo +STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES_HELPTEXT :Postavi podrazumevani servisni interval za nova drumska vozila, ukoliko nema zadatog servisnog intervala za vozilo +STR_CONFIG_SETTING_SERVINT_AIRCRAFT :Podrazumevani servisni interval za letelice: {STRING} +STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT :Postavi podrazumevani servisni interval za nove letelice, ukoliko nema zadatog servisnog intervala za vozilo STR_CONFIG_SETTING_SERVINT_SHIPS :Podrazumevani servisni interval za brodove: {STRING} -STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT :Postavite podrazumevani servisni interval za nove brodove, ako nema zadanog servisnog intervala za vozilo +STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT :Postavi podrazumevani servisni interval za nove brodove, ukoliko nema zadatog servisnog intervala za vozilo STR_CONFIG_SETTING_SERVINT_VALUE :{COMMA} dan{P 0 "" a a}/% ###setting-zero-is-special STR_CONFIG_SETTING_SERVINT_DISABLED :Onemogućeno @@ -1938,9 +1936,11 @@ STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER_HELPTEXT :Prikazuje novin STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS :Udesi/nepogode: {STRING} STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT :Prikazuje novinske naslove kada se dese nezgode ili katastrofe +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER :Sudari konkurentskih vozila: {STRING} +STR_CONFIG_SETTING_NEWS_ACCIDENT_OTHER_HELPTEXT :Prikaži novinske naslove o sudarenim vozilima takmičarima STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION :Podaci o preduzeću: {STRING} -STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT :Prikazuje novinske naslove kada se otvori nova kompanija, ili kada postojeća rizikuje bankrot +STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT :Prikazuje novinske naslove kada se otvori novo preduzeće, ili kada postojeća rizikuje bankrot STR_CONFIG_SETTING_NEWS_INDUSTRY_OPEN :Otvaranje nove fabrike: {STRING} STR_CONFIG_SETTING_NEWS_INDUSTRY_OPEN_HELPTEXT :Prikazuje novinske naslove kada se otvori nova fabrika @@ -1948,17 +1948,17 @@ STR_CONFIG_SETTING_NEWS_INDUSTRY_OPEN_HELPTEXT :Prikazuje novin STR_CONFIG_SETTING_NEWS_INDUSTRY_CLOSE :Zatvaranje fabrike: {STRING} STR_CONFIG_SETTING_NEWS_INDUSTRY_CLOSE_HELPTEXT :Prikazuje novinske naslove o zatvaranju fabrika -STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES :Promene u ekonomiji: {STRING} -STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES_HELPTEXT :Prikazuje novinske naslove o globalnim ekonomskim promenama +STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES :Promene u privredi: {STRING} +STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES_HELPTEXT :Prikazuje novinske naslove o globalnim privrednim promenama -STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY :Promene u proizvodnji usluženih industrija: {STRING} -STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY_HELPTEXT :Prikazuje novinske naslove kada se promeni nivo proizvodnje u industriji koju naša kompanija pokriva +STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY :Promene u proizvodnji fabrika usluženih od strane preduzeća: {STRING} +STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY_HELPTEXT :Prikazuje novinske naslove kada se promeni nivo proizvodnje u fabrici koje naše preduzeće uslužuje -STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER :Promene u proizvodnji industrija usluženih konkurencijom: {STRING} -STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER_HELPTEXT :Prikazuje novinske naslove kada se promeni nivo proizvodnje u industriji koju konkurencija pokriva +STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER :Promene u proizvodnji fabrika usluženih od strane konkurencije: {STRING} +STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_OTHER_HELPTEXT :Prikazuje novinske naslove kada se promeni nivo proizvodnje u fabrici koju konkurencija uslužuje -STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED :Promene u proizvodnji ostalih industrija: {STRING} -STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED_HELPTEXT :Prikazuje novinske naslove kada se promeni nivo proizvodnje u industriji koju ne pokriva ni naša kompanija, ni konkurencija +STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED :Promene u proizvodnji ostalih fabrika: {STRING} +STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED_HELPTEXT :Prikazuje novinske naslove kada se promeni nivo proizvodnje u fabrici koju ne uslužuje ni naše preduzeće ni konkurencija STR_CONFIG_SETTING_NEWS_ADVICE :Savet / Izveštaji o vozilima preduzeća: {STRING} STR_CONFIG_SETTING_NEWS_ADVICE_HELPTEXT :Prikaži poruke o događajima na vozilima koji zahtevaju intervenciju @@ -1966,7 +1966,7 @@ STR_CONFIG_SETTING_NEWS_ADVICE_HELPTEXT :Prikaži poruke STR_CONFIG_SETTING_NEWS_NEW_VEHICLES :Nova vozila: {STRING} STR_CONFIG_SETTING_NEWS_NEW_VEHICLES_HELPTEXT :Prikazuje novinske naslove kada postane dostupan novi tip vozila -STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE :Promene u prihvatanju tovara: {STRING} +STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE :Promene u prihvatanju tereta: {STRING} STR_CONFIG_SETTING_NEWS_CHANGES_ACCEPTANCE_HELPTEXT :Prikaži poruke kada stanice promene tip prijema robe i putnika STR_CONFIG_SETTING_NEWS_SUBSIDIES :Subvencije: {STRING} @@ -1984,13 +1984,13 @@ STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Godina počev o STR_CONFIG_SETTING_STARTING_YEAR :Početna godina: {STRING} STR_CONFIG_SETTING_ENDING_YEAR :Završna godina za rezultate: {STRING} -STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Godina kada se igra završava za računanje rezultata. Na kraju ove godine, rezultat kompanije se snima i tabela sa rezultatima se prikazuje, ali igrači mogu da nastave igru nakon ovoga.{}Ako je ova godina pre godine početka, tabela sa rezultatima se nikada neće prikazati. +STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Godina kada se igra završava za računanje rezultata. Na kraju ove godine, rezultat preduzeća se snima i tabela sa rezultatima se prikazuje, ali igrači mogu da nastave igru nakon ovoga.{}Ako je ova godina pre godine početka, tabela sa rezultatima se nikada neće prikazati. STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} ###setting-zero-is-special STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Nikada -STR_CONFIG_SETTING_ECONOMY_TYPE :Tip ekonomije: {STRING} -STR_CONFIG_SETTING_ECONOMY_TYPE_HELPTEXT :Glatka ekonomija čini da su promene u proizvodnji češće i u manjim koracima. Zamrznuta ekonomija blokira promene u proizvodnji i zatvaranje fabrika. Ovo podešavanje može da ne utiče na igru ako tipove industrije određuje NewGRF. +STR_CONFIG_SETTING_ECONOMY_TYPE :Tip privrede: {STRING} +STR_CONFIG_SETTING_ECONOMY_TYPE_HELPTEXT :Glatka privreda čini da su promene u proizvodnji češće i u manjim koracima. Zamrznuta privreda blokira promene u proizvodnji i zatvaranje fabrika. Ovo podešavanje može da ne utiče na igru ako tipove fabrika određuje NewGRF. ###length 3 STR_CONFIG_SETTING_ECONOMY_TYPE_ORIGINAL :Originalna STR_CONFIG_SETTING_ECONOMY_TYPE_SMOOTH :Glatka @@ -1999,8 +1999,8 @@ STR_CONFIG_SETTING_ECONOMY_TYPE_FROZEN :Zamrznuta STR_CONFIG_SETTING_ALLOW_SHARES :Dozvoljena kupovina deonica drugih preduzeća: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Ako je omogućeno, dozvoljava kupovinu i prodaju deonica preduzeća. Deonice su dostupne tek kad preduzeće dostigne određenu starost -STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Najmanja starost kompanije za trgovinu akcijama: {STRING} -STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Podesi najmanju starost kompanije da bi drugi mogli da trguju akcijama sa njom. +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Najmanja starost preduzeća za trgovinu akcijama: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Podesi najmanju starost preduzeća da bi drugi mogli da trguju akcijama sa njom. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Procenat prihoda koji će biti predan srednjim dionicama prevoza u fider sustavima: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Procenat prihoda koji će biti predan srednjim dionicama prevoza u fider sustavima, dajući više kontrole nad prihodima @@ -2012,10 +2012,10 @@ STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE :Prilikom prevla STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :Odabir ponašanja postavljanja signala uz Ctrl+povlačenje signala. Ako je onemogućeno, signali se postavljaju ispred i iza tunela ili mostova kako bi se izbegli dugi delovi pruge bez signala. Ako je omogućeno, signali se postavljaju svakih n kvadrata, olakšavajući poravnavanje signala na paralelnim delovima pruge STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Automatsko postavljanje semafora do: {STRING} -STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Postavite godinu za početak korištenja električnih signala za pruge. Prije ove godine, koristiti će se neelektrični signali (imaju iste funkcije samo izgledaju drugačije) +STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Postavi godinu za početak upotrebe električnih signala za pruge. Pre ove godine, koristiće se neelektrični signali (koji imaju iste funkcije, ali izgledaju drugačije) -STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Ciklični izbor vrste signalizacije: {STRING} -STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Ciklični izbor vrste signalizacije kada Ctrl+klik na izgradnju signala sa alatom signala +STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Ciklični odabir vrste signalizacije: {STRING} +STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Ciklični odabir vrste signalizacije kada Ctrl+klik na izgradnju signala sa alatom signala ###length 2 STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :Samo putna STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :Sve vidljivo @@ -2041,9 +2041,9 @@ STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Naseljima je do STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Omogućava naseljima da grade prelaz pruge preko puta STR_CONFIG_SETTING_NOISE_LEVEL :Naseljima je dozvoljeno da kontrolišu nivo buke aerodroma: {STRING} -STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Ako je ovo podešavanje onemogućeno mogu postojati 2 aerodroma u svakom naselju. Ako je podešavanje omogućeno, broj aerodroma u gradu je ograničen dozvoljenim nivoom buke u gradu koji zavisi od populacije i od veličine i udaljenosti aerodroma +STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Ako je ovo podešavanje onemogućeno mogu postojati 2 aerodroma u svakom naselju. Ako je podešavanje omogućeno, broj aerodroma u naselju je ograničen dozvoljenim nivoom buke u naselju koji zavisi od populacije i od veličine i udaljenosti aerodroma -STR_CONFIG_SETTING_TOWN_FOUNDING :Osnivanje naselja u toku partije: {STRING} +STR_CONFIG_SETTING_TOWN_FOUNDING :Osnivanje naselja u toku igre: {STRING} STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Dozvoljava igračima osnivanje novih naselja u toku igre ###length 3 STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :zabranjeno @@ -2051,18 +2051,18 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :dozvoljeno STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :dozvoljeno, zaseban plan gradnje STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Proizvodnja tereta u naselju: {STRING} -STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Koliko tovara se proizvede od strane kuća u naseljima, u odnosu na ukupan broj stanovnika u naselju.{}Kvadratni rast: naselje dvostruke veličine stvara četvorostruko više putnika.{}Linearan rast: naselje dvostruke veličine stvara dvostruko više putnika. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Koliko tereta se proizvede od strane kuća u naseljima, u odnosu na ukupan broj stanovnika u naselju.{}Kvadratni rast: naselje dvostruke veličine stvara četvorostruko više putnika.{}Linearan rast: naselje dvostruke veličine stvara dvostruko više putnika. ###length 2 STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Kvadratni (originalan) STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Linearno -STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Rasejavanje drveća tokom partije: {STRING} -STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Kontrola nasumične pojave drveća u toku igre. Ovo može uticati na industrije koje zavise o rastu drveća, na primer pilana +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Rasejavanje drveća tokom igre: {STRING} +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Kontrola nasumične pojave drveća u toku igre. Ovo može uticati na fabrike koje zavise od rasta drveća, na primer pilana ###length 4 -STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_SPREAD :Raste bez širenja {RED}(kvari rad drvne industrije) +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_SPREAD :Raste bez širenja {RED}(negativno utiče na rad pilane) STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_RAINFOREST :Raste ali se širi samo u prašumama STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_ALL :Raste i širi se svuda -STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_GROWTH_NO_SPREAD :Bez rasta, bez širenja {RED}(kvari rad drvne industrije) +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_GROWTH_NO_SPREAD :Bez rasta, bez širenja {RED}(negativno utiče na rad pilane) STR_CONFIG_SETTING_TOOLBAR_POS :Lokacija glavne trake sa alatima: {STRING} STR_CONFIG_SETTING_TOOLBAR_POS_HELPTEXT :Horizontalna pozicija glavne trake s alatkama na vrhu ekrana @@ -2080,7 +2080,7 @@ STR_CONFIG_SETTING_SOFT_LIMIT_VALUE :{COMMA} STR_CONFIG_SETTING_SOFT_LIMIT_DISABLED :Isključeno STR_CONFIG_SETTING_ZOOM_MIN :Najbliži nivo: {STRING} -STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT :Najveći nivo zumiranja prema unutra u prikazima. Uzmite u obzir da uključivanje većih nivoa zumiranja prema unutra povećava i upotrebu memorije +STR_CONFIG_SETTING_ZOOM_MIN_HELPTEXT :Najveći nivo zumiranja prema unutra u prikazima. Treba imati u obzir da uključivanje većih nivoa zumiranja prema unutra povećava i upotrebu memorije STR_CONFIG_SETTING_ZOOM_MAX :Najudaljeniji nivo: {STRING} STR_CONFIG_SETTING_ZOOM_MAX_HELPTEXT :Najmanji nivo zumiranja prema van u prikazima. Veći nivo zumiranja prema van može uzrokovati usporavanje igre ###length 6 @@ -2112,11 +2112,11 @@ STR_CONFIG_SETTING_LARGER_TOWNS_HELPTEXT :Broj naselja ko STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 u {COMMA} ###setting-zero-is-special STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Nijedan -STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Inicijalni množilac razvoja gradova: {STRING} -STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Prosečna veličina naselja relativno u odnosu na gradove na početku partije +STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Inicijalni množilac rasta gradova: {STRING} +STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Prosečna veličina naselja relativno u odnosu na gradove na početku igre STR_CONFIG_SETTING_LINKGRAPH_INTERVAL :Ažuriraj grafikon distribucije svakih {STRING}{NBSP}dan{P 0:2 a a a} -STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Vreme između slijedećih preračuna grafikona. Svaki preračun izračunava planove za jednu komponentu grafikona. To znači da vrednost X za ovu postavku ne mora da znači i ažuriranje celog grafikona unutar X dana. Samo neke komponente će da budu ažurirane. Čim kraće vreme odredite, više će biti potrebno resursa CPUa za izračun. Čim duže vrijeme odredite, trebati će više vremena za pokretanje distribucije po novim putevima. +STR_CONFIG_SETTING_LINKGRAPH_INTERVAL_HELPTEXT :Vreme između sledećih preračuna grafikona. Svaki preračun izračunava planove za jednu komponentu grafikona. To znači da vrednost X za ovu postavku ne mora da znači i ažuriranje celog grafikona unutar X dana. Samo neke komponente će biti ažurirane. Što je vreme kraće, to će biti potrebno više procesorskih resursa za proračun. Što je vreme duže, više će vremena biti potrebno da se distribucija tereta započne na novim putanjama. STR_CONFIG_SETTING_LINKGRAPH_TIME :Uzmi {STRING}{NBSP}dan{P 0:2 a a a} za preračun grafikona STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Vreme potrebno za preračun komponente grafikona. Kada se preračun pokrene, stvara se sled koji može raditi broj dana koliko ovdje odredite. Čim kraće vreme odredite, postoji mogućnost da sled neće biti gotov kada bi trebao. Tada se igra usporava odnosno zaustavlja dok ne bude gotovo. Čim duže vreme odredite, potrebno je duže da se distribucija ažurira kada se izmene rute. @@ -2124,8 +2124,8 @@ STR_CONFIG_SETTING_DISTRIBUTION_PAX :Način distribu STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simetrično" znači da će se otprilike isti broj putnika slati od stanice A prema stanici B kao i od B prema A. "Asimetrično" znači da će se proizvoljan broj putnika slati u oba smera. "Ručno" znači da se distribucija putnika neće vršiti automatski. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Režim distribucije za poštu: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Simetrično" znači da će se otprilike ista količina pošte slati od stanice A prema stanici B kao i od B prema A. "Asimetrično" znači da će se proizvoljne količine pošte slati u oba smera. "Ručno" znači da se distribucija pošte neće vršiti automatski. -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Način distribucije za OKLOPLJENU klasu tereta: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :OKLOPLJENA klasa tereta sadrži dragocenosti u umjerenoj klimi, dijamante u subtropskoj klimi ili zlato u subarktičkoj klimi. NewGFR-ovi bi mogli ovo izmeniti. "Simetrično" znači da će se otprilike ista količina tereta slati od stanice A prema stanici B kao i od B prema A. "Asimetrično" znači da će se proizvoljne količine tereta slati u oba smera. "Ručno" znači da se distribucija tih tereta neće vršiti automatski. Preporučljivo je namestiti ovu postavku na "asimetrično" ili "ručno" kod subarktičke klime jer banke neće slati zlato natrag prema rudnicima zlata. Za umjerenu i subtropsku klimu možete namestiti i "simetrično" jer će banke slati neke dragocenosti natrag prema banci porekla. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Način distribucije za OKLOPNU klasu tereta: {STRING} +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :OKLOPNA klasa tereta sadrži dragocenosti u umerenoj klimi, dijamante u subtropskoj klimi ili zlato u subarktičkoj klimi. NewGFR-ovi bi mogli ovo izmeniti. "Simetrično" znači da će se otprilike ista količina tereta slati od stanice A prema stanici B kao i od B prema A. "Asimetrično" znači da će se proizvoljne količine tereta slati u oba smera. "Ručno" znači da se distribucija tih tereta neće vršiti automatski. Preporučljivo je namestiti ovu postavku na "asimetrično" ili "ručno" kod subarktičke klime jer banke neće slati zlato natrag prema rudnicima zlata. Za umerenu i subtropsku klimu može se namestiti i "simetrično" jer će banke slati neke dragocenosti natrag prema banci porekla. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Način distribucije za ostale klase tereta: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asimetrično" znači da odabrana količina tereta može biti poslana u svim smerovima. "ručno" znači da neće biti automatske distribucije za odabrane terete ###length 3 @@ -2134,15 +2134,15 @@ STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimetrično STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :simetrično STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Tačnost distribucije: {STRING} -STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Čim višu vrednost odaberete, CPU će trebati više vremena za izračun grafikona. Ako bude trebalo predugo, mogli bi primetiti usporavanje igre. U suprotnom, ako namestite na manju vrednost, distribucija će biti netočnija i mogli biste primetiti da se teret šalje na mesta koja niste očekivali. +STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Što je vrednost viša, biće potrebno više procesorskih resursa za izračun grafa. Ako proračun bude trajao predugo, to može izazvati usporenje igre. Ukoliko se vrednost podesi na manju vrednost, distribucija će biti manje tačna i može se desiti da teret bude poslat na neočekivana mesta. STR_CONFIG_SETTING_DEMAND_DISTANCE :Uticaj daljine na zahteve: {STRING} -STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Ako podesite ovu vrednost veće od 0, daljina između porekla stanice A nekog tereta i moguće destinacije B će imati uticaj na iznos poslatog tereta od A do B. Što daljnije B je od A, smaniće se iznos tereta što će biti poslat. Ako vrednost povećavate, manji iznos tereta će biti poslat dalekim mestima i veći iznos tereta će biti poslat bližnjim stanicama. +STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :Podešavanjem ove vrednosti na veću od 0, daljina između porekla stanice A nekog tereta i moguće destinacije B će imati uticaj na iznos poslatog tereta od A do B. Što je B dalje od A, smaniće se iznos tereta što će biti poslat. Ako se vrednost poveća, manji iznos tereta će biti poslat dalekim mestima i veći iznos tereta će biti poslat bližnjim stanicama. STR_CONFIG_SETTING_DEMAND_SIZE :Količina tereta koji se šalje natrag za simetrični mod: {STRING} -STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Postavljanje ovoga na manje od 100% daje da se simetrična distribucija ponaša sličnije asimetričnoj distribuciji. Manje tereta biti će prisilno vraćeno ako je određena količina poslata u stanicu. Ako postavku namestite na 0%, simetrična distribucija se ponaša tačno kao asimetrična distribucija. +STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Postavljanje ove vrednosti na manje od 100% čini da se simetrična distribucija ponaša sličnije asimetričnoj distribuciji. Manje tereta biti će prisilno vraćeno ako je određena količina poslata u stanicu. Postavljanjem vrednosti na 0%, simetrična distribucija se ponaša tačno kao asimetrična distribucija. -STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Zasićenje kratkih putova pre korišćenja putova velikih kapaciteta: {STRING} -STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Često postoji više puteva izmeđe dve stanice. Cargodist će prvo popuniti najkraći put, nakon toga koristiti drugi najkraći put dok se ne popuni itd. Popunjenost se određuje procenom kapaciteta i planirane upotrebe. Jednom kad se popune svi putevi i ako i dalje postoji potreba, pretrpati će sve puteve preferirajući one sa visokim kapacitetom. Ipak, algoritam najčešće neće proceniti kapacitet tačno. Ova postavka vam omogućava da specificirate do kojeg postotka će kraći put biti popunjen u prvom prolazu pre nego se počne popunjavati sledeći put. Namestite ga na manje od 100% da bi izbegli pretrpane stanice u slučaju previsoko procenjenog kapaciteta. +STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Zasićenje kratkih puteva pre korišćenja puteva velikih kapaciteta: {STRING} +STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Često postoji više puteva izmeđe dve stanice. Cargodist će prvo popuniti najkraći put, nakon toga koristiti drugi najkraći put dok se ne popuni itd. Popunjenost se određuje procenom nosivosti i planirane upotrebe. Jednom kad se popune svi putevi i ako i dalje postoji potreba, pretrpati će sve puteve preferirajući one sa visokim kapacitetom. Ipak, algoritam najčešće neće proceniti kapacitet tačno. Ova postavka omogućava da podešavanje do kojeg postotka će kraći put biti popunjen u prvom prolazu pre nego se počne popunjavati sledeći put. Podešavanjem na vrednost manje od 100% izbegavaju se pretrpane stanice u slučaju previsoko procenjenog kapaciteta. STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Mere brzine: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :Kada brzina bude pokazana u interfejsu, pokaži u željenoj meri @@ -2206,8 +2206,8 @@ STR_CONFIG_SETTING_GENWORLD :{ORANGE}Stvaran STR_CONFIG_SETTING_ENVIRONMENT :{ORANGE}Okoliš STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES :{ORANGE}Vlasti STR_CONFIG_SETTING_ENVIRONMENT_TOWNS :{ORANGE}Naselja -STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Industrije -STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distribucija Tovara +STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Fabrike +STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distribucija tereta STR_CONFIG_SETTING_AI :{ORANGE}Suparnici STR_CONFIG_SETTING_AI_NPC :{ORANGE}Računar STR_CONFIG_SETTING_NETWORK :{ORANGE}Mreža @@ -2222,7 +2222,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatska prom STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Dozvoljeno okretanje vozova na signalu, ako su dugo čekali ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Preporučuje se) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Preporučuje se) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Promena vrednosti @@ -2239,12 +2239,12 @@ STR_CONFIG_ERROR_INVALID_GRF_SYSTEM :sistem NewGRF STR_CONFIG_ERROR_INVALID_GRF_INCOMPATIBLE :nekompatibilno sa ovom OpenTTD verzijom STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN :nepoznato STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_LEVEL :{WHITE}... nivo kompresije '{STRING}' nije ispravan -STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM :{WHITE}... format sačuvane partije '{STRING}' nije dostupan. Vraćanje na '{STRING}' +STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM :{WHITE}... format sačuvane igre '{STRING}' nije dostupan. Vraćanje na '{STRING}' STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND :{WHITE}... ignoriram osnovni set grafike '{STRING}': nije pronađen STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND :{WHITE}...ignoriram osnovni skup zvukova '{STRING}': nije pronađen STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND :{WHITE}... ignoriram osnovni set muzike '{STRING}': nije pronađen STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}Nema više memorije -STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}Dodela {BYTES} predmemorije sprajtova nije uspelo. Predmemorija sprajtova je smanjena na {BYTES}. Ovo će smanjiti performanse OpenTTDa. Kako bi smanjili memorijske zahteve možete pokušati da isključite 32bpp grafiku i/ili nivo zumiranja +STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}Dodela {BYTES} predmemorije sprajtova nije uspelo. Predmemorija sprajtova je smanjena na {BYTES}. Ovo će smanjiti performanse OpenTTD-a. Radi smanjenja utroška memorije možeš da probaš da isključiš 32bpp grafiku i/ili nivo zumiranja # Video initalization errors STR_VIDEO_DRIVER_ERROR :{WHITE}Greška sa podešavanjima videa... @@ -2253,54 +2253,56 @@ STR_VIDEO_DRIVER_ERROR_NO_HARDWARE_ACCELERATION :{WHITE}... komp # Intro window STR_INTRO_CAPTION :{WHITE}OpenTTD {REV} -STR_INTRO_NEW_GAME :{BLACK}Nova Partija -STR_INTRO_LOAD_GAME :{BLACK}Učitavanje Partije -STR_INTRO_PLAY_SCENARIO :{BLACK}Partija sa Scenarijom -STR_INTRO_PLAY_HEIGHTMAP :{BLACK}Partija sa Elevacionom kartom -STR_INTRO_SCENARIO_EDITOR :{BLACK}Editor Scenarija -STR_INTRO_MULTIPLAYER :{BLACK}Partija preko Mreže +STR_INTRO_NEW_GAME :{BLACK}Nova igra +STR_INTRO_LOAD_GAME :{BLACK}Učitavanje igre +STR_INTRO_PLAY_SCENARIO :{BLACK}Igra sa scenariom +STR_INTRO_PLAY_HEIGHTMAP :{BLACK}Igra sa visinskom kartom +STR_INTRO_SCENARIO_EDITOR :{BLACK}Uređivač scenarija +STR_INTRO_MULTIPLAYER :{BLACK}Mrežna igra STR_INTRO_GAME_OPTIONS :{BLACK}Opcije STR_INTRO_HIGHSCORE :{BLACK}Tabela najboljih rezultata STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Podešavanja -STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Podešavanja -STR_INTRO_ONLINE_CONTENT :{BLACK}Spisak Dodataka na Mreži -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Podešavanja VI/Skripte Partije -STR_INTRO_QUIT :{BLACK}Izađi +STR_INTRO_NEWGRF_SETTINGS :{BLACK}Podešavanja NewGRF +STR_INTRO_ONLINE_CONTENT :{BLACK}Proveri dodatke na mreži +STR_INTRO_AI_SETTINGS :{BLACK}Podešavanja VI +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Podešavanja skripte +STR_INTRO_QUIT :{BLACK}Napusti -STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Započinje novu partiju. Ctrl+Klik preskače konfiguraciju mape +STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Započinje novu igru. Ctrl+klik preskače konfiguraciju mape STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}Učitavanje stare pozicije -STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}Pokreće novu partiju, koristeći elevacionu kartu kao teren -STR_INTRO_TOOLTIP_PLAY_SCENARIO :{BLACK}Započinje novu partiju, koristeći prethodno napravljen scenario +STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}Započinje novu igru, koristeći visinsku kartu kao teren +STR_INTRO_TOOLTIP_PLAY_SCENARIO :{BLACK}Započinje novu igru, koristeći prethodno napravljen scenario STR_INTRO_TOOLTIP_SCENARIO_EDITOR :{BLACK}Kreiranje sveta/scenarija u igri po svom ukusu -STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}Pokreće mrežnu partiju sa više igrača +STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}Pokreće mrežnu igru sa više igrača STR_INTRO_TOOLTIP_TEMPERATE :{BLACK}Izbor umerenog klimatskog pojasa STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}Izbor subpolarnog klimatskog pojasa STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}Izbor suptropskog klimatskog pojasa -STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Izbor 'zemlje igračaka' +STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Izbor zemlje igračaka STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Prikazuje opcije igre STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Prikazuje tabelu najboljih rezultata -STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Prikaži podešavanje -STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Prikazuje NewGRF podešavanja -STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Pregled novih i ažureiranih dodatka za preuzimanje -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Prikazuje podešavanja za VI/Skriptu partije +STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Prikazuje podešavanje +STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Prikazuje podešavanja NewGRF +STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Pregled novih i ažuriranih dodatka za preuzimanje +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Prikazuje podešavanja VI +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Prikazuje podešavanja skripte STR_INTRO_TOOLTIP_QUIT :{BLACK}Napušta 'OpenTTD' -STR_INTRO_BASESET :{BLACK}Trenutno odabranom skupu osnovne grafike nedostaje {NUM} sprajt{P "" "ova" "ova"}. Proverite da li postoje izmene za ovaj skup. -STR_INTRO_TRANSLATION :{BLACK}Ovom prevodu nedostaje {NUM} nisk{P a e i}. Pomozite da OpenTTD bude bolji - prijavite se kao prevodilac. Za detalje pogledajte readme.txt. +STR_INTRO_BASESET :{BLACK}Trenutno odabranom skupu osnovne grafike nedostaje {NUM} sprajt{P "" "ova" "ova"}. Proveri da li postoje izmene za ovaj skup. +STR_INTRO_TRANSLATION :{BLACK}Ovom prevodu nedostaje {NUM} nisk{P a e i}. Pomozi da OpenTTD bude bolji - prijavi se kao prevodilac. Za detalje pogledaj readme.txt. # Quit window STR_QUIT_CAPTION :{WHITE}Izlaz -STR_QUIT_ARE_YOU_SURE_YOU_WANT_TO_EXIT_OPENTTD :{YELLOW}Da li ste sigurni da želite da napustite OpenTTD? +STR_QUIT_ARE_YOU_SURE_YOU_WANT_TO_EXIT_OPENTTD :{YELLOW}Da li ste zaista želiš da napustiš OpenTTD? STR_QUIT_YES :{BLACK}Da STR_QUIT_NO :{BLACK}Ne # Abandon game -STR_ABANDON_GAME_CAPTION :{WHITE}Napuštanje partije -STR_ABANDON_GAME_QUERY :{YELLOW}Da li stvarno želite da napustite ovu partiju? -STR_ABANDON_SCENARIO_QUERY :{YELLOW}Da li stvarno želite da izađete iz ovog scenarija? +STR_ABANDON_GAME_CAPTION :{WHITE}Napuštanje igre +STR_ABANDON_GAME_QUERY :{YELLOW}Da li zaista želiš da napustiš ovu igru? +STR_ABANDON_SCENARIO_QUERY :{YELLOW}Da li zaista želiš da napustiš ovaj scenario? # Cheat window STR_CHEATS :{WHITE}Varanja @@ -2311,54 +2313,48 @@ STR_CHEAT_CHANGE_COMPANY :{LTBLUE}Upravlj STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Magični buldožer (uklanja fabrike, nepokretnosti): {ORANGE}{STRING} STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tuneli mogu da se ukrštaju: {ORANGE}{STRING} STR_CHEAT_NO_JETCRASH :{LTBLUE}Veliki avioni se neće (često) rušiti kod malih aerodorma: {ORANGE} {STRING} -STR_CHEAT_EDIT_MAX_HL :{LTBLUE}Promenite maksimalnu visinu mape: {ORANGE}{NUM} -STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}Promenite maksimalnu visinu planina na mapi +STR_CHEAT_EDIT_MAX_HL :{LTBLUE}Promeni maksimalnu visinu mape: {ORANGE}{NUM} +STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}Promeni maksimalnu visinu planina na mapi STR_CHEAT_CHANGE_DATE :{LTBLUE}Promena datuma: {ORANGE} {DATE_SHORT} STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Promena trenutne godine -STR_CHEAT_SETUP_PROD :{LTBLUE}Dozvoliti promenu količine proizvodnje: {ORANGE}{STRING} - -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Umereni klimatski pojas -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subpolarni klimatski pojas -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Suptropski klimatski pojas -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Zemlja igračaka +STR_CHEAT_SETUP_PROD :{LTBLUE}Dozvoli promenu količine proizvodnje: {ORANGE}{STRING} # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Šema boja -STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Prikaži generalnu mustru boja -STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Prikaži mustre boja vozova -STR_LIVERY_ROAD_VEHICLE_TOOLTIP :{BLACK}Prikaži mustre boja drumskih vozila -STR_LIVERY_SHIP_TOOLTIP :{BLACK}Prikaži mustre boja brodova -STR_LIVERY_AIRCRAFT_TOOLTIP :{BLACK}Prikaži mustre boja letilica -STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Izaberite osnovnu boju za označenu kategoriju. Ctrl+klik će izabrati ovu boju za sve kategorije -STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Izaberite dodatnu boju za označenu kategoriju. Ctrl+klik će izabrati ovu boju za sve kategorije -STR_LIVERY_PANEL_TOOLTIP :{BLACK}Označite kategoriju za izmenu boje, ili više njih koristeći Ctrl+Klik. Kliknite na kvadratić kako biste aktivirali korišćenje boje +STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Prikaži generalnu šemu boja +STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Prikaži šeme boja vozova +STR_LIVERY_ROAD_VEHICLE_TOOLTIP :{BLACK}Prikaži šeme boja drumskih vozila +STR_LIVERY_SHIP_TOOLTIP :{BLACK}Prikaži šeme boja brodova +STR_LIVERY_AIRCRAFT_TOOLTIP :{BLACK}Prikaži šeme boja letelica +STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Izaberi osnovnu boju za označenu kategoriju. Ctrl+klik će izabrati ovu boju za sve kategorije +STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Izaberi dodatnu boju za označenu kategoriju. Ctrl+klik će izabrati ovu boju za sve kategorije +STR_LIVERY_PANEL_TOOLTIP :{BLACK}Označi šemu boja za izmenu, ili više njih koristeći Ctrl+klik. Klikom na kutijicu aktivira se upotreba date šeme ###length 23 -STR_LIVERY_DEFAULT :Uobičajene Boje -STR_LIVERY_STEAM :Parna Lokomotiva -STR_LIVERY_DIESEL :Dizel Lokomotiva +STR_LIVERY_DEFAULT :Uobičajene boje +STR_LIVERY_STEAM :Parna lokomotiva +STR_LIVERY_DIESEL :Dizel lokomotiva STR_LIVERY_ELECTRIC :Električna Lokomotiva -STR_LIVERY_MONORAIL :Jednošinska Lokomotiva -STR_LIVERY_MAGLEV :Maglev Lokomotiva +STR_LIVERY_MONORAIL :Jednošinska lokomotiva +STR_LIVERY_MAGLEV :Maglev lokomotiva STR_LIVERY_DMU :DMU STR_LIVERY_EMU :EMU -STR_LIVERY_PASSENGER_WAGON_STEAM :Putnička Kola (Parna) -STR_LIVERY_PASSENGER_WAGON_DIESEL :Putnička Kola (Dizel) -STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Putnička Kola (Električna) -STR_LIVERY_PASSENGER_WAGON_MONORAIL :Putnička Kola (Jednošinska) -STR_LIVERY_PASSENGER_WAGON_MAGLEV :Putnička Kola (Maglev) -STR_LIVERY_FREIGHT_WAGON :Teretni Vagon +STR_LIVERY_PASSENGER_WAGON_STEAM :Putnička kola (parna) +STR_LIVERY_PASSENGER_WAGON_DIESEL :Putnička kola (dizel) +STR_LIVERY_PASSENGER_WAGON_ELECTRIC :Putnička kola (električna) +STR_LIVERY_PASSENGER_WAGON_MONORAIL :Putnička kola (jednošinska) +STR_LIVERY_PASSENGER_WAGON_MAGLEV :Putnička kola (Maglev) +STR_LIVERY_FREIGHT_WAGON :Teretni vagon STR_LIVERY_BUS :Autobus STR_LIVERY_TRUCK :Kamion -STR_LIVERY_PASSENGER_SHIP :Putnički Brod -STR_LIVERY_FREIGHT_SHIP :Teretni Brod +STR_LIVERY_PASSENGER_SHIP :Putnički trajekt +STR_LIVERY_FREIGHT_SHIP :Teretni brod STR_LIVERY_HELICOPTER :Helikopter -STR_LIVERY_SMALL_PLANE :Mali Avion -STR_LIVERY_LARGE_PLANE :Veliki Avion -STR_LIVERY_PASSENGER_TRAM :Putnički Tramvaj -STR_LIVERY_FREIGHT_TRAM :Teretni Tramvaj +STR_LIVERY_SMALL_PLANE :Mali avion +STR_LIVERY_LARGE_PLANE :Veliki avion +STR_LIVERY_PASSENGER_TRAM :Putnički tramvaj +STR_LIVERY_FREIGHT_TRAM :Teretni tramvaj # Face selection window STR_FACE_CAPTION :{WHITE}Izbor lica @@ -2378,7 +2374,7 @@ STR_FACE_SIMPLE :{BLACK}Jednosta STR_FACE_SIMPLE_TOOLTIP :{BLACK}Jednostavan odabir lica STR_FACE_LOAD :{BLACK}Učitaj STR_FACE_LOAD_TOOLTIP :{BLACK}Učitavanje omiljenog lica -STR_FACE_LOAD_DONE :{WHITE}Vaše omiljeno lice je učitano iz OpenTTD datoteke podešavanja +STR_FACE_LOAD_DONE :{WHITE}Tvoje omiljeno lice je učitano iz OpenTTD datoteke podešavanja STR_FACE_FACECODE :{BLACK}Redni broj lica STR_FACE_FACECODE_TOOLTIP :{BLACK}Pregled i/ili postavljanje rednog broja lica vlasnika preduzeća STR_FACE_FACECODE_CAPTION :{WHITE}Pregled i/ili postavljanje rednog broja lica vlasnika @@ -2425,48 +2421,49 @@ STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Javno STR_NETWORK_SERVER_VISIBILITY_INVITE_ONLY :Samo uz pozivnicu # Network server list -STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Mrežna partija +STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Mrežna igra STR_NETWORK_SERVER_LIST_PLAYER_NAME :{BLACK}Ime igrača: -STR_NETWORK_SERVER_LIST_ENTER_NAME_TOOLTIP :{BLACK}Sa ovim imenom će Vas drugi igrači (pre)poznavati +STR_NETWORK_SERVER_LIST_ENTER_NAME_TOOLTIP :{BLACK}Sa ovim imenom će te drugi igrači (pre)poznavati STR_NETWORK_SERVER_LIST_GAME_NAME :{BLACK}Naziv -STR_NETWORK_SERVER_LIST_GAME_NAME_TOOLTIP :{BLACK}Naziv partije +STR_NETWORK_SERVER_LIST_GAME_NAME_TOOLTIP :{BLACK}Naziv igre STR_NETWORK_SERVER_LIST_GENERAL_ONLINE :{BLACK}{COMMA}/{COMMA} - {COMMA}/{COMMA} STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION :{BLACK}Igrači STR_NETWORK_SERVER_LIST_CLIENTS_CAPTION_TOOLTIP :{BLACK}Priključeno igrača / najviše igrača{}Aktivnia preduzeća / najviše preduzeća STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT :{BLACK}{COMMA}x{COMMA} STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION :{BLACK}Veličina terena -STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION_TOOLTIP :{BLACK}Veličina terena u partiji{}Klikom će se poređati po veličini +STR_NETWORK_SERVER_LIST_MAP_SIZE_CAPTION_TOOLTIP :{BLACK}Veličina terena u igri{}Klikom će se poređati po veličini STR_NETWORK_SERVER_LIST_DATE_CAPTION :{BLACK}Datum -STR_NETWORK_SERVER_LIST_DATE_CAPTION_TOOLTIP :{BLACK}Trenutni datum u partiji +STR_NETWORK_SERVER_LIST_DATE_CAPTION_TOOLTIP :{BLACK}Trenutni datum u igri STR_NETWORK_SERVER_LIST_YEARS_CAPTION :{BLACK}Godina -STR_NETWORK_SERVER_LIST_YEARS_CAPTION_TOOLTIP :{BLACK}Ukupan broj godina{}koliko traje partija +STR_NETWORK_SERVER_LIST_YEARS_CAPTION_TOOLTIP :{BLACK}Ukupan broj godina{}koliko traje igra STR_NETWORK_SERVER_LIST_INFO_ICONS_TOOLTIP :{BLACK}Jezik, verzija servera, itd. -STR_NETWORK_SERVER_LIST_CLICK_GAME_TO_SELECT :{BLACK}Kliknite na partiju sa spiska da biste je obeležili -STR_NETWORK_SERVER_LIST_LAST_JOINED_SERVER :{BLACK}Server na koji ste se priključili prošli put: -STR_NETWORK_SERVER_LIST_CLICK_TO_SELECT_LAST :{BLACK}Kliknite kako biste označili server na kome ste igrali prošli put +STR_NETWORK_SERVER_LIST_CLICK_GAME_TO_SELECT :{BLACK}Klikom na igru sa spiska vrši se njen odabir +STR_NETWORK_SERVER_LIST_LAST_JOINED_SERVER :{BLACK}Server sa prošle igre: +STR_NETWORK_SERVER_LIST_CLICK_TO_SELECT_LAST :{BLACK}Klikom se označava server sa prošle igre -STR_NETWORK_SERVER_LIST_GAME_INFO :{SILVER}PODACI O PARTIJI +STR_NETWORK_SERVER_LIST_GAME_INFO :{SILVER}PODACI O IGRI STR_NETWORK_SERVER_LIST_CLIENTS :{SILVER}Igrača: {WHITE}{COMMA} / {COMMA} - {COMMA} / {COMMA} STR_NETWORK_SERVER_LIST_LANDSCAPE :{SILVER}Klima: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_MAP_SIZE :{SILVER}Veličina terena: {WHITE}{COMMA}x{COMMA} STR_NETWORK_SERVER_LIST_SERVER_VERSION :{SILVER}Verzija servera: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_SERVER_ADDRESS :{SILVER}Adresa servera: {WHITE}{STRING} +STR_NETWORK_SERVER_LIST_INVITE_CODE :{SILVER}Kod pozivnice: {WHITE}{STRING} STR_NETWORK_SERVER_LIST_START_DATE :{SILVER}Početni datum: {WHITE}{DATE_SHORT} STR_NETWORK_SERVER_LIST_CURRENT_DATE :{SILVER}Trenutni datum: {WHITE}{DATE_SHORT} STR_NETWORK_SERVER_LIST_GAMESCRIPT :{SILVER}Skripta igre: {WHITE}{STRING} (v{NUM}) STR_NETWORK_SERVER_LIST_PASSWORD :{SILVER}Zaštićeno šifrom! STR_NETWORK_SERVER_LIST_SERVER_OFFLINE :{SILVER}SERVER JE VAN MREŽE STR_NETWORK_SERVER_LIST_SERVER_FULL :{SILVER}SERVER JE POPUNJEN -STR_NETWORK_SERVER_LIST_SERVER_BANNED :{SILVER}SERVER VAS JE BLOKIRAO +STR_NETWORK_SERVER_LIST_SERVER_BANNED :{SILVER}SERVER TE JE BLOKIRAO STR_NETWORK_SERVER_LIST_SERVER_TOO_OLD :{SILVER}SERVER JE ZASTAREO STR_NETWORK_SERVER_LIST_VERSION_MISMATCH :{SILVER}NEODGOVARAJUĆA VERZIJA -STR_NETWORK_SERVER_LIST_GRF_MISMATCH :{SILVER}NEWGRF NEPOKLAPANJE +STR_NETWORK_SERVER_LIST_GRF_MISMATCH :{SILVER}NEPOKLAPANJE NEWGRF STR_NETWORK_SERVER_LIST_JOIN_GAME :{BLACK}Priključi se STR_NETWORK_SERVER_LIST_REFRESH :{BLACK}Ažuriranje servera -STR_NETWORK_SERVER_LIST_REFRESH_TOOLTIP :{BLACK}Ažurirajte podatke sa servera +STR_NETWORK_SERVER_LIST_REFRESH_TOOLTIP :{BLACK}Ažuriraj podatke sa servera STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET :{BLACK}Pretraži internet STR_NETWORK_SERVER_LIST_SEARCH_SERVER_INTERNET_TOOLTIP :{BLACK}Pretraži internet za javne servere @@ -2475,29 +2472,29 @@ STR_NETWORK_SERVER_LIST_SEARCH_SERVER_LAN_TOOLTIP :{BLACK}Pronađi STR_NETWORK_SERVER_LIST_ADD_SERVER :{BLACK}Dodaj server STR_NETWORK_SERVER_LIST_ADD_SERVER_TOOLTIP :{BLACK}Dodaje server na spisak. Može biti adresa servera ili kod pozivnice STR_NETWORK_SERVER_LIST_START_SERVER :{BLACK}Pokreni server -STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Pokrenite sopstveni server +STR_NETWORK_SERVER_LIST_START_SERVER_TOOLTIP :{BLACK}Pokreni sopstveni server -STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Unesite Vaše ime +STR_NETWORK_SERVER_LIST_PLAYER_NAME_OSKTITLE :{BLACK}Unesi svoje ime STR_NETWORK_SERVER_LIST_ENTER_SERVER_ADDRESS :{BLACK}Unesi adresu servera ili kod pozivnice # Start new multiplayer server -STR_NETWORK_START_SERVER_CAPTION :{WHITE}Pokreni novu mrežnu partiju +STR_NETWORK_START_SERVER_CAPTION :{WHITE}Pokreni novu mrežnu igru -STR_NETWORK_START_SERVER_NEW_GAME_NAME :{BLACK}Naziv partije: -STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}Naziv partije će se prikazati na spisku izbora mrežnih partija drugih igrača +STR_NETWORK_START_SERVER_NEW_GAME_NAME :{BLACK}Naziv igre: +STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}Naziv igre će se prikazati na spisku mrežnih igara drugim igračima STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Postavi lozinku -STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Ukoliko ne želite da bude javno dostupna zaštitite Vašu partiju lozinkom +STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Zaštiti igru lozinkom ukoliko ne želiš da bude javno vidljiva STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}Vidljivost STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP :{BLACK}Da li drugi igrači mogu videti tvoj server na javnom spisku STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} igrač{P "" a a} STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Najviše igrača: -STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}Odaberite koliko najviše može da ima igrača. Nemoraju sva mesta da budu popunjena +STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}Odaberi maksimalan broj klijenata. Ne moraju sva mesta biti popunjena STR_NETWORK_START_SERVER_COMPANIES_SELECT :{BLACK}{NUM} preduzeć{P e a a} STR_NETWORK_START_SERVER_NUMBER_OF_COMPANIES :{BLACK}Najviše preduzeća: -STR_NETWORK_START_SERVER_NUMBER_OF_COMPANIES_TOOLTIP :{BLACK}Odaberite koliko najviše može biti preduzeća na serveru +STR_NETWORK_START_SERVER_NUMBER_OF_COMPANIES_TOOLTIP :{BLACK}Odaberi maksimalan broj preduzeća na serveru -STR_NETWORK_START_SERVER_NEW_GAME_NAME_OSKTITLE :{BLACK}Unos naziva mrežne partije +STR_NETWORK_START_SERVER_NEW_GAME_NAME_OSKTITLE :{BLACK}Unos naziva mrežne igre # Network connecting window STR_NETWORK_CONNECTING_CAPTION :{WHITE}Povezivanje... @@ -2513,13 +2510,13 @@ STR_NETWORK_CONNECTING_3 :{BLACK}(3/6) Č STR_NETWORK_CONNECTING_4 :{BLACK}(4/6) Preuzimam teren... STR_NETWORK_CONNECTING_5 :{BLACK}(5/6) Obrađujem podatke... STR_NETWORK_CONNECTING_6 :{BLACK}(6/6) Prijavljujem se... -STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Tražim podatke o partiji... -STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Tražim podatke o preduzećima... +STR_NETWORK_CONNECTING_SPECIAL_1 :{BLACK}Preuzimanje podataka o igri... +STR_NETWORK_CONNECTING_SPECIAL_2 :{BLACK}Preuzimanje podataka o preduzećima... STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}Isključenje -STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server je zaštićen. Unesite lozinku -STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Preduzeće je zaštićeno. Unesite lozinku +STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server je zaštićen. Unesi lozinku +STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Preduzeće je zaštićeno. Unesi lozinku # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Prisutni igrači @@ -2544,17 +2541,16 @@ STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Ime igra STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}Promeni svoje ime STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION :Ime igrača STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}Administratorske akcije za ovaj klijent -STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}Administratorske akcije za ovu kompaniju -STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}Priključi se ovoj kompaniji +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}Administratorske akcije za ovo preduzeće +STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}Pridruži se ovom preduzeću STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}Pošalji poruku ovom igraču -STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Pošalji poruku svim igračima ove kompanije +STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Pošalji poruku svim igračima ovog preduzeća STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Pošalji poruku svim posmatračima STR_NETWORK_CLIENT_LIST_SPECTATORS :Posmatrači -STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(nova kompanija) -STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Napravi novu kompaniju i pridruži joj se +STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(novo preduzeće) +STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Napravi novo preduzeće i pridruži mu se STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Ovo si ti STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Ovo je domaćin igre -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klijen{P t ata ata} / {NUM} kompanij{P e a a} # Matches ConnectionType ###length 5 @@ -2570,13 +2566,13 @@ STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Obriši STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :Otključavanje lozinkom STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Administratorska akcija -STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Da li stvarno želite da izbacite igrača '{STRING}'? -STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Da li stvarno želite da blokirate igrača '{STRING}'? -STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Da li stvarno želite da obrišete kompaniju '{COMPANY}'? -STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Da li stvarno želite da promenite lozinku kompanije '{COMPANY}'? +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Da li zaista želiš da izbaciš igrača '{STRING}'? +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Da li zaista želiš da blokiraš igrača '{STRING}'? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Da li zaista želiš da obrišeš preduzeće '{COMPANY}'? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Da li zaista želiš da promeniš lozinku preduzeća '{COMPANY}'? STR_NETWORK_ASK_RELAY_CAPTION :{WHITE}Koristi relej? -STR_NETWORK_ASK_RELAY_TEXT :{YELLOW}Neuspelo uspostavljanje konekcije sa serverom '{STRING}'.{}Da li želite da uspostavite relejnu konekciju preko '{STRING}'? +STR_NETWORK_ASK_RELAY_TEXT :{YELLOW}Neuspelo uspostavljanje konekcije sa serverom '{STRING}'.{}Da li želiš da uspostaviš relejnu konekciju preko '{STRING}'? STR_NETWORK_ASK_RELAY_NO :{BLACK}Ne STR_NETWORK_ASK_RELAY_YES_ONCE :{BLACK}Da, jednom STR_NETWORK_ASK_RELAY_YES_ALWAYS :{BLACK}Da, ne pitaj ponovo @@ -2587,14 +2583,14 @@ STR_NETWORK_SPECTATORS :Posmatrači STR_COMPANY_PASSWORD_CANCEL :{BLACK}Otkaži unetu lozinku STR_COMPANY_PASSWORD_OK :{BLACK}Postavi preduzeću novu lozinku STR_COMPANY_PASSWORD_CAPTION :{WHITE}Lozinka za preduzeće -STR_COMPANY_PASSWORD_MAKE_DEFAULT :{BLACK}Uobičajena lozinka za preduzeće -STR_COMPANY_PASSWORD_MAKE_DEFAULT_TOOLTIP :{BLACK}Koristite ovu lozinku kao uobičajenu za nova preduzeća +STR_COMPANY_PASSWORD_MAKE_DEFAULT :{BLACK}Podrazumevana lozinka za preduzeće +STR_COMPANY_PASSWORD_MAKE_DEFAULT_TOOLTIP :{BLACK}Koristi ovu lozinku kao podrazumevanu za nova preduzeća # Network company info join/password -STR_COMPANY_VIEW_JOIN :{BLACK}Pridružite se +STR_COMPANY_VIEW_JOIN :{BLACK}Pridruži se STR_COMPANY_VIEW_JOIN_TOOLTIP :{BLACK}Pridruži se i igraj kao ovo preduzeće STR_COMPANY_VIEW_PASSWORD :{BLACK}Lozinka -STR_COMPANY_VIEW_PASSWORD_TOOLTIP :{BLACK}Zaštitite vaše preduzeće lozinkom kako se ne bi drugi korisnici neovlašćeno pridruživali +STR_COMPANY_VIEW_PASSWORD_TOOLTIP :{BLACK}Zaštiti svoje preduzeće lozinkom kako se drugi korisnici ne bi nedozvoljeno pridruživali STR_COMPANY_VIEW_SET_PASSWORD :{BLACK}Postavi lozinku za preduzeće # Network chat @@ -2609,24 +2605,24 @@ STR_NETWORK_CHAT_CLIENT :[Privatno] {STR STR_NETWORK_CHAT_TO_CLIENT :[Privatno] Za {STRING}: {WHITE}{STRING} STR_NETWORK_CHAT_ALL :[Svima] {STRING}: {WHITE}{STRING} STR_NETWORK_CHAT_EXTERNAL :[{3:STRING}] {0:STRING}: {WHITE}{1:STRING} -STR_NETWORK_CHAT_OSKTITLE :{BLACK}Unesite tekst poruke za razgovor +STR_NETWORK_CHAT_OSKTITLE :{BLACK}Unesi tekst poruke za razgovor # Network messages STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Nijedan mrežni uređaj nije nađen ili je igra kompajlirana bez ENABLE_NETWORK STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Konekcija ka serveru je istekla ili nije dozvoljena STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Povezivanje je neuspešno zbog nepoklapanja NewGRF-ova -STR_NETWORK_ERROR_DESYNC :{WHITE}Neuspešna sinhronizacija mrežne partije -STR_NETWORK_ERROR_LOSTCONNECTION :{WHITE}Veza sa mrežnom partijom je pukla -STR_NETWORK_ERROR_SAVEGAMEERROR :{WHITE}Neuspešno učitavanje sačuvane partije +STR_NETWORK_ERROR_DESYNC :{WHITE}Neuspešna sinhronizacija mrežne igre +STR_NETWORK_ERROR_LOSTCONNECTION :{WHITE}Veza sa mrežnom igrom je prekinuta +STR_NETWORK_ERROR_SAVEGAMEERROR :{WHITE}Neuspešno učitavanje sačuvane igre STR_NETWORK_ERROR_SERVER_START :{WHITE}Neuspešno pokretanje servera -STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Nastala je greška u protokolu i veza je zatvorena -STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}Ime igrača nije podešeno. Ono se može podesiti na vrhu prozora Partija preko mreže -STR_NETWORK_ERROR_BAD_SERVER_NAME :{WHITE}Naziv tvog servera nije podešen. Naziv može biti promenjen na vrhu prozora Partija preko mreže +STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Nastala je greška u protokolu i veza je prekinuta +STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}Ime igrača nije podešeno. Ono se može podesiti na vrhu prozora Mrežna igra +STR_NETWORK_ERROR_BAD_SERVER_NAME :{WHITE}Naziv tvog servera nije podešen. Naziv može biti promenjen na vrhu prozora Mrežna igra STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}Revizija igre ovog klijenta se ne poklapa sa revizijom servera STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Pogrešna lozinka STR_NETWORK_ERROR_SERVER_FULL :{WHITE}Server je pun -STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}Vi ste zauvek izbačeni sa ovog servera -STR_NETWORK_ERROR_KICKED :{WHITE}Vi ste izbačeni iz ove partije +STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}Trajno izbačen/a sa ovog servera +STR_NETWORK_ERROR_KICKED :{WHITE}Izbačen/a iz trenutne igre STR_NETWORK_ERROR_KICK_MESSAGE :{WHITE}Razlog: {STRING} STR_NETWORK_ERROR_CHEATER :{WHITE}Varanja nisu dozvoljena na ovom serveru STR_NETWORK_ERROR_TOO_MANY_COMMANDS :{WHITE}Slali ste previše naredbi na server @@ -2634,7 +2630,7 @@ STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}Trebalo STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Računar je suviše spor da bi ispratio rad servera STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Računaru je suviše dugo trebalo da preuzme mapu STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Računaru je suviše dugo trebalo da se priključi serveru -STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Vaš naziv igrača nije ispravan +STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Tvoje ime igrača nije ispravno STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Moguć gubitak veze STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION :{WHITE}U poslednj{P 0 oj e ih} {NUM} sekund{P i e i} nije primljen nijedan podatak sa servera @@ -2666,31 +2662,31 @@ STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :neispravan nazi STR_NETWORK_SERVER_MESSAGE :*** {1:STRING} ###length 12 -STR_NETWORK_SERVER_MESSAGE_GAME_PAUSED :Partija je pauzirana ({STRING}) -STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_1 :Partija je još uvek pauzirana ({STRING}) -STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_2 :Partija je još uvek pauzirana ({STRING}, {STRING}) -STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_3 :Partija je još uvek pauzirana ({STRING}, {STRING}, {STRING}) -STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_4 :Partija je još uvek pauzirana ({STRING}, {STRING}, {STRING}, {STRING}) -STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_5 :Partija je još uvek pauzirana ({STRING}, {STRING}, {STRING}, {STRING}, {STRING}) -STR_NETWORK_SERVER_MESSAGE_GAME_UNPAUSED :Partija je nastavljena ({STRING}) +STR_NETWORK_SERVER_MESSAGE_GAME_PAUSED :Igra je pauzirana ({STRING}) +STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_1 :Igra je još uvek pauzirana ({STRING}) +STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_2 :Igra je još uvek pauzirana ({STRING}, {STRING}) +STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_3 :Igra je još uvek pauzirana ({STRING}, {STRING}, {STRING}) +STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_4 :Igra je još uvek pauzirana ({STRING}, {STRING}, {STRING}, {STRING}) +STR_NETWORK_SERVER_MESSAGE_GAME_STILL_PAUSED_5 :Igra je još uvek pauzirana ({STRING}, {STRING}, {STRING}, {STRING}, {STRING}) +STR_NETWORK_SERVER_MESSAGE_GAME_UNPAUSED :Igra je nastavljena ({STRING}) STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS :nema dovoljno igrača STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS :priključivanje igrača STR_NETWORK_SERVER_MESSAGE_GAME_REASON_MANUAL :ručno -STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT :skripta partije +STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT :skripta igre STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :čeka se dopuna grafa STR_NETWORK_MESSAGE_CLIENT_LEAVING :napušta -STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} se priključio partiji -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} se pridružio partiji (Igrač #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} se pridružio preduzeću #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} se priključio igri +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} se pridružio igri (klijent #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} se pridružio preduzeću #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} se pridružio posmatračima -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} je osnovao novo preduzeće (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} je napustio partiju ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} je osnovao novo preduzeće (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} je napustio igru ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} je promenio/la ime u {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} je dao {2:CURRENCY_LONG} preduzeću {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} je dao {2:CURRENCY_LONG} preduzeću {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server je zatvorio sesiju -STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server se ponovo pokreće...{}Molimo sačekajte... -STR_NETWORK_MESSAGE_KICKED :*** {STRING} je izvačen. Razlog: ({STRING}) +STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server se ponovo pokreće...{}Molimo sačekaj... +STR_NETWORK_MESSAGE_KICKED :*** {STRING} je izbačen. Razlog: ({STRING}) STR_NETWORK_ERROR_COORDINATOR_REGISTRATION_FAILED :{WHITE}Neuspešna registracija na serveru STR_NETWORK_ERROR_COORDINATOR_REUSE_OF_INVITE_CODE :{WHITE}Drugi server sa istim kodom pozivnice je već registrovan. Tip igre je promenjen na "lokalno". @@ -2703,17 +2699,17 @@ STR_CONTENT_TYPE_CAPTION :{BLACK}Vrsta STR_CONTENT_TYPE_CAPTION_TOOLTIP :{BLACK}Vrsta dodatka STR_CONTENT_NAME_CAPTION :{BLACK}Naziv STR_CONTENT_NAME_CAPTION_TOOLTIP :{BLACK}Naziv dodatka -STR_CONTENT_MATRIX_TOOLTIP :{BLACK}Kliknite kako biste videli detalje{}Kliknite na kvadratić kako biste ga označili za skidanje +STR_CONTENT_MATRIX_TOOLTIP :{BLACK}Klikni na liniju za detalje detalje{}Klikni na kutijicu radi označavanja za preuzimanje STR_CONTENT_SELECT_ALL_CAPTION :{BLACK}Označi sve STR_CONTENT_SELECT_ALL_CAPTION_TOOLTIP :{BLACK}Obeležava sve dodatke za preuzimanje STR_CONTENT_SELECT_UPDATES_CAPTION :{BLACK}Obeleži ažurirana STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP :{BLACK}Obeležava sve preuzete dodatke koje imaju novija izdanja za preuzimanje -STR_CONTENT_UNSELECT_ALL_CAPTION :{BLACK}Poništi izbor svega -STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP :{BLACK}Otkazuje preuzimanje svih dodataka +STR_CONTENT_UNSELECT_ALL_CAPTION :{BLACK}Poništi odabir +STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP :{BLACK}Otkaži preuzimanje svih dodataka STR_CONTENT_SEARCH_EXTERNAL :{BLACK}Pretraži eksterne web stranice STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP :{BLACK}Traženi sadržaj nije dostupan u OpenTTD servisu za sadržaje za web stranice koje nisu pridružene u OpenTTD -STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}Vi napuštate OpenTTD! -STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER :{WHITE}Odredbe i uslovi za preuzimanje sadržaja sa spoljnih sajtova varira.{}Moraćete pogledati spoljašnje sajtove za uputstva kako da instalirate sadržaj u OpenTTD.{}Želite li da nastavite? +STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}Napuštaš OpenTTD! +STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER :{WHITE}Odredbe i uslovi za preuzimanje sadržaja sa spoljnih sajtova varira.{}Moraćeš da pogledaš spoljašnje sajtove za uputstva u vezi instalacije sadržaja u OpenTTD.{}Želiš li da nastaviš? STR_CONTENT_FILTER_TITLE :{BLACK}Filter po oznaci/nazivu: STR_CONTENT_OPEN_URL :{BLACK}Idi na Web lokaciju STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Ovaj sadržaj nalazi se na Web lokaciji @@ -2751,7 +2747,7 @@ STR_CONTENT_TYPE_SCENARIO :Scenario STR_CONTENT_TYPE_HEIGHTMAP :Elevaciona karta STR_CONTENT_TYPE_BASE_SOUNDS :Osnovni zvukovi STR_CONTENT_TYPE_BASE_MUSIC :Osnovna muzika -STR_CONTENT_TYPE_GAME_SCRIPT :Skripta partije +STR_CONTENT_TYPE_GAME_SCRIPT :Skripta igre STR_CONTENT_TYPE_GS_LIBRARY :SP biblioteka # Content downloading progress window @@ -2773,27 +2769,27 @@ STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}Da, preu STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}Ne, napusti OpenTTD STR_MISSING_GRAPHICS_ERROR_TITLE :{WHITE}Neuspešno preuzimanje -STR_MISSING_GRAPHICS_ERROR :{BLACK}Preuzimanje grafike nije uspelo.{}Pokušajte da preuzmete grafiku ručno. +STR_MISSING_GRAPHICS_ERROR :{BLACK}Preuzimanje grafike nije uspelo.{}Pokušaj da grafiku preuzmeš ručno. STR_MISSING_GRAPHICS_ERROR_QUIT :{BLACK}Napusti OpenTTD # Transparency settings window STR_TRANSPARENCY_CAPTION :{WHITE}Podešavanja Prozirnosti -STR_TRANSPARENT_SIGNS_TOOLTIP :{BLACK}Promena prozirnosti znakova. Sa Ctrl+Klik se zaključava -STR_TRANSPARENT_TREES_TOOLTIP :{BLACK}Promena prozirnosti drveća. Sa Ctrl+Klik se zaključava -STR_TRANSPARENT_HOUSES_TOOLTIP :{BLACK}Promena prozirnosti zgrada. Sa Ctrl+Klik se zaključava -STR_TRANSPARENT_INDUSTRIES_TOOLTIP :{BLACK}Promena prozirnosti fabrika. Sa Ctrl+Klik se zaključava -STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Promena prozirnosti građevina poput stanica, depoa i putanja. Sa Ctrl+Klik se zaključava -STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Promena prozirnosti mostova. Sa Ctrl+Klik se zaključava -STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Promena prozirnosti građevina poput svetionika i repetitora. Sa Ctrl+Klik se zaključava -STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Promena prozirnosti kontaktnih mreža. Sa Ctrl+Klik se zaključava -STR_TRANSPARENT_LOADING_TOOLTIP :{BLACK}Promena prozirnosti pokazatelja utovara. Sa Ctrl+Klik se zaključava +STR_TRANSPARENT_SIGNS_TOOLTIP :{BLACK}Promena prozirnosti znakova. Sa Ctrl+klik se zaključava +STR_TRANSPARENT_TREES_TOOLTIP :{BLACK}Promena prozirnosti drveća. Sa Ctrl+klik se zaključava +STR_TRANSPARENT_HOUSES_TOOLTIP :{BLACK}Promena prozirnosti zgrada. Sa Ctrl+klik se zaključava +STR_TRANSPARENT_INDUSTRIES_TOOLTIP :{BLACK}Promena prozirnosti fabrika. Sa Ctrl+klik se zaključava +STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Promena prozirnosti građevina poput stanica, depoa i putanja. Sa Ctrl+klik se zaključava +STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Promena prozirnosti mostova. Sa Ctrl+klik se zaključava +STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Promena prozirnosti građevina poput svetionika i repetitora. Sa Ctrl+klik se zaključava +STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Promena prozirnosti kontaktnih mreža. Sa Ctrl+klik se zaključava +STR_TRANSPARENT_LOADING_TOOLTIP :{BLACK}Promena prozirnosti pokazatelja utovara. Sa Ctrl+klik se zaključava STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Čini objekte nevidljivim umesto prozirnim # Linkgraph legend window STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Legenda protoka tereta STR_LINKGRAPH_LEGEND_ALL :{BLACK}Sve STR_LINKGRAPH_LEGEND_NONE :{BLACK}Nema -STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Odaberite preduzeća koja želite da se prikažu +STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Odaberi preduzeća koja želiš da se prikažu STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap @@ -2801,6 +2797,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}zasićen STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}Preopterećen +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} će biti prevezeno svakog meseca od {STATION} do {STATION} ({COMMA}% kapaciteta){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} će biti prevezeno nazad ({COMMA}% kapaciteta) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Prosečno vreme putovanja: {NUM}{NBSP}dan{P "" a a} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Označavanje zahvaćenog područja STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Isključeno @@ -2809,6 +2810,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Isključ STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Uključi označavanje zahvaćenog područja STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Prihvata: {GOLD}{CARGO_LIST.aku} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Snabdeva: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Troškovi održavanja: {GOLD}{CURRENCY_SHORT}/god # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Pridruži stanicu @@ -2831,7 +2833,7 @@ STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Izgradnj STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Izgradnja voznog depoa (za pravljenje novih, kao i za servis starih vozova). Shift prebacuje između izgradnje i prikaza procene troškova STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Promena pruge u čvorište. Uz Ctrl se spaja sa drugim čvorištima. Shift prebacuje između promene i prikaza procene troškova STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Izgradnja železničke stanice. Uz Ctrl se spaja sa drugim stanicama. Shift prebacuje između izgradnje i prikaza procene troškova -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Izgradnja železničke signalizacije. Ctrl uključuje semafore/svetlosne signale{}Prevlačenjem se grade signali duž prave linije pruge. Ctrl gradi signale do sledeće raskrsnice{}Ctrl+Klik uključuje otvaranje prozora za izbor signala. Shift prebacuje između izgradnje i prikaza procene troškova +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Izgradnja železničke signalizacije. Ctrl uključuje semafore/svetlosne signale{}Prevlačenjem se grade signali duž prave linije pruge. Ctrl gradi signale do sledeće raskrsnice{}Ctrl+klik uključuje otvaranje prozora za odabir signala. Shift prebacuje između izgradnje i prikaza procene troškova STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Izgradnja železničkog mosta. Shift prebacuje između izgradnje i prikaza procene troškova STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Izgradnja železničkog tunela. Shift prebacuje između izgradnje i prikaza procene troškova STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Izgradnja/Uklanjanje železničkih pruga, signalizacije, putnih tačaka i stanica (kad je uključeno). Držanjem Ctrl takođe se uklanja pruga sa putnih tačaka i stanica @@ -2844,44 +2846,45 @@ STR_RAIL_NAME_MAGLEV :Magnetna želez # Rail depot construction window STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION :{WHITE}Orijentacija železničkog depoa -STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP :{BLACK}Izbor orijentacije železničkog depoa +STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP :{BLACK}Odabir orijentacije železničkog depoa # Rail waypoint construction window STR_WAYPOINT_CAPTION :{WHITE}Putanja -STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Odaberite tip putanje +STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Odaberi tip putanje # Rail station construction window STR_STATION_BUILD_RAIL_CAPTION :{WHITE}Izbor železničke stanice STR_STATION_BUILD_ORIENTATION :{BLACK}Orijentacija -STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP :{BLACK}Izbor orijentacije železničke stanice +STR_STATION_BUILD_RAILROAD_ORIENTATION_TOOLTIP :{BLACK}Odabir orijentacije železničke stanice STR_STATION_BUILD_NUMBER_OF_TRACKS :{BLACK}Broj koloseka -STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP :{BLACK}Izbor broja koloseka +STR_STATION_BUILD_NUMBER_OF_TRACKS_TOOLTIP :{BLACK}Odabir broja koloseka STR_STATION_BUILD_PLATFORM_LENGTH :{BLACK}Dužina platforme -STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP :{BLACK}Izbor dužine stanice +STR_STATION_BUILD_PLATFORM_LENGTH_TOOLTIP :{BLACK}Odabir dužine stanice STR_STATION_BUILD_DRAG_DROP :{BLACK}Prevlačenje STR_STATION_BUILD_DRAG_DROP_TOOLTIP :{BLACK}Gradnja stanice prevlačenjem -STR_STATION_BUILD_STATION_CLASS_TOOLTIP :{BLACK}Izbor klase stanica za prikaz -STR_STATION_BUILD_STATION_TYPE_TOOLTIP :{BLACK}Odaberite vrstu stanice za gradnju +STR_STATION_BUILD_STATION_CLASS_TOOLTIP :{BLACK}Odabir klase stanica za prikaz +STR_STATION_BUILD_STATION_TYPE_TOOLTIP :{BLACK}Odabir vrste stanice za izgradnju STR_STATION_CLASS_DFLT :Podrazumevana stanica STR_STATION_CLASS_WAYP :Putanje # Signal window -STR_BUILD_SIGNAL_CAPTION :{WHITE}Izbor Signalizacije -STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Blok Signalizacija (semafor){}Ovo je najosnovnija vrsta signalizacije, dozvoljava samo jedan voz da bude u istoj deonici -STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}Ulazna Signalizacija (semafor){}Otvoren prolaz ukoliko postoji jedna ili više otvorenih izlaznih signalizacija sa nastupajuće deonice. U suprotnom je zatvoren -STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Izlazna Signalizacija (semafor){}Ponaša se isto kao i blok signalizacija ali je neophodan za uparivanje sa ulaznom i/ili kombinovanom signalizacijom -STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Kombinovana Signalizacija (semafor){}Kombinovana signalizacija se ponaša kao ulazna i izlazna signalizacija. Ovim se omogućava gradnja velikih "stabala" predsignalizacije -STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}Putna Signalizacija (semafor){}Putna signalizacija omogućava da više vozova istovremeno uđe u istu deonicu, ukoliko mogu da obezbede put do zasebnog zaustavnog koloseka. Standardnu putnu signalizaciju moguće je proći i sa suprotnog smera -STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP :{BLACK}Jednosmerna Putna Signalizacija (semafor){}Putna signalizacija omogućava da više vozova istovremeno uđe u istu deonicu, ukoliko mogu da obezbede put do zasebnog zaustavnog koloseka. Jednosmerna putna signalizacija zabranjuje prolaz sa suprotnog smera -STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Blok Signalizacija (svetlosni semafor){}Ovo je najosnovnija vrsta signalizacije, dozvoljava samo jedan voz da bude u istoj deonici -STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}Ulazna Signalizacija (svetlosni semafor){}Otvoren prolaz ukoliko postoji jedna ili više otvorenih izlaznih signalizacija sa nastupajuće deonice. U suprotnom je zatvoren -STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Izlazna Signalizacija (svetlosni semafor){}Ponaša se isto kao i blok signalizacija ali je neophodan za uparivanje sa ulaznom i/ili kombinovanom signalizacijom -STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Kombinovana Signalizacija (svetlosni semafor){}Kombinovana signalizacija se ponaša kao ulazna i izlazna signalizacija. Ovim se omogućava gradnja velikih "stabala" predsignalizacije -STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Putna Signalizacija (svetlosni semafor){}Putna signalizacija omogućava da više vozova istovremeno uđe u istu deonicu, ukoliko mogu da obezbede put do zasebnog zaustavnog koloseka. Standardnu putnu signalizaciju moguće je proći i sa suprotnog smera -STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Jednosmerna Putna Signalizacija (svetlosni semafor){}Putna signalizacija omogućava da više vozova istovremeno uđe u istu deonicu, ukoliko mogu da obezbede put do zasebnog zaustavnog koloseka. Jednosmerna putna signalizacija zabranjuje prolaz sa suprotnog smera -STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Promena Signalizacije{}Kada je označeno, klikom na postojeću signalizaciju promeniće je na izabranu vrstu i podvrstu, sa Ctrl+klik će se označiti postojeća podvrsta. Shift+klik prikazuje procenu troškova promene +STR_BUILD_SIGNAL_CAPTION :{WHITE}Odabir signalizacije +STR_BUILD_SIGNAL_TOGGLE_ADVANCED_SIGNAL_TOOLTIP :{BLACK}Prikaz naprednih tipova signala +STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Blok signalizacija (semafor){}Ovo je najosnovnija vrsta signalizacije, dozvoljava samo jedan voz da bude u istoj deonici +STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}Ulazna signalizacija (semafor){}Otvoren prolaz ukoliko postoji jedna ili više otvorenih izlaznih signalizacija sa nastupajuće deonice. U suprotnom je zatvoren +STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Izlazna signalizacija (semafor){}Ponaša se isto kao i blok signalizacija ali je neophodan za uparivanje sa ulaznom i/ili kombinovanom signalizacijom +STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Kombinovana signalizacija (semafor){}Kombinovana signalizacija se ponaša kao ulazna i izlazna signalizacija. Ovim se omogućava gradnja velikih "stabala" predsignalizacije +STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}Putna signalizacija (semafor){}Putna signalizacija omogućava da više vozova istovremeno uđe u istu deonicu, ukoliko mogu da obezbede put do zasebnog zaustavnog koloseka. Standardnu putnu signalizaciju moguće je proći i sa suprotnog smera +STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP :{BLACK}Jednosmerna putna signalizacija (semafor){}Putna signalizacija omogućava da više vozova istovremeno uđe u istu deonicu, ukoliko mogu da obezbede put do zasebnog zaustavnog koloseka. Jednosmerna putna signalizacija zabranjuje prolaz sa suprotnog smera +STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Blok signalizacija (električna){}Ovo je najosnovnija vrsta signalizacije, dozvoljava samo jedan voz da bude u istoj deonici +STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}Ulazna signalizacija (električna){}Otvoren prolaz ukoliko postoji jedna ili više otvorenih izlaznih signalizacija sa nastupajuće deonice. U suprotnom je zatvoren +STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Izlazna signalizacija (električna){}Ponaša se isto kao i blok signalizacija ali je neophodan za uparivanje sa ulaznom i/ili kombinovanom signalizacijom +STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Kombinovana signalizacija (električna){}Kombinovana signalizacija se ponaša kao ulazna i izlazna signalizacija. Ovim se omogućava gradnja velikih "stabala" predsignalizacije +STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Putna signalizacija (električna){}Putna signalizacija omogućava da više vozova istovremeno uđe u istu deonicu, ukoliko mogu da obezbede put do zasebnog zaustavnog koloseka. Standardnu putnu signalizaciju moguće je proći i sa suprotnog smera +STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Jednosmerna putna signalizacija (električna){}Putna signalizacija omogućava da više vozova istovremeno uđe u istu deonicu, ukoliko mogu da obezbede put do zasebnog zaustavnog koloseka. Jednosmerna putna signalizacija zabranjuje prolaz sa suprotnog smera +STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Promena signalizacije{}Kada je označeno, klikom na postojeću signalizaciju promeniće je na izabranu vrstu i podvrstu, sa Ctrl+klik će se označiti postojeća podvrsta. Shift+klik prikazuje procenu troškova promene STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Razmak između signalizacija tokom povlačenja STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Smanjivanje razmaka između signalizacija STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Povećavanje razmaka između signalizacija @@ -2890,8 +2893,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Povećav STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Izbor železničkog mosta STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Izbor drumskog mosta STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Izbor mosta - gradnja se potvrđuje klikom na željeni most -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Viseći, čelični STR_BRIDGE_NAME_GIRDER_STEEL :Gredni, čelični STR_BRIDGE_NAME_CANTILEVER_STEEL :Obešeni, čelični @@ -2899,7 +2900,7 @@ STR_BRIDGE_NAME_SUSPENSION_CONCRETE :Viseći, betons STR_BRIDGE_NAME_WOODEN :Drveni STR_BRIDGE_NAME_CONCRETE :Betonski STR_BRIDGE_NAME_TUBULAR_STEEL :Cevasti, čelični -STR_BRIDGE_TUBULAR_SILICON :Cevni, Silicijumski +STR_BRIDGE_TUBULAR_SILICON :Cevasti, silicijumski # Road construction toolbar @@ -2913,7 +2914,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Izgradnj STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Izgradnja tramvajskog depoa (za izgradnju novih i servis starih tramvaja). Shift prebacuje između izgradnje i prikaza procene troškova STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Izgradnja autobuske stanice. Uz Ctrl se spaja sa drugim stanicama. Shift prebacuje između izgradnje i prikaza procene troškova STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Izgradnja putničke tamvajske stanice. Uz Ctrl se spaja sa drugim stanicama. Shift prebacuje između izgradnje i prikaza procene troškova -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Izgradnja tovarne stanice. Uz Ctrl se spaja sa drugim stanicama. Shift prebacuje između izgradnje i prikaza procene troškova +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}Izgradnja teretne stanice. Uz Ctrl se spaja sa drugim stanicama. Shift prebacuje između izgradnje i prikaza procene troškova STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION :{BLACK}Izgradnja teretne tamvajske stanice. Uz Ctrl se spaja sa drugim stanicama. Shift prebacuje između izgradnje i prikaza procene troškova STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD :{BLACK}Izgradnja jednosmernih puteva (kada je uključeno) STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE :{BLACK}Izgradnja drumskog mosta. Shift prebacuje između izgradnje i prikaza procene troškova @@ -2930,19 +2931,19 @@ STR_ROAD_NAME_TRAM :Tramvaj # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Orijentacija drumskog depoa -STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Izbor orijentacije drumskog depoa -STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION :{WHITE}Izbor orijentacije tramvajskog depoa -STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Izbor orijentacije tramvajskog depoa +STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Odabir orijentacije drumskog depoa +STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION :{WHITE}Odabir orijentacije tramvajskog depoa +STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Odabir orijentacije tramvajskog depoa # Road vehicle station construction window STR_STATION_BUILD_BUS_ORIENTATION :{WHITE}Orijentacija autobuske stanice -STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP :{BLACK}Izbor orijentacije autobuske stanice +STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP :{BLACK}Odabir orijentacije autobuske stanice STR_STATION_BUILD_TRUCK_ORIENTATION :{WHITE}Orijentacija stanice za utovar kamiona STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP :{BLACK}Izbor orijentacije stanice za utovar kamiona STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION :{WHITE}Orijentacija tramvajske putničke stanice -STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP :{BLACK}Odaberite orijentaciju putničke tramvajske stanice +STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP :{BLACK}Odabir orijentaciju putničke tramvajske stanice STR_STATION_BUILD_CARGO_TRAM_ORIENTATION :{WHITE}Orijentacija tramvajske teretne stanice -STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP :{BLACK}Odaberite orijentaciju teretne tamvajske stanice +STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP :{BLACK}Odabir orijentacije teretne tamvajske stanice # Waterways toolbar (last two for SE only) STR_WATERWAYS_TOOLBAR_CAPTION :{WHITE}Izgradnja plovnog sistema @@ -2953,12 +2954,12 @@ STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Gradnja STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Gradnja pristaništa. Uz Ctrl se spaja sa drugim stanicama. Shift prebacuje između izgradnje i prikaza procene troškova STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Postavlja bovu kako bi služila kao putokaz. Shift prebacuje između postavljanja i prikaza procene troškova STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Izgradnja akvadukta. Shift prebacuje između izgradnje i prikaza procene troškova -STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Vodena površina.{}Napravite kanal, ukoliko držite i Ctrl dok ste na nivou mora, tada popunjavate okolinu vodom -STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Postavljanje reka. Ctrl obeležava dijagonalno područje +STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Vodena površina.{}Napravi kanal, a ukoliko držiš i Ctrl dok ste na nivou mora, tada popunjavaš okolinu vodom +STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Postavljanje reka. Ctrl dijagonalno obeležava područje # Ship depot construction window STR_DEPOT_BUILD_SHIP_CAPTION :{WHITE}Orijentacija brodskog hangara -STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP :{BLACK}Izbor orijentacije brodskog hangara +STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP :{BLACK}Odabir orijentacije brodskog hangara # Dock construction window STR_STATION_BUILD_DOCK_CAPTION :{WHITE}Pristanište @@ -2970,7 +2971,7 @@ STR_TOOLBAR_AIRCRAFT_BUILD_AIRPORT_TOOLTIP :{BLACK}Izgradnj # Airport construction window STR_STATION_BUILD_AIRPORT_CAPTION :{WHITE}Izbor aerodroma STR_STATION_BUILD_AIRPORT_TOOLTIP :{BLACK}Izbor veličine/tipa aerodroma -STR_STATION_BUILD_AIRPORT_CLASS_LABEL :{BLACK}Tip aerodroma +STR_STATION_BUILD_AIRPORT_CLASS_LABEL :{BLACK}Klasa aerodroma STR_STATION_BUILD_AIRPORT_LAYOUT_NAME :{BLACK}Raspored {NUM} STR_AIRPORT_SMALL :Poljski aerodrom @@ -2992,15 +2993,15 @@ STR_STATION_BUILD_NOISE :{BLACK}Proizved # Landscaping toolbar STR_LANDSCAPING_TOOLBAR :{WHITE}Oblikovanje terena -STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Spušta ugao tla. Povlačenjem spušta prvi obeleženi ugao i izjednačava ostatk područja na nov nivo. Ctrl obeležava dijagonalno područje. Shift prebacuje između spuštanja i prikaza procene troškova -STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Podiže ugao tla. Povlačenjem podiže prvi obeleženi ugao i izjednačava ostatk područja na nov nivo. Ctrl obeležava dijagonalno područje. Shift prebacuje između podizanja i prikaza procene troškova -STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Izjednačava područje na najviši nivo prvo označenog ugla. Ctrl obeležava dijagonalno područje. Shift prebacuje između izjednačavanja i prikaza procene troškova -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Kupovina zemljišta za kasnije korišćenje. Shift prebacuje između kupovine i prikaza procene troškova kupovine +STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Spušta ugao tla. Povlačenjem spušta prvi obeleženi ugao i izjednačava ostatk područja na nov nivo. Ctrl dijagonalno obeležava područje. Shift prebacuje između spuštanja i prikaza procene troškova +STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Podiže ugao tla. Povlačenjem podiže prvi obeleženi ugao i izjednačava ostatk područja na nov nivo. Ctrl dijagonalno obeležava područje. Shift prebacuje između podizanja i prikaza procene troškova +STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Izjednačava područje na najviši nivo prvo označenog ugla. Ctrl dijagonalno obeležava područje. Shift prebacuje između izjednačavanja i prikaza procene troškova +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Kupovina zemljišta za kasnije korišćenje. Ctrl dijagonalno obeležava područje. Shift prebacuje između kupovine i prikaza procene troškova kupovine # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Izbor Objekta -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Odabir objekta za izgradnju. Shift prebacuje između izgradnje i prikaza procene troškova -STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Izbor klase objekata za izgradnju +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Odabir objekta za izgradnju. Ctrl dijagonalno obeležava područje. Shift prebacuje između izgradnje i prikaza procene troškova +STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Odabir klase objekata za izgradnju STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Privremeno prikazuje objekat STR_OBJECT_BUILD_SIZE :{BLACK}Veličina: {GOLD}{NUM} x {NUM} pločica @@ -3033,22 +3034,24 @@ STR_TERRAFORM_RESET_LANDSCAPE :{BLACK}Obnovi r STR_TERRAFORM_RESET_LANDSCAPE_TOOLTIP :{BLACK}Uklanja sve objekte u vlasništvu preduzeća sa terena STR_QUERY_RESET_LANDSCAPE_CAPTION :{WHITE}Obnovi reljef -STR_RESET_LANDSCAPE_CONFIRMATION_TEXT :{WHITE}Da li stvarno želite da uklonite sve objekte u vlasništvu preduzeća? +STR_RESET_LANDSCAPE_CONFIRMATION_TEXT :{WHITE}Da li zaista želiš da ukloniš sve objekte u vlasništvu preduzeća? # Town generation window (SE) STR_FOUND_TOWN_CAPTION :{WHITE}Stvaranje naselja STR_FOUND_TOWN_NEW_TOWN_BUTTON :{BLACK}Novo naselje -STR_FOUND_TOWN_NEW_TOWN_TOOLTIP :{BLACK}Osnivanje novog naselja. Shift+Klik prikazuje samo procenu troškova +STR_FOUND_TOWN_NEW_TOWN_TOOLTIP :{BLACK}Osnivanje novog naselja. Shift+klik prikazuje samo procenu troškova STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Nasumično naselje STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Osnuj naselje na nasumičnoj lokaciji STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Mnogo nasumičnih naselja STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Popunjava teren sa nasumično raspoređenim naseljima +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Proširi sve gradove +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Mali rast svih gradova -STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Ime grada: -STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Unos imena grada -STR_FOUND_TOWN_NAME_EDITOR_HELP :{BLACK}Kliknite za unos imena naselja +STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Naziv naselja: +STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Unos naziva naselja +STR_FOUND_TOWN_NAME_EDITOR_HELP :{BLACK}Klikni za unos naziva naselja STR_FOUND_TOWN_NAME_RANDOM_BUTTON :{BLACK}Proizvoljno ime -STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP :{BLACK}Daje gradu proizvoljno ime +STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP :{BLACK}Daje naselju proizvoljan naziv STR_FOUND_TOWN_INITIAL_SIZE_TITLE :{YELLOW}Veličina naselja: STR_FOUND_TOWN_INITIAL_SIZE_SMALL_BUTTON :{BLACK}Malo @@ -3069,11 +3072,11 @@ STR_FOUND_TOWN_SELECT_LAYOUT_RANDOM :{BLACK}Slučaja # Fund new industry window STR_FUND_INDUSTRY_CAPTION :{WHITE}Finansiranje nove fabrike -STR_FUND_INDUSTRY_SELECTION_TOOLTIP :{BLACK}Izaberite odgovarajuću fabriku sa spiska -STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES :{BLACK}Izgradi proizvoljne industrije -STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP :{BLACK}Popunjava teren sa nasumično rasporđenim fabrikama -STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_CAPTION :{WHITE}Izgradi proizvoljne industrije -STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_QUERY :{YELLOW}Da li stvarno želite da izgradite mnogo proizvoljnih fabrika? +STR_FUND_INDUSTRY_SELECTION_TOOLTIP :{BLACK}Izaberi odgovarajuću fabriku sa spiska +STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES :{BLACK}Izgradi proizvoljne fabrike +STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP :{BLACK}Popunjava teren sa nasumično raspoređenim fabrikama +STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_CAPTION :{WHITE}Izgradi proizvoljne fabrike +STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_QUERY :{YELLOW}Da li zaista želiš da izgradiš mnogo proizvoljnih fabrika? STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST :{BLACK}Trošak: {YELLOW}{CURRENCY_LONG} STR_FUND_INDUSTRY_PROSPECT_NEW_INDUSTRY :{BLACK}Istraži STR_FUND_INDUSTRY_BUILD_NEW_INDUSTRY :{BLACK}Izgradi @@ -3081,31 +3084,31 @@ STR_FUND_INDUSTRY_FUND_NEW_INDUSTRY :{BLACK}Finansir STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES :{BLACK}Ukloni sve fabrike STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_TOOLTIP :{BLACK}Ukloni sve fabrike trenutno prisutne na mapi STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_CAPTION :{WHITE}Ukloni sve fabrike -STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_QUERY :{YELLOW}Da li stvarno želite da uklonite sve fabrike? +STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_QUERY :{YELLOW}Da li zaista želiš da ukloniš sve fabrike? # Industry cargoes window STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION :{WHITE}Lanac snabdevanja - {STRING} STR_INDUSTRY_CARGOES_CARGO_CAPTION :{WHITE}Lanac proizvodnje - {STRING} -STR_INDUSTRY_CARGOES_PRODUCERS :{WHITE}Snabdevačke industrije -STR_INDUSTRY_CARGOES_CUSTOMERS :{WHITE}Potrošačke industrije +STR_INDUSTRY_CARGOES_PRODUCERS :{WHITE}Snabdevači +STR_INDUSTRY_CARGOES_CUSTOMERS :{WHITE}Potrošači STR_INDUSTRY_CARGOES_HOUSES :{WHITE}Domaćinstva -STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP :{BLACK}Klikom na industriju prikazuju se njegovi snabdevači i potrošači -STR_INDUSTRY_CARGOES_CARGO_TOOLTIP :{BLACK}{STRING}{}Klikom na tovar prikazuju se njegovi snabdevači i potrošači +STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP :{BLACK}Klikom na fabriku prikazuju se njegovi snabdevači i potrošači +STR_INDUSTRY_CARGOES_CARGO_TOOLTIP :{BLACK}{STRING}{}Klikom na teret prikazuju se njegovi snabdevači i potrošači STR_INDUSTRY_DISPLAY_CHAIN :{BLACK}Lanac -STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP :{BLACK}Prikazuje lanac snabdevanja industrija +STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP :{BLACK}Prikazuje lanac snabdevanja fabrika STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP :{BLACK}Obeleži na karti -STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP :{BLACK}Obeležava prikazane industrije i na karti -STR_INDUSTRY_CARGOES_SELECT_CARGO :{BLACK}Odaberite tovar -STR_INDUSTRY_CARGOES_SELECT_CARGO_TOOLTIP :{BLACK} Odaberite teret koji želite da prikažete -STR_INDUSTRY_CARGOES_SELECT_INDUSTRY :{BLACK}Odaberite fabriku -STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP :{BLACK}Odaberite fabriku koju želite da prikažete +STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP :{BLACK}Obeležava prikazane fabrike i na karti +STR_INDUSTRY_CARGOES_SELECT_CARGO :{BLACK}Odaberi teret +STR_INDUSTRY_CARGOES_SELECT_CARGO_TOOLTIP :{BLACK}Odaberi teret za prikaz +STR_INDUSTRY_CARGOES_SELECT_INDUSTRY :{BLACK}Odaberi fabriku +STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP :{BLACK}Odaberi fabriku za prikaz # Land area window STR_LAND_AREA_INFORMATION_CAPTION :{WHITE}Prikaži podatke o zemljištu -STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju pločice. Ctrl+Klik otvara novi pogled na lokaciju pločice +STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju pločice. Ctrl+klik otvara novi pogled na lokaciju pločice STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A :{BLACK}Cena čišćenja: {LTBLUE}N/A STR_LAND_AREA_INFORMATION_COST_TO_CLEAR :{BLACK}Cena čišćenja: {RED}{CURRENCY_LONG} -STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}Dobit po uklanjanju: {LTBLUE}{CURRENCY_LONG} +STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}Zarada po uklanjanju: {LTBLUE}{CURRENCY_LONG} STR_LAND_AREA_INFORMATION_OWNER_N_A :N/A STR_LAND_AREA_INFORMATION_OWNER :{BLACK}Vlasnik: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_ROAD_OWNER :{BLACK}Vlasnik kolovoza: {LTBLUE}{STRING} @@ -3121,9 +3124,9 @@ STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Klasa ae STR_LAND_AREA_INFORMATION_AIRPORT_NAME :{BLACK}Naziv aerodroma: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Naziv dela aerodroma: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Tovar prihvaćen: {LTBLUE} +STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Teret prihvaćen: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) -STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Tip šine: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Vrsta šina: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Vrsta druma: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Vrsta tramvaja: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Najveća brzina na pruzi: {LTBLUE}{VELOCITY} @@ -3287,12 +3290,12 @@ STR_FRAMETIME_CAPTION_AI :VI {NUM} {STRIN # Save/load game/scenario STR_SAVELOAD_SAVE_CAPTION :{WHITE}Sačuvaj poziciju -STR_SAVELOAD_LOAD_CAPTION :{WHITE}Učitavanje Partije +STR_SAVELOAD_LOAD_CAPTION :{WHITE}Učitavanje igre STR_SAVELOAD_SAVE_SCENARIO :{WHITE}Sačuvaj scenario STR_SAVELOAD_LOAD_SCENARIO :{WHITE}Učitaj scenario -STR_SAVELOAD_LOAD_HEIGHTMAP :{WHITE}Učitavanje Elevacione karte +STR_SAVELOAD_LOAD_HEIGHTMAP :{WHITE}Učitavanje visinske karte STR_SAVELOAD_SAVE_HEIGHTMAP :{WHITE}Sačuvaj Elevacionu kartu -STR_SAVELOAD_HOME_BUTTON :{BLACK}Pritisnite ovde kako biste otišli u uobičajeni direktorijum za čuvanje pozicije +STR_SAVELOAD_HOME_BUTTON :{BLACK}Klikni ovde za preskakanje u uobičajeni direktorijum za čuvanje igre STR_SAVELOAD_BYTES_FREE :{BLACK}{BYTES} slobodno STR_SAVELOAD_LIST_TOOLTIP :{BLACK}Spisak diskova, direktorijuma i datoteka sa sačuvanim pozicijama STR_SAVELOAD_EDITBOX_TOOLTIP :{BLACK}Ime sačuvane pozicije @@ -3301,26 +3304,28 @@ STR_SAVELOAD_DELETE_TOOLTIP :{BLACK}Obriši STR_SAVELOAD_SAVE_BUTTON :{BLACK}Sačuvaj STR_SAVELOAD_SAVE_TOOLTIP :{BLACK}Sačuvaj tekuću igru, koristeći odabrano ime STR_SAVELOAD_LOAD_BUTTON :{BLACK}Učitaj -STR_SAVELOAD_LOAD_TOOLTIP :{BLACK}Učitava označenu partiju -STR_SAVELOAD_LOAD_HEIGHTMAP_TOOLTIP :{BLACK}Učitaj odabranu elevacionu kartu -STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalji partije +STR_SAVELOAD_LOAD_TOOLTIP :{BLACK}Učitava označenu igru +STR_SAVELOAD_LOAD_HEIGHTMAP_TOOLTIP :{BLACK}Učitaj odabranu visinsku kartu +STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalji igre STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Podaci ne postoje STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Tekst za filtriranje: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Tekst za pretragu: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Prepisivanje datoteke -STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Da li ste sigurni da želite da prepišete postojeću datoteku? +STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Da li zaista želiš da prepišeš postojeću datoteku? STR_SAVELOAD_DIRECTORY :{STRING} (Direktorijum) STR_SAVELOAD_PARENT_DIRECTORY :{STRING} (Nadređeni direktorijum) -STR_SAVELOAD_OSKTITLE :{BLACK}Unesite naziv sačuvane partije +STR_SAVELOAD_OSKTITLE :{BLACK}Unesi naziv sačuvane igre # World generation STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}Stvaranje sveta STR_MAPGEN_MAPSIZE :{BLACK}Veličina terena: -STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Izaberite veličinu mape u pločicama. Broj dostupnih pločica će biti neznatno manji +STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Izaberi veličinu mape u pločicama. Broj dostupnih pločica će biti neznatno manji STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Broj naselja: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Imena naselja: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Izaberi stil imena naselja STR_MAPGEN_DATE :{BLACK}Datum: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Broj fabrika: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Najviši vrh: @@ -3334,13 +3339,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Pokriven STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Povećaj pokrivenost pustinjom za deset procenata STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Smanji pokrivenost pustinjom za deset procenata STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Oblikovanje reljefa: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Vrsta terena: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Nivo mora: +STR_MAPGEN_SEA_LEVEL :{BLACK}Nivo mora: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Broj reka: STR_MAPGEN_SMOOTHNESS :{BLACK}Postepenost: STR_MAPGEN_VARIETY :{BLACK}Raznolikost: STR_MAPGEN_GENERATE :{WHITE}Napravi +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Podešavanja NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Prikazuje podešavanja NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Podešavanja VI +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Prikazuje podešavanja VI +STR_MAPGEN_GS_SETTINGS :{BLACK}Podešavanja skripte +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Prikazuje podešavanja skripte + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Engleska (Originalna) +STR_MAPGEN_TOWN_NAME_FRENCH :Francuska +STR_MAPGEN_TOWN_NAME_GERMAN :Nemačka +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Engleska (Dodatna) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latinoamerička +STR_MAPGEN_TOWN_NAME_SILLY :Šašava +STR_MAPGEN_TOWN_NAME_SWEDISH :Švedska +STR_MAPGEN_TOWN_NAME_DUTCH :Holandska +STR_MAPGEN_TOWN_NAME_FINNISH :Finska +STR_MAPGEN_TOWN_NAME_POLISH :Poljska +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovačka +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norveška +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Mađarska +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austrijanska +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumunska +STR_MAPGEN_TOWN_NAME_CZECH :Češka +STR_MAPGEN_TOWN_NAME_SWISS :Švajcarska +STR_MAPGEN_TOWN_NAME_DANISH :Danska +STR_MAPGEN_TOWN_NAME_TURKISH :Turska +STR_MAPGEN_TOWN_NAME_ITALIAN :Italijanska +STR_MAPGEN_TOWN_NAME_CATALAN :Katalonska # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Ivice terena: @@ -3379,8 +3412,8 @@ STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Promena # Map generation progress STR_GENERATION_WORLD :{WHITE}Stvaranje Sveta... STR_GENERATION_ABORT :{BLACK}Prekini -STR_GENERATION_ABORT_CAPTION :{WHITE}Prekid Stvaranja Sveta -STR_GENERATION_ABORT_MESSAGE :{YELLOW}Da li stvarno želite da prekinete stvaranje? +STR_GENERATION_ABORT_CAPTION :{WHITE}Prekid stvaranja sveta +STR_GENERATION_ABORT_MESSAGE :{YELLOW}Da li zaista želiš da prekineš stvaranje? STR_GENERATION_PROGRESS :{WHITE}{NUM}% završeno STR_GENERATION_PROGRESS_NUM :{BLACK}{NUM} / {NUM} STR_GENERATION_WORLD_GENERATION :{BLACK}Stvaranje sveta @@ -3388,27 +3421,27 @@ STR_GENERATION_RIVER_GENERATION :{BLACK}Određiv STR_GENERATION_TREE_GENERATION :{BLACK}Postavljanje drveća STR_GENERATION_OBJECT_GENERATION :{BLACK}Postavljenje nepomičnih objekata STR_GENERATION_CLEARING_TILES :{BLACK}Dodavanje grubih i stenovitih područja -STR_GENERATION_SETTINGUP_GAME :{BLACK}Podešavanje partije +STR_GENERATION_SETTINGUP_GAME :{BLACK}Podešavanje igre STR_GENERATION_PREPARING_TILELOOP :{BLACK}Razrađivanje pločica STR_GENERATION_PREPARING_SCRIPT :{BLACK}Pokretanje skripte -STR_GENERATION_PREPARING_GAME :{BLACK}Pripremanje partije +STR_GENERATION_PREPARING_GAME :{BLACK}Pripremanje igre # NewGRF settings -STR_NEWGRF_SETTINGS_CAPTION :{WHITE}NewGRF podešavanja +STR_NEWGRF_SETTINGS_CAPTION :{WHITE}Podešavanja NewGRF STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Detaljni NewGRF podaci STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Aktivne NewGRF datoteke STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Neaktivne NewGRF datoteke STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Odabir postavke: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter niska: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Tekst pretrage: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Učitava označenu postavku STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Sačuvaj postavku -STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Sačuvajte trenutni spisak u postavku -STR_NEWGRF_SETTINGS_PRESET_DELETE :{BLACK}Izbriši postavku -STR_NEWGRF_SETTINGS_PRESET_DELETE_TOOLTIP :{BLACK}Izbrišite trenutno označenu postavku +STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Sačuvaj trenutni spisak u postavku +STR_NEWGRF_SETTINGS_PRESET_DELETE :{BLACK}Obriši postavku +STR_NEWGRF_SETTINGS_PRESET_DELETE_TOOLTIP :{BLACK}Obriši trenutno označenu postavku STR_NEWGRF_SETTINGS_ADD :{BLACK}Dodaj -STR_NEWGRF_SETTINGS_ADD_FILE_TOOLTIP :{BLACK}Dodajte odabranu NewGRF datoteku na vaš listu -STR_NEWGRF_SETTINGS_RESCAN_FILES :{BLACK}Osveži izbor -STR_NEWGRF_SETTINGS_RESCAN_FILES_TOOLTIP :{BLACK}Osvežite izbor dostupnih NewGRF datoteka +STR_NEWGRF_SETTINGS_ADD_FILE_TOOLTIP :{BLACK}Dodaj odabranu NewGRF datoteku u svoju konfiguraciju +STR_NEWGRF_SETTINGS_RESCAN_FILES :{BLACK}Osveži spisak datoteka +STR_NEWGRF_SETTINGS_RESCAN_FILES_TOOLTIP :{BLACK}Osveži spisak dostupnih NewGRF datoteka STR_NEWGRF_SETTINGS_REMOVE :{BLACK}Ukloni STR_NEWGRF_SETTINGS_REMOVE_TOOLTIP :{BLACK}Uklanja označenu NewGRF datoteku sa spiska STR_NEWGRF_SETTINGS_MOVEUP :{BLACK}Naviše @@ -3416,17 +3449,17 @@ STR_NEWGRF_SETTINGS_MOVEUP_TOOLTIP :{BLACK}Pomera o STR_NEWGRF_SETTINGS_MOVEDOWN :{BLACK}Naniže STR_NEWGRF_SETTINGS_MOVEDOWN_TOOLTIP :{BLACK}Pomera označenu NewGRF datoteku niže na spisku STR_NEWGRF_SETTINGS_UPGRADE :{BLACK}Ažuriraj -STR_NEWGRF_SETTINGS_UPGRADE_TOOLTIP :{BLACK}Nadogradite NewGRF datoteke za koje već imate instalirane novije verzije +STR_NEWGRF_SETTINGS_UPGRADE_TOOLTIP :{BLACK}Nadogradi NewGRF datoteke za koje već imaš instalirane novije verzije STR_NEWGRF_SETTINGS_FILE_TOOLTIP :{BLACK}Spisak instaliranih NewGRF datoteka. STR_NEWGRF_SETTINGS_SET_PARAMETERS :{BLACK}Postavi parametre STR_NEWGRF_SETTINGS_SHOW_PARAMETERS :{BLACK}Prikaži parametre STR_NEWGRF_SETTINGS_TOGGLE_PALETTE :{BLACK}Promeni paletu -STR_NEWGRF_SETTINGS_TOGGLE_PALETTE_TOOLTIP :{BLACK}Menja paletu označenog NewGRF-a.{}Promenite paletu ako grafici iz NewGRF-a su ružičasti tokom igre +STR_NEWGRF_SETTINGS_TOGGLE_PALETTE_TOOLTIP :{BLACK}Menja paletu označenog NewGRF-a.{}Promeni paletu ako su grafike iz NewGRF-a ružičaste tokom igre STR_NEWGRF_SETTINGS_APPLY_CHANGES :{BLACK}Primeni promene STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_BUTTON :{BLACK}Traži nedostajući dodatak -STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_TOOLTIP :{BLACK}Proverite da li se nedostajući dodaci mogu naći na mreži +STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_TOOLTIP :{BLACK}Proveri da li se nedostajući dodaci mogu naći na mreži STR_NEWGRF_SETTINGS_FILENAME :{BLACK}Datoteka: {SILVER}{STRING} STR_NEWGRF_SETTINGS_GRF_ID :{BLACK}GRF ID: {SILVER}{STRING} @@ -3447,9 +3480,9 @@ STR_NEWGRF_SETTINGS_DISABLED :{RED}Isključen STR_NEWGRF_SETTINGS_INCOMPATIBLE :{RED}Nije kompatibilno sa ovom OpenTTD verzijom # NewGRF save preset window -STR_SAVE_PRESET_CAPTION :{WHITE} Sačuvajte postavku -STR_SAVE_PRESET_LIST_TOOLTIP :{BLACK}Lista dostupnih postavki, odaberite jednu za kopiranje pod imenom ispod -STR_SAVE_PRESET_TITLE :{BLACK} Unesite ime postavke +STR_SAVE_PRESET_CAPTION :{WHITE}Sačuvaj postavku +STR_SAVE_PRESET_LIST_TOOLTIP :{BLACK}Lista dostupnih postavki, odaberi jednu za kopiranje pod imenom ispod +STR_SAVE_PRESET_TITLE :{BLACK}Unesi ime postavke STR_SAVE_PRESET_EDITBOX_TOOLTIP :{BLACK}Trenutno izabrani naziv za snimanje početnih postavki STR_SAVE_PRESET_CANCEL :{BLACK}Otkaži STR_SAVE_PRESET_CANCEL_TOOLTIP :{BLACK}Ne manjati odabrane postavke @@ -3485,7 +3518,14 @@ STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK}Ide na d STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Prethodni sprajt STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Vraća se na prethodni normalan sprajt, preskačući sve pseudo/prebojavajuće/font sprajtove i prelazi na kraj posle početnog STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Prikaz trenutno odabranog sprajta. Poravnanje se ignoriše tokom iscrtavanja ovog sprajta -STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Premeštanje sprajta po kordinatama, menjanjem X i Y pomeraja. Ctrl+Klik za pomeranje sprajta osam jedinica odjednom +STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Premeštanje sprajta po kordinatama, menjanjem X i Y pomeraja. Ctrl+klik pomera sprajt osam jedinica odjednom + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Centrirano sa pomakom +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Centriran sprajt + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Nišan + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Poništi relativne STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Poništi trenutne relativne pomake STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X pomak: {NUM}, Y pomak: {NUM} (Apsolutni) @@ -3500,18 +3540,16 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Upozorenje: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Greška: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Kobno: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Došlo je do neotklonljive NewGRF greške:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Dogodila se greška kod NewGRF-a:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} neće raditi sa TTDPatch verzijom prema prijavi OpenTTD-a -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} je za {STRING} verziju TTD-a -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} je napravljen za korišćenje sa {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Neispravan parametar za {1:STRING}: parametar {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} mora biti učitan pre {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} mora biti učitan posle {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} zahteva {STRING} ili višu verziju OpenTTD-a +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} je za {2:STRING} verziju TTD-a +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} je napravljen za korišćenje sa {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Neispravan parametar za {1:STRING}: parametar {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} mora biti učitan pre {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} mora biti učitan posle {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} zahteva verziju OpenTTD-a {2:STRING} ili višu STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF datoteka nije prilagođena za prevod STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Previše učitanih NewGRF-ova -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Učitavanje {1:STRING} kao statične NewGRF sa {STRING} može da izazove desinhronizacije +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Učitavanje {1:STRING} kao statične NewGRF sa {2:STRING} može da izazove desinhronizacije STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Neočekivani sprajt (sprajt {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Nepoznato svojstvo Akcije 0 {4:HEX} (sprajt {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Pokušaj korišćenja neispravnog ID-ja (sprajt {3:NUM}) @@ -3526,7 +3564,7 @@ STR_NEWGRF_ERROR_INDPROD_CALLBACK :Neipravan povra # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Oprez! -STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Upravo ćete načiniti izmene na tekućoj partiji. To može srušiti OpenTTD ili narušiti stanje partije. Oko ovog problema nemojte prijavljivati greške.{}Da li ste apsolutno sigurni da ovo želite? +STR_NEWGRF_CONFIRMATION_TEXT :{YELLOW}Upravo vršiš izmene na tekućoj igri. To može prekinuti OpenTTD ili narušiti stanje igre. Ove probleme nije potrebno prijaviti kao greške u igri.{}Da li zaista želiš da nastaviš? STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Nemoguće dodati: duplicirani GRF ID STR_NEWGRF_COMPATIBLE_LOADED :{ORANGE}Odabrana datoteka nije nađena (kompatibilan GRF učitan) @@ -3535,7 +3573,7 @@ STR_NEWGRF_TOO_MANY_NEWGRFS :{WHITE}Ne mogu STR_NEWGRF_COMPATIBLE_LOAD_WARNING :{WHITE}Kompatibilni GRF(ovi) učitani umesto nepronađenih datoteka STR_NEWGRF_DISABLED_WARNING :{WHITE}Nepronađene GRF datoteke su isključene STR_NEWGRF_UNPAUSE_WARNING_TITLE :{YELLOW}Nepronađene GRF datoteke -STR_NEWGRF_UNPAUSE_WARNING :{WHITE}Nastavljenje može da krahira OpenTTD. Nemojte čuvati izveštaje o ovom mogućem krahu.{}Da li stvarno želite da nastavite? +STR_NEWGRF_UNPAUSE_WARNING :{WHITE}Nastavljanje igre može da poremeti rad OpenTTD. Nemoj čuvati izveštaj o ovom mogućem prekidu igre.{}Da li zaista želiš da nastaviš? # NewGRF status STR_NEWGRF_LIST_NONE :Nema @@ -3548,21 +3586,21 @@ STR_NEWGRF_LIST_MISSING :{RED}Nedostaju STR_NEWGRF_BROKEN :{WHITE}NewGRF '{0:STRING}' može izazvati desinhronizacije i/ili krahove STR_NEWGRF_BROKEN_POWERED_WAGON :{WHITE}Vagon '{1:ENGINE}' je promenio motorno stanje izvan depoa STR_NEWGRF_BROKEN_VEHICLE_LENGTH :{WHITE}Promenio je dužinu vozila '{1:ENGINE}' dok je izvan depoa -STR_NEWGRF_BROKEN_CAPACITY :{WHITE}Promenio je kapacitet vozila '{1:ENGINE}' dok je izvan depoa ili u remontu +STR_NEWGRF_BROKEN_CAPACITY :{WHITE}Promenio je nosivost vozila '{1:ENGINE}' dok je izvan depoa ili u remontu STR_BROKEN_VEHICLE_LENGTH :{WHITE}Voz '{VEHICLE}' preduzeća '{COMPANY}' je neispravne dužine. Verovatno je izazvana nekim problemima sa NewGRF(ovima). Igra može da krahira ili da se desinhronizuje STR_NEWGRF_BUGGY :{WHITE}NewGRF '{0:STRING}' sadrži neispravne podatke -STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Podaci o tovaru/prenameni za '{1:ENGINE}' se posle izgradnje razlikuju od nabavne liste. Ovo može izazvati neispravnu automatsku zamenu/preuređenje +STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Podaci o teretu/prenameni za '{1:ENGINE}' se posle izgradnje razlikuju od nabavne liste. Ovo može izazvati neispravnu automatsku zamenu/preuređenje STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' je izazvao beskrajnu petlju tokom povratnog poziva proizvodnje STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Povratni poziv {1:HEX} vratio je nepoznatu/neispravnu vrednost {2:HEX} STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' je vratio neispravan tip tereta u povratnom pozivu jid {2:HEX} # 'User removed essential NewGRFs'-placeholders for stuff without specs -STR_NEWGRF_INVALID_CARGO : +STR_NEWGRF_INVALID_CARGO : STR_NEWGRF_INVALID_CARGO_ABBREV :?? -STR_NEWGRF_INVALID_CARGO_QUANTITY :{COMMA} +STR_NEWGRF_INVALID_CARGO_QUANTITY :{COMMA} STR_NEWGRF_INVALID_ENGINE : -STR_NEWGRF_INVALID_INDUSTRYTYPE : +STR_NEWGRF_INVALID_INDUSTRYTYPE : # Placeholders for other invalid stuff, e.g. vehicles that have gone (Game Script). STR_INVALID_VEHICLE : @@ -3591,7 +3629,7 @@ STR_TOWN_DIRECTORY_CAPTION :{WHITE}Naselja STR_TOWN_DIRECTORY_NONE :{ORANGE}- Prazno - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (City){BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Imena naselja - klikom na ime se centrira glavni pogled na to naselje. Ctrl+Klik otvara novi pogled na lokaciju naselja +STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Imena naselja - klikom na naziv glavni pogled se premešta na to naselje. Ctrl+klik otvara novi pogled na lokaciju naselja STR_TOWN_POPULATION :{BLACK}Svetska populacija: {COMMA} # Town view window @@ -3599,7 +3637,7 @@ STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Grad) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Populacija: {ORANGE}{COMMA}{BLACK} Zgrada: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} u poslednjem mesecu: {ORANGE}{COMMA}{BLACK} max: {ORANGE}{COMMA} -STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Tovar potreban za razvoj naselja: +STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Teret potreban za razvoj naselja: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} potrebno STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} potrebno zimi STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED_GENERAL :{ORANGE}{STRING}{GREEN} dostavljeno @@ -3609,7 +3647,7 @@ STR_TOWN_VIEW_TOWN_GROWS_EVERY :{BLACK}Naselje STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}Naselje se razvija u periodu od {ORANGE}{COMMA}{BLACK} dan{P a a a} (sponzorisano) STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}Naselje se {RED}ne{BLACK} razvija STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}Nivo buke u naselju: {ORANGE}{COMMA}{BLACK} najviše: {ORANGE}{COMMA} -STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Pozicionira glavni pogled na lokaciju naselja. Ctrl+Klik otvara novi pogled na lokaciju naselja +STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju naselja. Ctrl+klik otvara novi pogled na lokaciju naselja STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON :{BLACK}Lokalna vlast STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP :{BLACK}Prikaži podatke o lokalnoj vlasti STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Promeni ime naselja @@ -3643,14 +3681,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Kupovina eksklu STR_LOCAL_AUTHORITY_ACTION_BRIBE :Podmićivanje lokalne vlasti ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Ulaganje u malu reklamnu kampanju će doneti preduzeću više putnika i robe iz ovog naselja.{}Privremeno povećava rejting stanica u malom prečniku oko centra grada tokom trajanja kampanje.{}Trošak: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Ulaganje u reklamnu kampanju srednje veličine će doneti preduzeću više putnika i robe iz ovog naselja.{}Privremeno povećava rejting stanica u prečniku srednje veličine oko centra grada tokom trajanja kampanje.{}Trošak: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Ulaganje u veliku reklamnu kampanju će doneti preduzeću više putnika i robe iz ovog naselja.{}Privremeno povećava rejting stanica u velikom prečniku oko centra grada tokom trajanja kampanje.{}Trošak: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Finansiranje rekonstrukcije lokalne mreže puteva.{}Može prouzrokovati kolaps u drumskom saobraćaju u trajanju do 6 meseci.{}Trošak: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Otkrivanje spomenika preduzeća.{}Trajno povećava rejting stanica u gradu tokom trajanja kampanje.{}Trošak: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW} Finansiranje izgradnje novih objekata u naselju.{}Privremeno povećava brzinu rasta grada u ovom gradu.{}Trošak: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Kupovina ekskluzivnih prava prevoza od lokalne vlasti na godinu dana.{}Grad osigurava da će lokalni korisnici prevoza koristiti isključivo usluge vašeg preduzeća.{}Trošak: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Davanje mita lokalnoj vlasti kako bi porastao rejting vašeg preduzeća, uz rizik velike štete ukoliko se otkrije.{} Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Ulaganje u malu reklamnu kampanju će doneti preduzeću više putnika i robe iz ovog naselja.{}Privremeno povećava ocenu stanica u malom prečniku oko centra naselja tokom trajanja kampanje.{}{POP_COLOUR}Trošak: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Ulaganje u reklamnu kampanju srednje veličine će doneti preduzeću više putnika i robe iz ovog naselja.{}Privremeno povećava ocenu stanica u prečniku srednje veličine oko centra naselja tokom trajanja kampanje.{}{POP_COLOUR}Trošak: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Ulaganje u veliku reklamnu kampanju će doneti preduzeću više putnika i robe iz ovog naselja.{}Privremeno povećava ocenu stanica u velikom prečniku oko centra naselja tokom trajanja kampanje.{}{POP_COLOUR}Trošak: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Finansiranje rekonstrukcije lokalne mreže puteva.{}Može prouzrokovati kolaps u drumskom saobraćaju u trajanju do 6 meseci.{}{POP_COLOUR}Trošak: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Otkrivanje spomenika preduzeća.{}Trajno povećava ocenu stanica u naselju tokom trajanja kampanje.{}{POP_COLOUR}Trošak: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW} Finansiranje izgradnje novih objekata u naselju.{}Privremeno povećava brzinu rasta u ovom naselju.{}{POP_COLOUR}Trošak: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Kupovina ekskluzivnih prava prevoza od lokalne vlasti na godinu dana.{}Lokalna vlast osigurava da će lokalni korisnici prevoza koristiti isključivo usluge vašeg preduzeća.{}{POP_COLOUR}Trošak: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Davanje mita lokalnoj vlasti kako bi porasla ocena vašeg preduzeća, uz rizik velike štete ukoliko se otkrije.{}{POP_COLOUR}Trošak: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Ciljevi @@ -3658,13 +3696,13 @@ STR_GOALS_SPECTATOR_CAPTION :{WHITE}Opšti c STR_GOALS_SPECTATOR :Opšti ciljevi STR_GOALS_GLOBAL_BUTTON :{BLACK}Opšte STR_GOALS_GLOBAL_BUTTON_HELPTEXT :{BLACK}Prikaži opšte ciljeve -STR_GOALS_COMPANY_BUTTON :{BLACK}Kompanija -STR_GOALS_COMPANY_BUTTON_HELPTEXT :{BLACK}Prikaži ciljeve kompanije +STR_GOALS_COMPANY_BUTTON :{BLACK}Preduzeće +STR_GOALS_COMPANY_BUTTON_HELPTEXT :{BLACK}Prikaži ciljeve preduzeća STR_GOALS_TEXT :{ORANGE}{STRING} STR_GOALS_NONE :{ORANGE}- Nema - STR_GOALS_PROGRESS :{ORANGE}{STRING} STR_GOALS_PROGRESS_COMPLETE :{GREEN}{STRING} -STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klikom na cilj premešta se glavni pogled na fabriku/naselje/pločicu. Ctrl+Kilk otvara novi pogled na lokaciju fabrike/naselja/pločice +STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klikom na cilj premešta se glavni pogled na fabriku/naselje/pločicu. Ctrl+klik otvara novi pogled na lokaciju fabrike/naselja/pločice # Goal question window STR_GOAL_QUESTION_CAPTION_QUESTION :{BLACK}Pitanje @@ -3695,12 +3733,12 @@ STR_GOAL_QUESTION_BUTTON_CLOSE :Zatvori # Subsidies window STR_SUBSIDIES_CAPTION :{WHITE}Subvencije -STR_SUBSIDIES_OFFERED_TITLE :{BLACK}Subvencije u toku (u vezi preuzimanja navedenog tovara): +STR_SUBSIDIES_OFFERED_TITLE :{BLACK}Subvencije u toku (u vezi preuzimanja navedenog tereta): STR_SUBSIDIES_OFFERED_FROM_TO :{ORANGE}{STRING.big} od {STRING} do {STRING}{YELLOW} (pre {DATE_SHORT}) STR_SUBSIDIES_NONE :{ORANGE}- Prazno - STR_SUBSIDIES_SUBSIDISED_TITLE :{BLACK}Odobrene subvencije: STR_SUBSIDIES_SUBSIDISED_FROM_TO :{ORANGE}{STRING} između stanica {STRING} i {STRING}{YELLOW} ({COMPANY}{YELLOW}, do {DATE_SHORT}) -STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klikom na uslugu prebacuje glavni pogled na lokaciju fabrike/naselja. Ctrl+Klik otvara novi pogled na to mesto +STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klikom na uslugu prebacuje glavni pogled na lokaciju fabrike/naselja. Ctrl+klik otvara novi pogled na to mesto # Story book window STR_STORY_BOOK_CAPTION :{WHITE}Priča {COMPANY} @@ -3708,7 +3746,7 @@ STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}Globalna STR_STORY_BOOK_SPECTATOR :Svetska priča STR_STORY_BOOK_TITLE :{YELLOW}{STRING} STR_STORY_BOOK_GENERIC_PAGE_ITEM :Stranica {NUM} -STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}Idi do željene stranice uz izbor te stranice u ovoj listi. +STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}Skoči do željene stranice odabirom te stranice u ovom spisku. STR_STORY_BOOK_PREV_PAGE :{BLACK}Prethodni STR_STORY_BOOK_PREV_PAGE_TOOLTIP :{BLACK}Idi do prethodne stranice STR_STORY_BOOK_NEXT_PAGE :{BLACK}Sledeće @@ -3716,15 +3754,15 @@ STR_STORY_BOOK_NEXT_PAGE_TOOLTIP :{BLACK}Idi do s STR_STORY_BOOK_INVALID_GOAL_REF :{RED}Nevažeća referenca cilja # Station list window -STR_STATION_LIST_TOOLTIP :{BLACK}Imena stanica - klikom na ime se centrira glavni pogled na stanicu. Ctrl+Klik otvara novi pogled na lokaciju stanice +STR_STATION_LIST_TOOLTIP :{BLACK}Nazivi stanica - klikom na naziv glavni pogled se premešta na tu stanicu. Ctrl+klik otvara novi pogled na lokaciju stanice STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE :{BLACK}Držanjem Ctrl moguće je označiti više od jedne stavke STR_STATION_LIST_CAPTION :{WHITE}{COMPANY} - {COMMA} Stanic{P a e a} STR_STATION_LIST_STATION :{YELLOW}{STATION} {STATION_FEATURES} STR_STATION_LIST_WAYPOINT :{YELLOW}{WAYPOINT} STR_STATION_LIST_NONE :{YELLOW}- Prazno - STR_STATION_LIST_SELECT_ALL_FACILITIES :{BLACK}Odaberi sve objekte -STR_STATION_LIST_SELECT_ALL_TYPES :{BLACK}Odaberi sve vrste tovara (uključujući i one bez tovara) -STR_STATION_LIST_NO_WAITING_CARGO :{BLACK}Ni jedna vrsta tovara nije na čekanju +STR_STATION_LIST_SELECT_ALL_TYPES :{BLACK}Odaberi sve vrste tereta (uključujući i one bez tereta) +STR_STATION_LIST_NO_WAITING_CARGO :{BLACK}Nema tereta bilo koje vrste na čekanju # Station view window STR_STATION_VIEW_CAPTION :{WHITE}{STATION} {STATION_FEATURES} @@ -3732,11 +3770,11 @@ STR_STATION_VIEW_WAITING_CARGO :{WHITE}{CARGO_L STR_STATION_VIEW_RESERVED :{YELLOW}({CARGO_SHORT} rezervisan za utovar) STR_STATION_VIEW_ACCEPTS_BUTTON :{BLACK}Prihvata -STR_STATION_VIEW_ACCEPTS_TOOLTIP :{BLACK}Prikaži spisak tovara koje stanica prihvata +STR_STATION_VIEW_ACCEPTS_TOOLTIP :{BLACK}Prikaži spisak tereta koje stanica prihvata STR_STATION_VIEW_ACCEPTS_CARGO :{BLACK}Prihvata: {WHITE}{CARGO_LIST} -STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF :{BLACK}Ova stanica ima ekskluzivna transportna prava u ovom gradu. -STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY :{YELLOW}{COMPANY}{BLACK} je kupio ekskluzivna prava prevoza u ovom gradu. +STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF :{BLACK}Ova stanica ima ekskluzivna prava za prevoz u ovom naselju. +STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY :{YELLOW}{COMPANY}{BLACK} je kupio ekskluzivna prava za prevoz u ovom naselju. STR_STATION_VIEW_RATINGS_BUTTON :{BLACK}Ocene STR_STATION_VIEW_RATINGS_TOOLTIP :{BLACK}Prikaži ocene stanice @@ -3746,8 +3784,8 @@ STR_STATION_VIEW_CARGO_SUPPLY_RATING :{WHITE}{STRING} STR_STATION_VIEW_GROUP :{BLACK}Sortiraj po STR_STATION_VIEW_WAITING_STATION :Stanica: Čekajuća STR_STATION_VIEW_WAITING_AMOUNT :Količina: Čekajuća -STR_STATION_VIEW_PLANNED_STATION :Stanica: Planirana -STR_STATION_VIEW_PLANNED_AMOUNT :Količina: Planirana +STR_STATION_VIEW_PLANNED_STATION :Stanica: planirana +STR_STATION_VIEW_PLANNED_AMOUNT :Količina: planirana STR_STATION_VIEW_FROM :{YELLOW}{CARGO_SHORT} od {STATION} STR_STATION_VIEW_VIA :{YELLOW}{CARGO_SHORT} preko {STATION} STR_STATION_VIEW_TO :{YELLOW}{CARGO_SHORT} do {STATION} @@ -3776,12 +3814,12 @@ STR_CARGO_RATING_VERY_GOOD :veoma dobro STR_CARGO_RATING_EXCELLENT :odlično STR_CARGO_RATING_OUTSTANDING :izvanredno -STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}Centrira glavni pogled na lokaciju stanice. Ctrl+Klik otvara novi pogled na lokaciju stanice +STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju stanice. Ctrl+klik otvara novi pogled na lokaciju stanice STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}Preimenuj stanicu STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}Prikazuje sve vozove koji imaju ovu stanicu u svom voznom redu -STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP :{BLACK}Prikazuje sva drumka vozila koja imaju ovu stanicu u svom voznom redu -STR_STATION_VIEW_SCHEDULED_AIRCRAFT_TOOLTIP :{BLACK}Prikazuje sve letilice koje imaju ovu stanicu u svom voznom redu +STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP :{BLACK}Prikazuje sva drumska vozila koja imaju ovu stanicu u svom voznom redu +STR_STATION_VIEW_SCHEDULED_AIRCRAFT_TOOLTIP :{BLACK}Prikazuje sve letelice koje imaju ovu stanicu u svom voznom redu STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP :{BLACK}Prikazuje sve brodove koji imaju ovu stanicu u svom voznom redu STR_STATION_VIEW_RENAME_STATION_CAPTION :Preimenuj stanicu @@ -3791,7 +3829,7 @@ STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}Spreči # Waypoint/buoy view window STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT} -STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju čvorišta. Ctrl+Klik otvara novi pogled na čvorište +STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju čvorišta. Ctrl+klik otvara novi pogled na čvorište STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}Promena naziva putanje STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju bove. Ctrl+klik otvara novi pogled na bovu STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}Promeni naziv bove @@ -3803,28 +3841,42 @@ STR_FINANCES_CAPTION :{WHITE}{COMPANY STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}Zarada +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Operativni troškovi +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Kapitalni troškovi ###length 13 STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Izgradnja STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Nova vozila -STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Vozovi - Rashod -STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Drumska vozila - Rashod -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Letelice - Rashod -STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Brodovi - Rashod +STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Vozovi +STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Drumska vozila +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Letelica +STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Brodovi +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Infrastruktura +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Vozovi +STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}Drumska vozila +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Letelica +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Brodovi STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Kamata na zajam STR_FINANCES_SECTION_OTHER :{GOLD}Ostalo -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} -STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_TOTAL_CAPTION :{WHITE}Ukupno +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} +STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Zarada STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Stanje na računu +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Sopstvena sredstva STR_FINANCES_LOAN_TITLE :{WHITE}Zajam +STR_FINANCES_INTEREST_RATE :{WHITE}Kamata na zajam: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Najviša Pozajmica: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Pozajmi {CURRENCY_LONG} -STR_FINANCES_BORROW_TOOLTIP :{BLACK}Uvećanje količine zajma. Sa Ctrl+Klik se pozajmljuje najviši mogući iznos +STR_FINANCES_BORROW_TOOLTIP :{BLACK}Uvećanje količine zajma. Ctrl+klik pozajmljuje najviši mogući iznos STR_FINANCES_REPAY_BUTTON :{BLACK}Vrati {CURRENCY_LONG} -STR_FINANCES_REPAY_TOOLTIP :{BLACK}Otplati deo duga. Sa Ctrl+Klik se otplaćuje največi mogući iznos duga +STR_FINANCES_REPAY_TOOLTIP :{BLACK}Otplati deo duga. Ctrl+klik otplaćuje največi mogući iznos duga STR_FINANCES_INFRASTRUCTURE_BUTTON :{BLACK}Infrastruktura # Company view @@ -3836,7 +3888,7 @@ STR_COMPANY_VIEW_COLOUR_SCHEME_TITLE :{GOLD}Šema boj STR_COMPANY_VIEW_VEHICLES_TITLE :{GOLD}Vozila: STR_COMPANY_VIEW_TRAINS :{WHITE}{COMMA} voz{P "" a ova} STR_COMPANY_VIEW_ROAD_VEHICLES :{WHITE}{COMMA} drumsk{P o a ih} vozil{P o a a} -STR_COMPANY_VIEW_AIRCRAFT :{WHITE}{COMMA} letilic{P a e a} +STR_COMPANY_VIEW_AIRCRAFT :{WHITE}{COMMA} letelic{P a e a} STR_COMPANY_VIEW_SHIPS :{WHITE}{COMMA} brod{P "" a ova} STR_COMPANY_VIEW_VEHICLES_NONE :{WHITE}Nema STR_COMPANY_VIEW_COMPANY_VALUE :{GOLD}Vrednost preduzeća: {WHITE}{CURRENCY_LONG} @@ -3854,18 +3906,18 @@ STR_COMPANY_VIEW_BUILD_HQ_TOOLTIP :{BLACK}Izgrađu STR_COMPANY_VIEW_VIEW_HQ_BUTTON :{BLACK}Prikaži upravnu zgradu STR_COMPANY_VIEW_VIEW_HQ_TOOLTIP :{BLACK}Prebacuje pogled na upravnu zgradu preduzeća STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}Preseli upravnu zgradu -STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Premešta sedište preduzeća na drugu lokaciju za cenu od 1% vrednosti preduzeća. Shift+Klik prikazuje procenu troškova bez premeštanja zgrade +STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Premešta sedište preduzeća na drugu lokaciju za cenu od 1% vrednosti preduzeća. Shift+klik prikazuje procenu troškova bez premeštanja zgrade STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}Detalji STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}Detaljni pregled računa za infrastrukturu STR_COMPANY_VIEW_GIVE_MONEY_BUTTON :{BLACK}Daj novac -STR_COMPANY_VIEW_GIVE_MONEY_TOOLTIP :{BLACK}Daj novac ovoj kompaniji +STR_COMPANY_VIEW_GIVE_MONEY_TOOLTIP :{BLACK}Daj novac ovom preduzeću STR_COMPANY_VIEW_NEW_FACE_BUTTON :{BLACK}Novo lice -STR_COMPANY_VIEW_NEW_FACE_TOOLTIP :{BLACK}Izbor novog lica za vlasnika +STR_COMPANY_VIEW_NEW_FACE_TOOLTIP :{BLACK}Odabir novog lica za vlasnika STR_COMPANY_VIEW_COLOUR_SCHEME_BUTTON :{BLACK}Šema boja STR_COMPANY_VIEW_COLOUR_SCHEME_TOOLTIP :{BLACK}Promena izgleda vozila preduzeća -STR_COMPANY_VIEW_COMPANY_NAME_BUTTON :{BLACK}Ime preduzeća -STR_COMPANY_VIEW_COMPANY_NAME_TOOLTIP :{BLACK}Promena imena preduzeća +STR_COMPANY_VIEW_COMPANY_NAME_BUTTON :{BLACK}Naziv preduzeća +STR_COMPANY_VIEW_COMPANY_NAME_TOOLTIP :{BLACK}Promena naziva preduzeća STR_COMPANY_VIEW_PRESIDENT_NAME_BUTTON :{BLACK}Ime vlasnika STR_COMPANY_VIEW_PRESIDENT_NAME_TOOLTIP :{BLACK}Promena imena vlasnika @@ -3874,11 +3926,11 @@ STR_COMPANY_VIEW_SELL_SHARE_BUTTON :{BLACK}Prodaj 2 STR_COMPANY_VIEW_BUY_SHARE_TOOLTIP :{BLACK}Otkup 25% udela u ovom preduzeću. Shift+klik prikazuje procenu troškova bez kupovine udela STR_COMPANY_VIEW_SELL_SHARE_TOOLTIP :{BLACK}Prodaja 25% udela u ovom preduzeću. Shift+klik prikazuje procenu zarade bez prodaje udela -STR_COMPANY_VIEW_COMPANY_NAME_QUERY_CAPTION :Ime Preduzeća +STR_COMPANY_VIEW_COMPANY_NAME_QUERY_CAPTION :Naziv preduzeća STR_COMPANY_VIEW_PRESIDENT_S_NAME_QUERY_CAPTION :Ime vlasnika STR_COMPANY_VIEW_GIVE_MONEY_QUERY_CAPTION :Unesi iznos novca koji želiš da daš -STR_BUY_COMPANY_MESSAGE :{WHITE}U potrazi smo za preduzećem koje bi preuzelo naše.{}{}Da li biste kupili {COMPANY} za {CURRENCY_LONG}? +STR_BUY_COMPANY_MESSAGE :{WHITE}U potrazi smo za preduzećem koje bi preuzelo naše.{}{}Da li želiš da kupiš {COMPANY} za {CURRENCY_LONG}? # Company infrastructure window STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastruktura preduzeća {COMPANY} @@ -3902,9 +3954,9 @@ STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUST STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} i još {NUM}... -STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Imena fabrika - klikom na ime premešta se glavni pogled na fabriku. Ctrl+Klik otvara novi pogled na lokaciju fabrike -STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Prihvaćen tovar: {SILVER}{STRING} -STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Proizveden tovar: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nazivi fabrika - klikom na naziv glavni pogled se premešta na tu fabriku. Ctrl+klik otvara novi pogled na lokaciju fabrike +STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Prihvaćen teret: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Proizveden teret: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Sve vrste tereta STR_INDUSTRY_DIRECTORY_FILTER_NONE :Nijedna @@ -3912,7 +3964,7 @@ STR_INDUSTRY_DIRECTORY_FILTER_NONE :Nijedna STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Prošlomesečna proizvodnja: STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% prevezeno) -STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju fabrike. Ctrl+Klik otvara novi pogled na lokaciju fabrike +STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju fabrike. Ctrl+klik otvara novi pogled na lokaciju fabrike STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Nivo proizvodnje: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Fabrika je objavila da može svakog trenutka da se zatvori! @@ -3921,7 +3973,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Proizvod STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK} Zahteva: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} čekaje {STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Promena proizvodnje @@ -3932,34 +3984,36 @@ STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Promena STR_VEHICLE_LIST_TRAIN_CAPTION :{WHITE}{STRING} - {COMMA} Voz{P "" a ova} STR_VEHICLE_LIST_ROAD_VEHICLE_CAPTION :{WHITE}{STRING} - {COMMA} Drumsk{P o a ih} Vozil{P o a a} STR_VEHICLE_LIST_SHIP_CAPTION :{WHITE}{STRING} - {COMMA} Brod{P "" a ova} -STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING} - {COMMA} Leteluca +STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING} - {COMMA} Letelica ###length VEHICLE_TYPES -STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP :{BLACK}Vozovi - kliknite na voz za podatke -STR_VEHICLE_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Drumska vozila - kliknite na vozilo za podatke -STR_VEHICLE_LIST_SHIP_TOOLTIP :{BLACK}Brodovi - kliknite na brod za podatke -STR_VEHICLE_LIST_AIRCRAFT_TOOLTIP :{BLACK}Letilice - kliknite na letilicu za podatke +STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP :{BLACK}Vozovi - klikni na voz za podatke +STR_VEHICLE_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Drumska vozila - klikni na vozilo za podatke +STR_VEHICLE_LIST_SHIP_TOOLTIP :{BLACK}Brodovi - klikni na brod za podatke +STR_VEHICLE_LIST_AIRCRAFT_TOOLTIP :{BLACK}Letelice - klik na letelicu za podatke ###length VEHICLE_TYPES -STR_VEHICLE_LIST_AVAILABLE_TRAINS :Dostupni Vozovi -STR_VEHICLE_LIST_AVAILABLE_ROAD_VEHICLES :Dostupna Drumska Vozila -STR_VEHICLE_LIST_AVAILABLE_SHIPS :Dostupni Brodovi -STR_VEHICLE_LIST_AVAILABLE_AIRCRAFT :Dostupne Letelice +STR_VEHICLE_LIST_AVAILABLE_TRAINS :Dostupni vozovi +STR_VEHICLE_LIST_AVAILABLE_ROAD_VEHICLES :Dostupna drumska vozila +STR_VEHICLE_LIST_AVAILABLE_SHIPS :Dostupni brodovi +STR_VEHICLE_LIST_AVAILABLE_AIRCRAFT :Dostupne letelice STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}Upravljanje -STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Pošaljite naredbu svim vozilima na ovoj listi +STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Pošalji naredbu svim vozilima na ovoj listi STR_VEHICLE_LIST_REPLACE_VEHICLES :Obnovi vozila -STR_VEHICLE_LIST_SEND_FOR_SERVICING :Pošalji na Servisiranje +STR_VEHICLE_LIST_SEND_FOR_SERVICING :Pošalji na servis STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Ovogodišnja zarada: {CURRENCY_LONG} (prošle godine: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} -STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Pošalji u Depo -STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Pošalji u Depo -STR_VEHICLE_LIST_SEND_SHIP_TO_DEPOT :Pošalji u Depo -STR_VEHICLE_LIST_SEND_AIRCRAFT_TO_HANGAR :Pošalji u Hangar +STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Pošalji u depo +STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Pošalji u depo +STR_VEHICLE_LIST_SEND_SHIP_TO_DEPOT :Pošalji u depo +STR_VEHICLE_LIST_SEND_AIRCRAFT_TO_HANGAR :Pošalji u hangar STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP :{BLACK}Klikom se zaustavljaju sva vozila na spisku STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP :{BLACK}Klikom se pokreću sva vozila na spisku -STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP :{BLACK}Prikazuje listu raspoloživih mašina za ovu vrstu vozila +STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP :{BLACK}Prikazuje listu raspoloživih lokomotiva za ovu vrstu vozila STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION :{WHITE}Deljene naredbe {COMMA} Vozil{P o a a} @@ -3968,13 +4022,13 @@ STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION :{WHITE}Deljene STR_GROUP_ALL_TRAINS :Svi vozovi STR_GROUP_ALL_ROAD_VEHICLES :Sva drumska vozila STR_GROUP_ALL_SHIPS :Svi brodovi -STR_GROUP_ALL_AIRCRAFTS :Sve letilice +STR_GROUP_ALL_AIRCRAFTS :Sve letelice ###length VEHICLE_TYPES STR_GROUP_DEFAULT_TRAINS :Negrupisani vozovi STR_GROUP_DEFAULT_ROAD_VEHICLES :Negrupisana drumska vozila STR_GROUP_DEFAULT_SHIPS :Negrupisani brodovi -STR_GROUP_DEFAULT_AIRCRAFTS :Negrupisane letilice +STR_GROUP_DEFAULT_AIRCRAFTS :Negrupisane letelice STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) @@ -3985,35 +4039,35 @@ STR_GROUP_RENAME_TOOLTIP :{BLACK}Preimeno STR_GROUP_LIVERY_TOOLTIP :{BLACK}Promena boja odabrane grupe STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Klikom se ova grupa štiti od globalne automatske zamene. Ctrl+klik da se zaštite i podgrupe. -STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Izbriši grupu -STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Da li stvarno želite da izbrišete ovu grupu i sve podgrupe? +STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Obriši grupu +STR_GROUP_DELETE_QUERY_TEXT :{WHITE}Da li zaista želiš da pbrišeš ovu grupu i sve podgrupe? STR_GROUP_ADD_SHARED_VEHICLE :Dodaj deljeno vozilo STR_GROUP_REMOVE_ALL_VEHICLES :Ukloni sva vozila STR_GROUP_RENAME_CAPTION :{BLACK}Preimenuj grupu -STR_GROUP_PROFIT_THIS_YEAR :Dobit ove godine: -STR_GROUP_PROFIT_LAST_YEAR :Dobit prošle godine: +STR_GROUP_PROFIT_THIS_YEAR :Zarada ove godine: +STR_GROUP_PROFIT_LAST_YEAR :Zarada prošle godine: STR_GROUP_OCCUPANCY :Trenutna upotreba: STR_GROUP_OCCUPANCY_VALUE :{NUM}% # Build vehicle window ###length 4 -STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION :Nova Železnička Vozila -STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nova Železnička Električna Vozila -STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nova Jednošinska Vozila -STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nova Maglev Vozila +STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION :Nova železnička vozila +STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nova električna železnička vozila +STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nova jednošinska vozila +STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nova Maglev vozila STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nova drumska vozila STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Nova tramvajska vozila # Vehicle availability ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Šinska Vozila +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nova železnička vozila STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Nova drumska vozila -STR_BUY_VEHICLE_SHIP_CAPTION :Novi Brodovi -STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nove Letilice +STR_BUY_VEHICLE_SHIP_CAPTION :Novi brodovi +STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nove letelice STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} Težina: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} (Cena prepravke: {GOLD}{CURRENCY_LONG}{BLACK}) Težina: {GOLD}{WEIGHT_SHORT} @@ -4021,7 +4075,7 @@ STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Brzina: STR_PURCHASE_INFO_SPEED :{BLACK}Brzina: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Brzina na moru: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_CANAL :{BLACK}Brzina na kanalu/reci: {GOLD}{VELOCITY} -STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Cena održavanja: {GOLD}{CURRENCY_LONG}/god +STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Trošak održavanja: {GOLD}{CURRENCY_LONG}/god STR_PURCHASE_INFO_CAPACITY :{BLACK}Nosivost: {GOLD}{CARGO_LONG} {STRING} STR_PURCHASE_INFO_REFITTABLE :(prepravljiv) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Projektovan: {GOLD}{NUM}{BLACK} Životni vek: {GOLD}{COMMA} godin{P a e a} @@ -4040,19 +4094,24 @@ STR_PURCHASE_INFO_ENGINES_ONLY :Samo lokomotive STR_PURCHASE_INFO_ALL_BUT :Sve sem {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Najveća vučna snaga: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Domet: {GOLD}{COMMA} pločica -STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK} Tip aviona: {GOLD} {STRING} +STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Vrsta aviona: {GOLD}{STRING} + +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Sve vrste tereta +STR_CARGO_TYPE_FILTER_FREIGHT :Teret +STR_CARGO_TYPE_FILTER_NONE :Nijedan ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Spisak probranih šinskih vozila - kliknite na vozilo za više podataka -STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Spisak probranih drumskih vozila - kliknite na vozilo za više podataka -STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}Spisak probranih brodova - kliknite na brod za više podataka -STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Spisak probranih letilica - kliknite na vozilo za više podataka +STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Spisak železničkih vozila. Klik na vozilo za više podataka. Ctrl+klik za prikaz i sakrivanje vrste letelice +STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Spisak drumskih vozila. Klik na vozilo za više podataka. Ctrl+klik za prikaz i sakrivanje vrste letelice +STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}Spisak brodova. Klik na brod za više podataka. Ctrl+klik za prikaz i sakrivanje vrste letelice +STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Spisak letelica. Klik na letelicu za više podataka. Ctrl+klik za prikaz i sakrivanje vrste letelice ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Kupi Vozilo -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Kupi Vozilo -STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Kupi Brod -STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Kupi Letelicu +STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Kupi vozilo +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Kupi vozilo +STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Kupi brod +STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Kupi letelicu ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kupi i prepravi vozilo @@ -4061,16 +4120,16 @@ STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kupi i p STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kupi i prepravi letelicu ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Kupuje označeno šinsko vozilo. Shift+Klik prikazuje procenu troškova bez kupovine -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Kupuje označeno drumsko vozilo. Shift+Klik prikazuje procenu troškova bez kupovine -STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Kupuje označeni brod. Shift+Klik prikazuje procenu troškova bez kupovine -STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Kupuje označenu letilicu. Shift+Klik prikazuje procenu troškova bez kupovine +STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Kupuje označeno železničko vozilo. Shift+klik prikazuje procenu troškova bez kupovine +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Kupuje označeno drumsko vozilo. Shift+klik prikazuje procenu troškova bez kupovine +STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Kupuje označeni brod. Shift+klik prikazuje procenu troškova bez kupovine +STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Kupuje označenu letelicu. Shift+klik prikazuje procenu troškova bez kupovine ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :Kupi i prepravi označeneno šinsko vozilo. Shift+Klik prikazuje procenu troškova bez kupovine -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kupi i prepravi označeno drumsko vozilo. Shift+Klik prikazuje procenu troškova bez kupovine -STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kupi i prepravi označeni brod. Shift+Klik prikazuje procenu troškova bez kupovine -STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kupi i prepravi označenu letelicu. Shift+Klik prikazuje procenu troškova bez kupovine +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kupi i prepravi označeneno železničko vozilo. Shift+klik prikazuje procenu troškova bez kupovine +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kupi i prepravi označeno drumsko vozilo. Shift+klik prikazuje procenu troškova bez kupovine +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kupi i prepravi označeni brod. Shift+klik prikazuje procenu troškova bez kupovine +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kupi i prepravi označenu letelicu. Shift+klik prikazuje procenu troškova bez kupovine ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Preimenuj @@ -4079,16 +4138,16 @@ STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Preimenu STR_BUY_VEHICLE_AIRCRAFT_RENAME_BUTTON :{BLACK}Preimenuj ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_RENAME_TOOLTIP :{BLACK}Preimenujte vrstu šinskog vozila -STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_TOOLTIP :{BLACK}Promenite naziv vrste drumskog vozila -STR_BUY_VEHICLE_SHIP_RENAME_TOOLTIP :{BLACK}Promenite naziv vrste broda -STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}Promenite naziv vrste letilice +STR_BUY_VEHICLE_TRAIN_RENAME_TOOLTIP :{BLACK}Promena naziva vrste železničkog vozila +STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_TOOLTIP :{BLACK}Promena naziva vrste drumskog vozila +STR_BUY_VEHICLE_SHIP_RENAME_TOOLTIP :{BLACK}Promena naziva vrste broda +STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}Promena naziva vrste letelice ###length VEHICLE_TYPES -STR_BUY_VEHICLE_TRAIN_HIDE_TOGGLE_BUTTON :{BLACK}Sakriti -STR_BUY_VEHICLE_ROAD_VEHICLE_HIDE_TOGGLE_BUTTON :{BLACK}Sakriti -STR_BUY_VEHICLE_SHIP_HIDE_TOGGLE_BUTTON :{BLACK}Sakriti -STR_BUY_VEHICLE_AIRCRAFT_HIDE_TOGGLE_BUTTON :{BLACK}Sakriti +STR_BUY_VEHICLE_TRAIN_HIDE_TOGGLE_BUTTON :{BLACK}Sakrij +STR_BUY_VEHICLE_ROAD_VEHICLE_HIDE_TOGGLE_BUTTON :{BLACK}Sakrij +STR_BUY_VEHICLE_SHIP_HIDE_TOGGLE_BUTTON :{BLACK}Sakrij +STR_BUY_VEHICLE_AIRCRAFT_HIDE_TOGGLE_BUTTON :{BLACK}Sakrij ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_SHOW_TOGGLE_BUTTON :{BLACK}Prikaz @@ -4100,13 +4159,13 @@ STR_BUY_VEHICLE_AIRCRAFT_SHOW_TOGGLE_BUTTON :{BLACK}Prikaži STR_BUY_VEHICLE_TRAIN_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Uključi skrivanje/prikazivanje tip voza STR_BUY_VEHICLE_ROAD_VEHICLE_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Uključi skrivanje/prikazivanje tip drumskog vozila STR_BUY_VEHICLE_SHIP_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Uključi skrivanje/prikazivanje tip broda -STR_BUY_VEHICLE_AIRCRAFT_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Uključi skrivanje/prikazivanje tip letilice +STR_BUY_VEHICLE_AIRCRAFT_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Uključi skrivanje/prikazivanje tip letelice ###length VEHICLE_TYPES STR_QUERY_RENAME_TRAIN_TYPE_CAPTION :{WHITE}Promena naziva vrste šinskog vozila STR_QUERY_RENAME_ROAD_VEHICLE_TYPE_CAPTION :{WHITE}Naziv vrste drumskog vozila STR_QUERY_RENAME_SHIP_TYPE_CAPTION :{WHITE}Promena naziva vrste broda -STR_QUERY_RENAME_AIRCRAFT_TYPE_CAPTION :{WHITE}Promena naziva vrste letilice +STR_QUERY_RENAME_AIRCRAFT_TYPE_CAPTION :{WHITE}Promena naziva vrste letelice # Depot window STR_DEPOT_CAPTION :{WHITE}{DEPOT} @@ -4120,22 +4179,22 @@ STR_DEPOT_VEHICLE_TOOLTIP_CHAIN :{BLACK}{NUM} vo STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} ({CARGO_SHORT}) ###length VEHICLE_TYPES -STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Vozovi - prevlačenjem se vozila dodaju/uklanjaju iz kompozicije, desni klik na voz za podatke o njemu, Drži Ctrl da primeniš obe funkcije na ceo lanac +STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Vozovi - prevlačenjem se vozila dodaju/uklanjaju iz kompozicije, desni klik na voz za podatke o njemu. Držanjem Ctrl primenjuju se obe funkcije na ceo lanac STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Vozila - desni klik na vozilo za podatke o njemu STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}Brodovi - desni klik na brod za podatke o njemu -STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Letilice - desni klik na letilicu za podatke o njoj +STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Letelice - desni klik na letelicu za podatke o njoj ###length VEHICLE_TYPES -STR_DEPOT_TRAIN_SELL_TOOLTIP :{BLACK}Ovde prevucite šinsko vozilo kako biste ga prodali -STR_DEPOT_ROAD_VEHICLE_SELL_TOOLTIP :{BLACK}Ovde prevucite drumsko vozilo kako biste ga prodali -STR_DEPOT_SHIP_SELL_TOOLTIP :{BLACK}Ovde prevucite brod kako biste ga prodali -STR_DEPOT_AIRCRAFT_SELL_TOOLTIP :{BLACK}Ovde prevucite letilicu kako biste je prodali +STR_DEPOT_TRAIN_SELL_TOOLTIP :{BLACK}Prevuci ovde šinsko vozilo radi prodaje +STR_DEPOT_ROAD_VEHICLE_SELL_TOOLTIP :{BLACK}Prevuci ovde drumsko vozilo radi prodaje +STR_DEPOT_SHIP_SELL_TOOLTIP :{BLACK}Prevuci ovde brod radi prodaje +STR_DEPOT_AIRCRAFT_SELL_TOOLTIP :{BLACK}Prevuci letelicu ovde radi prodaje ###length VEHICLE_TYPES STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TOOLTIP :{BLACK}Prodaje sve vozove u depou STR_DEPOT_SELL_ALL_BUTTON_ROAD_VEHICLE_TOOLTIP :{BLACK}Prodaje sva drumska vozila u depou STR_DEPOT_SELL_ALL_BUTTON_SHIP_TOOLTIP :{BLACK}Prodaje sve brodove u depou -STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TOOLTIP :{BLACK}Prodaje sve letilice u hangaru +STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TOOLTIP :{BLACK}Prodaje sve letelice u hangaru ###length VEHICLE_TYPES STR_DEPOT_AUTOREPLACE_TRAIN_TOOLTIP :{BLACK}Automatsko obnavljanje svih vozova u depou @@ -4144,28 +4203,28 @@ STR_DEPOT_AUTOREPLACE_SHIP_TOOLTIP :{BLACK}Automats STR_DEPOT_AUTOREPLACE_AIRCRAFT_TOOLTIP :{BLACK}Automatsko obnavljanje svih letelica u hangaru ###length VEHICLE_TYPES -STR_DEPOT_TRAIN_NEW_VEHICLES_BUTTON :{BLACK}Nova Vozila -STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_BUTTON :{BLACK}Nova Vozila -STR_DEPOT_SHIP_NEW_VEHICLES_BUTTON :{BLACK}Novi Brodovi -STR_DEPOT_AIRCRAFT_NEW_VEHICLES_BUTTON :{BLACK}Nova Letilica +STR_DEPOT_TRAIN_NEW_VEHICLES_BUTTON :{BLACK}Nova vozila +STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_BUTTON :{BLACK}Nova vozila +STR_DEPOT_SHIP_NEW_VEHICLES_BUTTON :{BLACK}Novi brodovi +STR_DEPOT_AIRCRAFT_NEW_VEHICLES_BUTTON :{BLACK}Nova letelica ###length VEHICLE_TYPES -STR_DEPOT_TRAIN_NEW_VEHICLES_TOOLTIP :{BLACK}Kupovina novog šinskog vozila +STR_DEPOT_TRAIN_NEW_VEHICLES_TOOLTIP :{BLACK}Kupovina novog žeklezničkog vozila STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_TOOLTIP :{BLACK}Kupovina novog drumskog vozila STR_DEPOT_SHIP_NEW_VEHICLES_TOOLTIP :{BLACK}Kupovina novog broda -STR_DEPOT_AIRCRAFT_NEW_VEHICLES_TOOLTIP :{BLACK}Kupovina nove letilice +STR_DEPOT_AIRCRAFT_NEW_VEHICLES_TOOLTIP :{BLACK}Kupovina nove letelice ###length VEHICLE_TYPES -STR_DEPOT_CLONE_TRAIN :{BLACK}Kopiraj Voz -STR_DEPOT_CLONE_ROAD_VEHICLE :{BLACK}Kopiraj Vozilo -STR_DEPOT_CLONE_SHIP :{BLACK}Kopiraj Brod -STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Kopiraj Letilicu +STR_DEPOT_CLONE_TRAIN :{BLACK}Kopiraj voz +STR_DEPOT_CLONE_ROAD_VEHICLE :{BLACK}Kopiraj vozilo +STR_DEPOT_CLONE_SHIP :{BLACK}Kopiraj brod +STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Kopiraj letelicu ###length VEHICLE_TYPES -STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Ovim ćete kupiti istu kompoziciju. Kliknite na dugme i potom na voz koji je u ili van depoa. Sa Ctrl+klik će imati zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine -STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Ovim ćete kupiti isto drumsko vozilo. Kliknite na dugme i potom na drumsko vozilo koje je u ili van depoa. Sa Ctrl+klik će imati zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine -STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Ovim ćete kupiti isti brod. Kliknite na dugme i potom na brod koji je u ili van depoa. Sa Ctrl+klik će imati zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine -STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Ovim ćete kupiti istu letilicu. Kliknite na dugme i potom na letilicu koje je u ili van depoa. Sa Ctrl+klik će imati zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine +STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Ovime se kupuje ista železnička kompozicija, klikom na dugme i potom na voz koji je unutar ili van depoa. Ctrl+klik postavlja zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine +STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Ovime se kupuje isto drumsko vozilo, klikom na dugme i potom na drumsko vozilo koje je unutar ili van depoa. Ctrl+klik postavlja zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine +STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Ovime se kupuje isti brod, klikom na dugme i potom na brod koji je unutar ili van depoa. Ctrl+klik postavlja zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine +STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Ovime se kupuje ista letelica, klikom na dugme i potom na letelicu koja je unutar ili van depoa. Ctrl+klik postavlja zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine ###length VEHICLE_TYPES STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju železničkog depoa. Ctrl+klik otvara novi pogled na železnički depo @@ -4174,24 +4233,24 @@ STR_DEPOT_SHIP_LOCATION_TOOLTIP :{BLACK}Prebacuj STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju hangara. Ctrl+klik otvara novi pogled na hangar ###length VEHICLE_TYPES -STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP :{BLACK}Dohvata spisak svih vozova sa ovim depoom u naredbama -STR_DEPOT_VEHICLE_ORDER_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Dohvata spisak svih drumskih vozila sa ovim depoom u naredbama -STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TOOLTIP :{BLACK}Dohvata spisak svih brodova sa ovim depoom u naredbama -STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TOOLTIP :{BLACK}Dohvata spisak svih letilica sa hangarom na ovoj stanici u naredbama +STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP :{BLACK}Prikaži spisak svih vozova sa ovim depoom u naredbama +STR_DEPOT_VEHICLE_ORDER_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Prikaži spisak svih drumskih vozila sa ovim depoom u naredbama +STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TOOLTIP :{BLACK}Prikaži spisak svih brodova sa ovim depoom u naredbama +STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TOOLTIP :{BLACK}Prikaži spisak svih letelica sa hangarom na ovoj stanici u naredbama ###length VEHICLE_TYPES STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP :{BLACK}Klikom se zaustavljaju svi vozovi unutar depoa STR_DEPOT_MASS_STOP_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Klikom se zaustavljaju sva drumska vozila unutar depoa STR_DEPOT_MASS_STOP_DEPOT_SHIP_TOOLTIP :{BLACK}Klikom se zaustavljaju svi brodovi unutar depoa -STR_DEPOT_MASS_STOP_HANGAR_TOOLTIP :{BLACK}Klikom se zaustavljaju sve letilice unutar hangara +STR_DEPOT_MASS_STOP_HANGAR_TOOLTIP :{BLACK}Klikom se zaustavljaju sve letelice unutar hangara ###length VEHICLE_TYPES -STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP :{BLACK}Klikom se pokreću svi vozovi u depoima -STR_DEPOT_MASS_START_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Klikom se pokreću sva drumska vozila u depoima -STR_DEPOT_MASS_START_DEPOT_SHIP_TOOLTIP :{BLACK}Klikom se pokreću svi brodovi u depoima -STR_DEPOT_MASS_START_HANGAR_TOOLTIP :{BLACK}Klikom se pokreću sve letilice u hangarima +STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP :{BLACK}Klikom se pokreću svi vozovi u depou +STR_DEPOT_MASS_START_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Klikom se pokreću sva drumska vozila u depou +STR_DEPOT_MASS_START_DEPOT_SHIP_TOOLTIP :{BLACK}Klikom se pokreću svi brodovi u depou +STR_DEPOT_MASS_START_HANGAR_TOOLTIP :{BLACK}Klikom se pokreću sve letelice u hangaru -STR_DEPOT_DRAG_WHOLE_TRAIN_TO_SELL_TOOLTIP :{BLACK}Prevucite ovde lokomotivu kako bi prodali ceo voz +STR_DEPOT_DRAG_WHOLE_TRAIN_TO_SELL_TOOLTIP :{BLACK}Prevuci ovde lokomotivu radi prodaje celog voza STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Upravo ćete prodati sva vozila u depou. Da li ste sigurni? # Engine preview window @@ -4201,27 +4260,27 @@ STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Upravo sm STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=srednji}železničko vučno vozilo STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.aku :železničkog vučnog vozila STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :lokomotiva elektrifikovane železnice -STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=srednji}jednopružno žel. vučno vozilo -STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE.aku :jednopružnog žel. vučnog vozila -STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=srednji}megnetno žel. vučno vozilo +STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=srednji}jednošinsko železnično vučno vozilo +STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE.aku :jednopružnog železničkog vučnog vozila +STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=srednji}magnetno žel. vučno vozilo STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE.aku :magnetnog žel. vučnog vozila STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=srednji}drumsko vozilo STR_ENGINE_PREVIEW_ROAD_VEHICLE.aku :drumskog vozila STR_ENGINE_PREVIEW_TRAM_VEHICLE :tramvajsko vozilo -STR_ENGINE_PREVIEW_AIRCRAFT :{G=ženski}letilica -STR_ENGINE_PREVIEW_AIRCRAFT.aku :letilice +STR_ENGINE_PREVIEW_AIRCRAFT :{G=ženski}letelica +STR_ENGINE_PREVIEW_AIRCRAFT.aku :letelice STR_ENGINE_PREVIEW_SHIP :{G=muški}brod STR_ENGINE_PREVIEW_SHIP.aku :broda -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cena: {CURRENCY_LONG} Težina: {WEIGHT_SHORT}{}Brzina: {VELOCITY} Snaga: {POWER}{}Cena Održavanja: {CURRENCY_LONG}/god.{}Nosivost: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cena: {CURRENCY_LONG} Težina: {WEIGHT_SHORT}{}Brzina: {VELOCITY} Snaga: {POWER} Najveća vučna snaga: {6:FORCE}{}Cena Održavanja: {4:CURRENCY_LONG}/god{}Nosivost: {5:CARGO_LONG} -STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Najveća Brzina: {VELOCITY}{}Nosivost: {CARGO_LONG}{}Cena Održavanja: {CURRENCY_LONG}/god. -STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :BLACK} Cena: {CURRENCY_LONG} Maks. Brzina: {VELOCITY}{} Tip aviona: {STRING}{} Kapacitet: {CARGO_LONG}, {CARGO_LONG}{}Pokretna cena: {CURRENCY_LONG}/godine. -STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK} Cena: {CURRENCY_LONG} Maks. Brzina: {VELOCITY}{}Tip aviona: {STRING}{}Kapacitet: {CARGO_LONG}{}Pokretna cena: {CURRENCY_LONG}/god. -STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK} Cena: {CURRENCY_LONG} Maks. Brzina: {VELOCITY}{} Tip aviona: {STRING} Domet: {COMMA} pločice{}Kapacitet: {CARGO_LONG}, {CARGO_LONG}{} Pokretni trošak: {CURRENCY_LONG} /god. -STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :BLACK}Cena: {CURRENCY_LONG} Maks. Brzina: {VELOCITY}{}Tip aviona: {STRING} Opseg: {COMMA} pločice{}Kapacitet: {CARGO_LONG}{}Pokretni trošak: {CURRENCY_LONG}/god. +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cena: {CURRENCY_LONG} Težina: {WEIGHT_SHORT}{}Brzina: {VELOCITY} Snaga: {POWER}{}Trošak održavanja: {CURRENCY_LONG}/god.{}Nosivost: {CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cena: {0:CURRENCY_LONG} Težina: {1:WEIGHT_SHORT}{}Brzina: {2:VELOCITY} Snaga: {3:POWER} Najveća vučna snaga: {6:FORCE}{}Trošak održavanja: {4:CURRENCY_LONG}/god{}Nosivost: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. brzina: {VELOCITY}{}Nosivost: {CARGO_LONG}{}Trošak održavanja: {CURRENCY_LONG}/god. +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. brzina: {VELOCITY}{}Vrsta letelice: {STRING}{} Nosivost: {CARGO_LONG}, {CARGO_LONG}{}Trošak održavanja: {CURRENCY_LONG}/godine. +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. brzina: {VELOCITY}{}Vrsta letelice: {STRING}{}Nosivost: {CARGO_LONG}{}Trošak održavanja: {CURRENCY_LONG}/god. +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. brzina: {VELOCITY}{}Vrsta letelice: {STRING} Domet: {COMMA} pločica{}Nosivost: {CARGO_LONG}, {CARGO_LONG}{}Trošak održavanja: {CURRENCY_LONG}/god. +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. brzina: {VELOCITY}{}Vrsta letelice: {STRING} Domet: {COMMA} pločice{}Nosivost: {CARGO_LONG}{}Trošak održavanja: {CURRENCY_LONG}/god. # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}Zameni {STRING} - {STRING} @@ -4247,35 +4306,35 @@ STR_REPLACE_VEHICLE_SHIP.aku :brod STR_REPLACE_VEHICLE_AIRCRAFT :letelica STR_REPLACE_VEHICLE_AIRCRAFT.aku :letelicu -STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Izaberite vrstu lokomotive za zamenu -STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Izaberite novu vrstu lokomotive koju biste želeli da koristite umesto obeležene s leve strane +STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Izaberi vrstu lokomotive za zamenu +STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Izaber novu vrstu lokomotive koju želiš da koristiš umesto obeležene sa leve strane -STR_REPLACE_VEHICLES_START :{BLACK}Počni Zamenu Vozila +STR_REPLACE_VEHICLES_START :{BLACK}Započni zamenu vozila STR_REPLACE_VEHICLES_NOW :Zameni sva vozila sada STR_REPLACE_VEHICLES_WHEN_OLD :Zameni samo stara vozila -STR_REPLACE_HELP_START_BUTTON :{BLACK}Pritisnite kako bi počela zamena vrste lokomotive označena sa leve strane sa vrstom označenom sa desne -STR_REPLACE_NOT_REPLACING :{BLACK}Nezamenjuje se +STR_REPLACE_HELP_START_BUTTON :{BLACK}Pritisni kako bi počela zamena vrste lokomotive označena sa leve strane sa vrstom označenom sa desne +STR_REPLACE_NOT_REPLACING :{BLACK}Bez zamene vozila STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Nijedno vozilo nije označeno STR_REPLACE_REPLACING_WHEN_OLD :{ENGINE} kada prethodni -STR_REPLACE_VEHICLES_STOP :{BLACK}Zaustavi Zamenu Vozila -STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Pritisnite kako bi se zaustavila zamena vrsta lokomotive označene sa leve strane +STR_REPLACE_VEHICLES_STOP :{BLACK}Zaustavi zamenu vozila +STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Pritisni kako bi se zaustavila zamena vrsta lokomotive označene sa leve strane STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Prebacuje između prikaza zamene lokomotiva i zamene vagona STR_REPLACE_ENGINES :Lokomotive STR_REPLACE_WAGONS :Vagoni -STR_REPLACE_ALL_RAILTYPE :Sve šinskih vozila +STR_REPLACE_ALL_RAILTYPE :Sva železnička vozila STR_REPLACE_ALL_ROADTYPE :Sva drumska vozila ###length 2 -STR_REPLACE_HELP_RAILTYPE :{BLACK}Izaberite vrstu pruge za koju želite zamenu kompozicije -STR_REPLACE_HELP_ROADTYPE :{BLACK}Odaberite vrstu puta za koju želite zamenu vozila +STR_REPLACE_HELP_RAILTYPE :{BLACK}Izaberi vrstu pruge za koju želiš zamenu kompozicije +STR_REPLACE_HELP_ROADTYPE :{BLACK}Odaberi vrstu puta za koju želiš zamenu vozila ###next-name-looks-similar STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Prikazuje koja lokomotiva će se zameniti označenom sa leve strane, ako ih ima -STR_REPLACE_RAIL_VEHICLES :Šinska Vozila -STR_REPLACE_ELRAIL_VEHICLES :Elektrošinska Vozila -STR_REPLACE_MONORAIL_VEHICLES :Jednošinska Vozila -STR_REPLACE_MAGLEV_VEHICLES :Magnetnošinska Vozila +STR_REPLACE_RAIL_VEHICLES :Železnička vozila +STR_REPLACE_ELRAIL_VEHICLES :Električna železnička vozila +STR_REPLACE_MONORAIL_VEHICLES :Jednošinska vozila +STR_REPLACE_MAGLEV_VEHICLES :Maglev vozila STR_REPLACE_ROAD_VEHICLES :Drumska vozila STR_REPLACE_TRAM_VEHICLES :Tramvajska vozila @@ -4288,45 +4347,45 @@ STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+ STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} ###length VEHICLE_TYPES -STR_VEHICLE_VIEW_TRAIN_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju voza. Dvostruki klik prati voz u glavnom pogledu. Ctrl+Klik otvara novi pogled na voz -STR_VEHICLE_VIEW_ROAD_VEHICLE_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju vozila. Dvostruki klik prati vozlo u glavnom pogledu. Ctrl+Klik otvara novi pogled na vozilo -STR_VEHICLE_VIEW_SHIP_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju broda. Dvostruki klik prati brod u glavnom pogledu. Ctrl+Klik otvara novi pogled na brod -STR_VEHICLE_VIEW_AIRCRAFT_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju letelice. Dvostruki klik prati letelicu u glavnom pogledu. Ctrl+Klik otvara novi pogled na letelicu +STR_VEHICLE_VIEW_TRAIN_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju voza. Dvostruki klik prati voz u glavnom pogledu. Ctrl+klik otvara novi pogled na voz +STR_VEHICLE_VIEW_ROAD_VEHICLE_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju vozila. Dvostruki klik prati vozlo u glavnom pogledu. Ctrl+klik otvara novi pogled na vozilo +STR_VEHICLE_VIEW_SHIP_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju broda. Dvostruki klik prati brod u glavnom pogledu. Ctrl+klik otvara novi pogled na brod +STR_VEHICLE_VIEW_AIRCRAFT_CENTER_TOOLTIP :{BLACK}Prebacuje glavni pogled na lokaciju letelice. Dvostruki klik prati letelicu u glavnom pogledu. Ctrl+klik otvara novi pogled na letelicu ###length VEHICLE_TYPES -STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}Pošaljite voz u depo. Sa Ctrl+Klik će otići samo na servis -STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Pošaljite vozilo u depo. Sa Ctrl+Klik će otići samo na servis -STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Pošaljite brod u depo. Sa Ctrl+Klik će otići samo na servis -STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Pošaljite letilicu u hangar. Sa Ctrl+Klik će otići samo na servis +STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}Šalje voz u depo. Ctrl+klik šalje voz samo na servis +STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Šalje vozilo u depo. Ctrl+klik šalje vozilo samo na servis +STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Šalje brod u depo. Ctrl+klik šalje brod samo na servis +STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Šalje letelicu u hangar. Ctrl+klik šalje letelicu samo na servis ###length VEHICLE_TYPES -STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}Ovim ćete kupiti istu kompoziciju. Sa Ctrl+Klik će imati zajedničke naredbe. Shift+Klik prikazuje procenu troškova bez kupovine -STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}Ovim ćete kupiti isto drumsko vozilo. Sa Ctrl+Klik će imati zajedničke naredbe. Shift+Klik prikazuje procenu troškova bez kupovine -STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}Ovim ćete kupiti isti brod. Sa Ctrl+Klik će imati zajedničke naredbe. Shift+Klik prikazuje procenu troškova bez kupovine -STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}Ovim ćete kupiti kopiju letilice. Sa Ctrl+Klik će imati zajedničke naredbe. Shift+Klik prikazuje procenu troškova bez kupovine +STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}Ovime se kupuje kopija kompozicije. Ctrl+klik postavlja zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine +STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}Ovime se kupuje kopija drumskog vozila. Ctrl+klik postavlja zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine +STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}Ovime se kupuje kopija broda. Ctrl+klik postavlja zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine +STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}Ovime se kupuje kopija letelice. Ctrl+klik postavlja zajedničke naredbe. Shift+klik prikazuje procenu troškova bez kupovine -STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}Nateraj voza da krene bez čekanja na signal za slobodan kolosek +STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}Nateraj voz da krene bez čekanja na signal za slobodan kolosek STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}Promena smera kretanja voza -STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}Naterajte vozilo da okrene -STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP :{BLACK}{BLACK}Prebacuje glavni pogled na destinaciju naredbe. Ctrl+Klik otvara novi pogled na lokaciju destinacije naredbe +STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}Nateraj vozilo da okrene +STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP :{BLACK}Prebacuje glavni pogled na destinaciju naredbe. Ctrl+klik otvara novi pogled na lokaciju destinacije naredbe ###length VEHICLE_TYPES STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Prepravlja voz kako bi prevozio drugu vrstu tereta -STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Prepravite drumsko vozilo kako bi prevozio drugu vrstu tovara -STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}Prepravite brod kako bi prevozio drugu vrstu tereta -STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Prepravite letilicu kako bi prevozila drugu vrstu tereta +STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Preprvlja drumsko vozilo kako bi prevozio drugu vrstu tereta +STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}Prepravlja brod kako bi prevozio drugu vrstu tereta +STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Prepravlja letelicu kako bi prevozila drugu vrstu tereta ###length VEHICLE_TYPES -STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP :{BLACK}Prikazuje naredbe vozu. Ctrl+Klik za prikaz reda vožnje -STR_VEHICLE_VIEW_ROAD_VEHICLE_ORDERS_TOOLTIP :{BLACK}Prikazuje naredbe vozilu. Ctrl+Klik za prikaz reda vožnje -STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Prikazuje naredbe brodu. Ctrl+Klik za prikaz reda vožnje -STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Prikazuje naredbe letilici. Ctrl+Klik za prikaz reda vožnje +STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP :{BLACK}Prikazuje naredbe voza. Ctrl+klik za prikaz reda vožnje +STR_VEHICLE_VIEW_ROAD_VEHICLE_ORDERS_TOOLTIP :{BLACK}Prikazuje naredbe vozila. Ctrl+klik za prikaz reda vožnje +STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Prikazuje naredbe broda. Ctrl+klik za prikaz reda vožnje +STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Prikazuje naredbe letelice. Ctrl+klik za prikaz reda vožnje ###length VEHICLE_TYPES STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Prikazuje podatke o vozu STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Prikazuje detalje drumskog vozila STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Prikazuje podatke o brodu -STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Prikazuje podatke o letilici +STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Prikaži detalje o letelici ###length VEHICLE_TYPES STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP :{BLACK}Trenutka akcija voza - klik za zaustavljanje/pokretanje voza @@ -4372,36 +4431,37 @@ STR_VEHICLE_DETAILS_CAPTION :{WHITE}{VEHICLE STR_VEHICLE_DETAILS_TRAIN_RENAME :{BLACK}Naziv voza STR_VEHICLE_DETAILS_ROAD_VEHICLE_RENAME :{BLACK}Naziv drumskog vozila STR_VEHICLE_DETAILS_SHIP_RENAME :{BLACK}Naziv broda -STR_VEHICLE_DETAILS_AIRCRAFT_RENAME :{BLACK}Naziv letilice +STR_VEHICLE_DETAILS_AIRCRAFT_RENAME :{BLACK}Naziv letelice -STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}Starost: {LTBLUE}{STRING}{BLACK} Cena Održavanja: {LTBLUE}{CURRENCY_LONG}/god. +STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}Starost: {LTBLUE}{STRING}{BLACK} Trošak održavanja: {LTBLUE}{CURRENCY_LONG}/god. STR_VEHICLE_INFO_AGE :{COMMA} godin{P a e a} ({COMMA}) STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} godin{P a e a} ({COMMA}) STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Najveća brzina: {LTBLUE}{VELOCITY} -STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Maks. brzina: {LTBLUE}{VELOCITY} {BLACK}Tip aviona: {LTBLUE}{STRING} -STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :BLACK} Maks. brzina: {LTBLUE} {VELOCITY} {BLACK} Tip aviona: {LTBLUE} {STRING} {BLACK} Opseg: {LTBLUE} {COMMA} pločice +STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Maks. brzina: {LTBLUE}{VELOCITY} {BLACK}Vrsta letelice: {LTBLUE}{STRING} +STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK} Maks. brzina: {LTBLUE} {VELOCITY} {BLACK}Vrsta letelice: {LTBLUE} {STRING} {BLACK} Domet: {LTBLUE} {COMMA} pločice STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Težina: {LTBLUE}{WEIGHT_SHORT} {BLACK}Snaga: {LTBLUE}{POWER}{BLACK} Najveća brzina: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Težina: {LTBLUE}{WEIGHT_SHORT} {BLACK}Snaga: {LTBLUE}{POWER}{BLACK} Najveća brzina: {LTBLUE}{VELOCITY} {BLACK} Najveća vučna snaga: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Ovogodišnja zarada: {LTBLUE}{CURRENCY_LONG} (prošlogodišnja: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Ovogodišnja zarada: {LTBLUE}{CURRENCY_LONG} (prošlogodišnja: {CURRENCY_LONG}) {BLACK}Najlošiji učinak: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Pouzdanost: {LTBLUE}{COMMA}% {BLACK}Kvarova od poslednjeg servisa: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Kupljen: {LTBLUE}{NUM}{BLACK} Vrednost: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Nosivost: {LTBLUE}Nula{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Nosivost: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Nosivost: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Nosivost: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Nosivost: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Nosivost: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Zarada od transfera: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS :{BLACK}Period servisiranja: {LTBLUE}{COMMA}dana{BLACK} Poslednji servis: {LTBLUE}{DATE_LONG} STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT :{BLACK}Period servisiranja: {LTBLUE}{COMMA}%{BLACK} Poslednji servis: {LTBLUE}{DATE_LONG} -STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Povećava period servisiranja za 10. Ctrl+Klik povećava period servisiranja za 5 -STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Smanjuje period servisiranja za 10. Ctrl+Klik smanjuje period servisiranja za 5 +STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Povećava period servisiranja za 10. Ctrl+klik povećava period servisiranja za 5 +STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}Smanjuje period servisiranja za 10. Ctrl+klik smanjuje period servisiranja za 5 STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP :{BLACK}Promeni tip intervala za servis -STR_VEHICLE_DETAILS_DEFAULT :Standard +STR_VEHICLE_DETAILS_DEFAULT :Podrazumevano STR_VEHICLE_DETAILS_DAYS :dani STR_VEHICLE_DETAILS_PERCENT :Procenat @@ -4409,64 +4469,64 @@ STR_VEHICLE_DETAILS_PERCENT :Procenat STR_QUERY_RENAME_TRAIN_CAPTION :{WHITE}Naziv voza STR_QUERY_RENAME_ROAD_VEHICLE_CAPTION :{WHITE}Naziv drumskog vozila STR_QUERY_RENAME_SHIP_CAPTION :{WHITE}Naziv broda -STR_QUERY_RENAME_AIRCRAFT_CAPTION :{WHITE}Naziv letilice +STR_QUERY_RENAME_AIRCRAFT_CAPTION :{WHITE}Naziv letelice # Extra buttons for train details windows STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE}{BLACK} Kupljen: {LTBLUE}{NUM}{BLACK} Vrednost: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Vrednost: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Ukupna nosivost ovog voza: -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Prazno STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} sa {STATION} STR_VEHICLE_DETAILS_CARGO_FROM_MULT :{LTBLUE}{CARGO_LONG} sa {STATION} (x{NUM}) -STR_VEHICLE_DETAIL_TAB_CARGO :{BLACK}Tovar -STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP :{BLACK}Prikazuje podatke o tovaru koji se prevozi +STR_VEHICLE_DETAIL_TAB_CARGO :{BLACK}Teret +STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP :{BLACK}Prikazuje podatke o teretu koji se prevozi STR_VEHICLE_DETAIL_TAB_INFORMATION :{BLACK}Podaci STR_VEHICLE_DETAILS_TRAIN_INFORMATION_TOOLTIP :{BLACK}Prikazuje podatke o kompoziciji -STR_VEHICLE_DETAIL_TAB_CAPACITIES :{BLACK}Kapaciteti +STR_VEHICLE_DETAIL_TAB_CAPACITIES :{BLACK}Nosivost STR_VEHICLE_DETAILS_TRAIN_CAPACITIES_TOOLTIP :{BLACK}Prikazuje nosivost svih vozila u kompoziciji -STR_VEHICLE_DETAIL_TAB_TOTAL_CARGO :{BLACK}Ukupni tovar -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP :{BLACK}Prikazuje ukupnu nosivost voza, podeljenu po vrsti tovara +STR_VEHICLE_DETAIL_TAB_TOTAL_CARGO :{BLACK}Ukupni teret +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP :{BLACK}Prikazuje ukupnu nosivost voza, podeljenu po vrsti tereta STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}Nosivost: {LTBLUE} # Vehicle refit STR_REFIT_CAPTION :{WHITE}{VEHICLE} (Prepravljanje) -STR_REFIT_TITLE :{GOLD}Izaberite vrstu tereta za prevoz: +STR_REFIT_TITLE :{GOLD}Izaberi vrstu tereta za prevoz: STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova nosivost: {GOLD}{CARGO_LONG}{}{BLACK}Cena prepravke: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Nova nosivost: {GOLD}{CARGO_LONG}{}{BLACK}Prihod od prepravke: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Nova nosivost: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Cena prepravke: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Nova nosivost: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Prihod od prepravke: {GREEN}{CURRENCY_LONG} -STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Obeležavanje vozila za prepravku. Povlačenjem miša moguće je obležiti više vozila. Klikom na prazan prostor obležava celo vozilo. Sa Ctrl+Klik će se obeležiti vozilo i prateći lanac +STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Odabir vozila za prepravku. Povlačenjem miša moguće je obležiti više vozila. Klikom na prazan prostor obležava celo vozilo. Sa Ctrl+klik će se obeležiti vozilo i prateći lanac ###length VEHICLE_TYPES -STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Označite vrstu tovara za prepravljanje voza -STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Označite vrstu tovara za prepravljanje drumskog vozila -STR_REFIT_SHIP_LIST_TOOLTIP :{BLACK}Označite vrstu tovara za prepravljanje broda -STR_REFIT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Odaberite vrstu tereta koju će letilica prevoziti +STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Označi vrstu tereta za prepravljanje voza +STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Označi vrstu tereta za prepravljanje drumskog vozila +STR_REFIT_SHIP_LIST_TOOLTIP :{BLACK}Označi vrstu tereta za prepravljanje broda +STR_REFIT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Odaberi vrstu tereta koju će letelica prevoziti ###length VEHICLE_TYPES STR_REFIT_TRAIN_REFIT_BUTTON :{BLACK}Prepavi voz STR_REFIT_ROAD_VEHICLE_REFIT_BUTTON :{BLACK}Prepravi drumsko vozilo STR_REFIT_SHIP_REFIT_BUTTON :{BLACK}Prepravi brod -STR_REFIT_AIRCRAFT_REFIT_BUTTON :{BLACK}Prepravi letilicu +STR_REFIT_AIRCRAFT_REFIT_BUTTON :{BLACK}Prepravi letelicu ###length VEHICLE_TYPES -STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}Prepravlja voz za prevoz označene vrste tovara -STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Prepravlja drumsko vozilo za prevoz označene vrste tovara -STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}Prepravlja brod za prevoz označene vrste tovara -STR_REFIT_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Prepravite letilicu kako bi prevozila označenu vrstu tereta +STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}Prepravlja voz za prevoz označene vrste tereta +STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Prepravlja drumsko vozilo za prevoz označene vrste tereta +STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}Prepravlja brod za prevoz označene vrste tereta +STR_REFIT_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Prepravilja letelicu kako bi prevozila označenu vrstu tereta # Order view STR_ORDERS_CAPTION :{WHITE}{VEHICLE} (Naredbe) STR_ORDERS_TIMETABLE_VIEW :{BLACK}Raspored STR_ORDERS_TIMETABLE_VIEW_TOOLTIP :{BLACK}Prelazi na raspored -STR_ORDERS_LIST_TOOLTIP :{BLACK}Spisak naredbi - klikom se obeležava naredba. Sa Ctrl+Klik se prelazi na lokaciju stanice +STR_ORDERS_LIST_TOOLTIP :{BLACK}Spisak naredbi - klikom se obeležava naredba. Ctrl+klik pomera prikaz na lokaciju stanice STR_ORDER_INDEX :{COMMA}:{NBSP} STR_ORDER_TEXT :{STRING} {STRING} {STRING} @@ -4496,11 +4556,11 @@ STR_ORDER_DROP_NO_UNLOADING :Bez istovara STR_ORDER_TOOLTIP_UNLOAD :{BLACK}Promena načina istovara u označenoj naredbi STR_ORDER_REFIT :{BLACK}Prepravi -STR_ORDER_REFIT_TOOLTIP :{BLACK}Označite za koji tovar da se prepravi u ovoj naredbi. Ctrl+Klik za uklanjanje prepravljanja +STR_ORDER_REFIT_TOOLTIP :{BLACK}Označi vrstu tereta za prepravku u ovoj naredbi. Ctrl+klik za uklanjanje prepravljanja STR_ORDER_REFIT_AUTO :{BLACK}Samo-prepravljanje -STR_ORDER_REFIT_AUTO_TOOLTIP :{BLACK}Odabir vrste tereta za samo-prepravljanje po redosledu. Ctrl+Klik za uklanjanje komande za prepravljanje. Samo-prepravljanje će se izvršiti samo ako vozilo to dozvoljava -STR_ORDER_DROP_REFIT_AUTO :Određen tovar -STR_ORDER_DROP_REFIT_AUTO_ANY :Dostupan tovar +STR_ORDER_REFIT_AUTO_TOOLTIP :{BLACK}Odabir vrste tereta za samo-prepravljanje po redosledu. Ctrl+klik za uklanjanje komande za prepravljanje. Samo-prepravljanje će se izvršiti samo ako vozilo to dozvoljava +STR_ORDER_DROP_REFIT_AUTO :Određen teret +STR_ORDER_DROP_REFIT_AUTO_ANY :Dostupan teret STR_ORDER_SERVICE :{BLACK}Servis STR_ORDER_DROP_GO_ALWAYS_DEPOT :Uvek @@ -4536,20 +4596,20 @@ STR_ORDER_CONDITIONAL_VALUE_TOOLTIP :{BLACK}Vrednost STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Unos vrednosti za poređenje STR_ORDERS_SKIP_BUTTON :{BLACK}Preskoči -STR_ORDERS_SKIP_TOOLTIP :{BLACK}Preskoči tekuću naredbu, i prelazi na sledeću. Ctrl+Klik preskače naredbe do obeležene +STR_ORDERS_SKIP_TOOLTIP :{BLACK}Preskoči tekuću naredbu i prelazi na sledeću. Ctrl+klik preskače naredbe do obeležene -STR_ORDERS_DELETE_BUTTON :{BLACK}Izbriši +STR_ORDERS_DELETE_BUTTON :{BLACK}Obriši STR_ORDERS_DELETE_TOOLTIP :{BLACK}Uklanja obeleženu naredbu STR_ORDERS_DELETE_ALL_TOOLTIP :{BLACK}Uklanja sva naređenja STR_ORDERS_STOP_SHARING_BUTTON :{BLACK}Prekini deljenje -STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}Prekida deljenje liste naredbi. Sa Ctrl+Klik se još i briše cela lista naredbi +STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}Prekida deljenje liste naredbi. Ctrl+klik dodatno uklanja sve naredbe za ovo vozilo STR_ORDERS_GO_TO_BUTTON :{BLACK}Idi do STR_ORDER_GO_TO_NEAREST_DEPOT :Idi do najbližeg depoa STR_ORDER_GO_TO_NEAREST_HANGAR :Idi do najbližeg hangara STR_ORDER_CONDITIONAL :Uslovna naredba skoka STR_ORDER_SHARE :Deli naredbe -STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Ubacuje novu naredbu pre obeležene, ili je dodaje na kraju spiska. Ctrl čini da stanica naredi "pun bilo koji tovar", putna tačka naredi "non-stop" i depo naredi "servis". "Deli naredbe" ili Ctrl omogućava da vozilo deli naredbe sa drugim odabranim vozilom. Klikom na drugo vozilo kopiraju se njegove naredbe. Naredbom za depo se isključuje automatsko servisiranje +STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Unosi novu naredbu pre obeležene, ili je dodaje na kraju spiska. Ctrl čini da stanica naredi "pun bilo koji teret", putna tačka naredi "non-stop" i depo naredi "servis". "Deli naredbe" ili Ctrl omogućava da vozilo deli naredbe sa drugim odabranim vozilom. Klikom na drugo vozilo kopiraju se njegove naredbe. Naredbom za depo se isključuje automatsko servisiranje STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Prikazuje sva vozila koja dele ovaj red vožnje @@ -4563,7 +4623,7 @@ STR_ORDER_SERVICE_NON_STOP_AT :Diektno na serv STR_ORDER_NEAREST_DEPOT :najbliži STR_ORDER_NEAREST_HANGAR :najbliži Hangar ###length 3 -STR_ORDER_TRAIN_DEPOT :Železnički Depo +STR_ORDER_TRAIN_DEPOT :Železnički depo STR_ORDER_ROAD_VEHICLE_DEPOT :Drumski Depo STR_ORDER_SHIP_DEPOT :Brodogradilište ###next-name-looks-similar @@ -4609,7 +4669,7 @@ STR_ORDER_NO_UNLOAD_REFIT :(Bez istovara i STR_ORDER_NO_UNLOAD_FULL_LOAD_REFIT :(Bez istovara i pun utovar sa samo-prepravljanjem za {STRING}) STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY_REFIT :(Bez istovara i pun utovar bilo kog sa samo-prepravljanjem za {STRING}) -STR_ORDER_AUTO_REFIT_ANY :dostupni tovar +STR_ORDER_AUTO_REFIT_ANY :dostupan teret ###length 3 STR_ORDER_STOP_LOCATION_NEAR_END :[pri početku] @@ -4656,25 +4716,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Ovaj ras STR_TIMETABLE_STATUS_START_AT :{BLACK}Ovaj raspored počinje {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Datum početka -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Izaberi datum kao početak ovog rasporeda. Ctrl+Click namešta polaznu tačku ovog rasporeda i deli ovaj raspored sa svim povezanim rasporedima +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Izaberi datum kao početak ovog rasporeda. Ctrl+klik jednako raspoređuje sva vozila koja dele ovu naredbu od datog datuma prema njihovom rasporedu, ukoliko je naredba u potpunosti unesena u vozni red -STR_TIMETABLE_CHANGE_TIME :{BLACK}Promena Vremena -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Menjanje količine vremena za koje će obeležena naredba trajati +STR_TIMETABLE_CHANGE_TIME :{BLACK}Promena vremena +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Promena količine vremena za koje će obeležena naredba trajati. Ctrl+klik podešava vreme za sve naredbe -STR_TIMETABLE_CLEAR_TIME :{BLACK}Ukloni Vreme -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Uklanja vreme koje je određeno za obeleženu naredbu +STR_TIMETABLE_CLEAR_TIME :{BLACK}Poništi vreme +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Poništava vreme koje je određeno za obeleženu naredbu. Ctrl+klik poništava vreme za sve naredbe -STR_TIMETABLE_CHANGE_SPEED :{BLACK}Promeni Ograničenje Brzine -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Menjanje ograničenja najviše brzine putovanja onznačene naredbe +STR_TIMETABLE_CHANGE_SPEED :{BLACK}Promeni ograničenje brzine +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Promena ograničenja najviše brzine putovanja označene naredbe. Ctrl+klik podešava brzinu za sve naredbe -STR_TIMETABLE_CLEAR_SPEED :{BLACK}Ukloni Ograničenje Brzine -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Uklanja ograničenje najviše brzine putovanja označene naredbe +STR_TIMETABLE_CLEAR_SPEED :{BLACK}Poništavanje ograničenja brzine +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Poništava ograničenje najviše brzine putovanja označene naredbe. Ctrl+klik poništava brzinu za sve naredbe STR_TIMETABLE_RESET_LATENESS :{BLACK}Poništi Merač Kašnjenja STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Poništava merač kašnjenja, tako da vozilo ide na vreme STR_TIMETABLE_AUTOFILL :{BLACK}Automatsko popunjavanje -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Popunjava raspored sa vrednostima iz sledećeg putovanja (Ctrl+Klik za zadržavanje vremena čekanja) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Popunjava raspored sa vrednostima iz sledećeg putovanja. Ctrl+klik zadržava vremena čekanja STR_TIMETABLE_EXPECTED :{BLACK}Očekivano STR_TIMETABLE_SCHEDULED :{BLACK}Po planu @@ -4694,7 +4754,7 @@ STR_DATE_YEAR_TOOLTIP :{BLACK}Izbor go # AI debug window -STR_AI_DEBUG :{WHITE}Korekcija veštačke inteligencije / skripte partije +STR_AI_DEBUG :{WHITE}Korekcija VI / skripte igre STR_AI_DEBUG_NAME_AND_VERSION :{BLACK}{STRING} (v{NUM}) STR_AI_DEBUG_NAME_TOOLTIP :{BLACK}Naziv skripte STR_AI_DEBUG_SETTINGS :{BLACK}Podešavanja @@ -4704,39 +4764,40 @@ STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}Zaustavl STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}Uključuje/isključuje prekidanje kada VI ispiše poruku koja se poklapa sa prekidnom niskom STR_AI_DEBUG_BREAK_ON_LABEL :{BLACK}Prekid na: STR_AI_DEBUG_BREAK_STR_OSKTITLE :{BLACK}Prekid na -STR_AI_DEBUG_BREAK_STR_TOOLTIP :{BLACK}Kada VI ispiše poruku koja se poklapa sa ovom niskom, partija se pauzira +STR_AI_DEBUG_BREAK_STR_TOOLTIP :{BLACK}Kada VI ispiše poruku koja se poklapa sa ovom niskom, igra se pauzira STR_AI_DEBUG_MATCH_CASE :{BLACK}Podudaranje vel. slova STR_AI_DEBUG_MATCH_CASE_TOOLTIP :{BLACK}Uključuje/isključuje podudaranje malih i velikih slova tokom poređenja zapisanih VI poruka sa prekidnom niskom STR_AI_DEBUG_CONTINUE :{BLACK}Nastavi -STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}Nastavlja partiju i VI +STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}Nastavlja rad VI STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}Prikazuje podatke radi korekcije ove VI -STR_AI_GAME_SCRIPT :{BLACK}Skripta Partije -STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Pregled zapisnika Skripte partije +STR_AI_GAME_SCRIPT :{BLACK}Skripta igre +STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Pregled dnevnika skripte igre STR_ERROR_AI_NO_AI_FOUND :Nije pronađena nijedna prikladna VI.{}Učitana zamena neće raditi ništa.{}Možete preuzeti nekoliko VI preko sistema za preuzimanje dodataka -STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Jedna od pokrenutih skripti je pukla. Molimo vas da prijavite grešku autoru skripte sa slikom prozora za korigovanje VI / Skripte Partije -STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Prozor za korigovanje VI / Skripte Partije je dostupan samo na serveru +STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Jedna od pokrenutih skripti je prestala da radi. Molimo za prijavu greške autoru skripte sa slikom prozora za korigovanje VI / skripte +STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Prozor za korigovanje VI / skripte je dostupan samo na serveru # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Podešavanja VI / skripte igre -STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Skripta igre koja će biti pokrenuta u sledećoj partiji -STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Veštačke inteligencije koje će biti pokrenute u sledećoj partiji +STR_AI_CONFIG_CAPTION_AI :{WHITE}Podešavanja VI +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Podešavanja skripte +STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Skripta koja će biti pokrenuta u sledećoj igri +STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Veštačke inteligencije koje će biti pokrenute u sledećoj igri STR_AI_CONFIG_HUMAN_PLAYER :Ljudsko biće STR_AI_CONFIG_RANDOM_AI :Proizvoljna VI STR_AI_CONFIG_NONE :(nijedna) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Najveći broj suparnika: {ORANGE}{COMMA} -STR_AI_CONFIG_MOVE_UP :{BLACK}Pomeri Naviše +STR_AI_CONFIG_MOVE_UP :{BLACK}Pomeri naviše STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Pomera obeleženu VI naviše u listi -STR_AI_CONFIG_MOVE_DOWN :{BLACK}Pomeri Naniže +STR_AI_CONFIG_MOVE_DOWN :{BLACK}Pomeri naniže STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Pomera obeleženu VI naniže u listi STR_AI_CONFIG_GAMESCRIPT :{SILVER}Skripta igre +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametri STR_AI_CONFIG_AI :{SILVER}VIe -STR_AI_CONFIG_CHANGE :{BLACK}Izaberi {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :VI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Skripta igre +STR_AI_CONFIG_CHANGE_AI :{BLACK}Odaberi VI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Odaberi skriptu STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Učitava drugu skriptu STR_AI_CONFIG_CONFIGURE :{BLACK}Podešavanje STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Podešavanje parametara skripte @@ -4744,7 +4805,7 @@ STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Podešav # Available AIs window STR_AI_LIST_CAPTION :{WHITE}Dostupno {STRING} STR_AI_LIST_CAPTION_AI :VIe -STR_AI_LIST_CAPTION_GAMESCRIPT :Skripte Partije +STR_AI_LIST_CAPTION_GAMESCRIPT :Skripte STR_AI_LIST_TOOLTIP :{BLACK}Klikom se označava skripta STR_AI_LIST_AUTHOR :{LTBLUE}Autor: {ORANGE}{STRING} @@ -4752,7 +4813,7 @@ STR_AI_LIST_VERSION :{LTBLUE}Izdanje STR_AI_LIST_URL :{LTBLUE}URL: {ORANGE}{STRING} STR_AI_LIST_ACCEPT :{BLACK}Prihvati -STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Izabira označenu skriptu +STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Bira označenu skriptu STR_AI_LIST_CANCEL :{BLACK}Otkaži STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ne menja skriptu @@ -4764,10 +4825,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Slika ek STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Slika ekrana sa elevacionom kartom STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Slika umanjene mape -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametri -STR_AI_SETTINGS_CAPTION_AI :VI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Skripta Partije +# Script Parameters +STR_AI_SETTINGS_CAPTION_AI :{WHITE}Parametri VI STR_AI_SETTINGS_CLOSE :{BLACK}Zatvori STR_AI_SETTINGS_RESET :{BLACK}Poništi STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4811,25 +4870,25 @@ STR_MESSAGE_ESTIMATED_COST :{WHITE}Procena STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Procena zarade: {CURRENCY_LONG} # Saveload messages -STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Čuvanje je još u toku,{}molim sačekajte dok se ne završi! +STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Čuvanje je još u toku,{}molimo sačekaj dok se ne završi! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Neuspešno automatsko čuvanje STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Čitanje sa diska nije uspelo STR_ERROR_GAME_SAVE_FAILED :{WHITE}Čuvanje pozicije nije uspelo{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Brisanje datoteke nije uspelo STR_ERROR_GAME_LOAD_FAILED :{WHITE}Učitavanje pozicije nije uspelo{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Unutrašnja greška: {STRING} -STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Neispravna sačuvana partija - {STRING} -STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Partija je sačuvana sa novijom verzijom igre +STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Neispravno sačuvana igra - {STRING} +STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Igra je sačuvana sa novijom verzijom igre STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE :Datoteka se ne može pročitati STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE :Ne može se upisivati u datoteku STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED :Integritet podataka je narušen STR_GAME_SAVELOAD_ERROR_PATCHPACK :Sačuvana igra je napravljena sa izmenjenom verzijom STR_GAME_SAVELOAD_NOT_AVAILABLE : -STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}Partija je sačuvana u vreziji bez podrške za tramvaje. Svi tramvaji su uklonjeni +STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}Igra je sačuvana u verziji bez podrške za tramvaje. Svi tramvaji su uklonjeni # Map generation messages STR_ERROR_COULD_NOT_CREATE_TOWN :{WHITE}Kreiranje terena otkazano...{}... nepostoje prikladne lokacije za naselja -STR_ERROR_NO_TOWN_IN_SCENARIO :{WHITE}... nepostoji nijedno naselje u ovom scenariju +STR_ERROR_NO_TOWN_IN_SCENARIO :{WHITE}... ne postoji nijedno naselje u ovom scenariju STR_ERROR_PNGMAP :{WHITE}Ne može se naparaviti reljef iz PNG slike... STR_ERROR_PNGMAP_FILE_NOT_FOUND :{WHITE}... datoteka nije nađena @@ -4845,11 +4904,11 @@ STR_WARNING_HEIGHTMAP_SCALE_CAPTION :{WHITE}Upozoren STR_WARNING_HEIGHTMAP_SCALE_MESSAGE :{YELLOW}Preterana promena veličine karte nije preporučljiva. Da li da se nastavi generisanje? # Soundset messages -STR_WARNING_FALLBACK_SOUNDSET :{WHITE}Pronađen je samo rezervni skup zvukova. Ukoliko želite zvukove, preuzmite skup zvukova preko sistema za dodatke +STR_WARNING_FALLBACK_SOUNDSET :{WHITE}Pronađen je samo rezervni skup zvukova. Ukoliko želiš zvukove, preuzmi skup zvukova preko sistema za dodatke # Screenshot related messages STR_WARNING_SCREENSHOT_SIZE_CAPTION :{WHITE}Ogromna slika ekrana -STR_WARNING_SCREENSHOT_SIZE_MESSAGE :{YELLOW}Slika ekrana će imati rezoluciju {COMMA} x {COMMA} tačaka. Snimanje slike će možda malo potrajati. Da li hoćete da nastavite? +STR_WARNING_SCREENSHOT_SIZE_MESSAGE :{YELLOW}Slika ekrana će imati rezoluciju {COMMA}x{COMMA} tačaka. Snimanje slike će možda malo potrajati. Da li želiš da nastaviš? STR_MESSAGE_HEIGHTMAP_SUCCESSFULLY :{WHITE}Visinska mapa uspešno sačuvana kao '{STRING}'. Najviši vrh je {NUM} STR_MESSAGE_SCREENSHOT_SUCCESSFULLY :{WHITE}Slika je snimljena pod imenom '{STRING}' @@ -4866,10 +4925,10 @@ STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY :{WHITE}Nema dov STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Neophodno je ravno tlo STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Teren je nagnut na lošu stranu STR_ERROR_CAN_T_DO_THIS :{WHITE}Neizvodljivo... -STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Zgradu bi trebalo srušiti prethodno +STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Potrebno je prvo srušiti zgradu STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Područje ne može biti očišćeno... STR_ERROR_SITE_UNSUITABLE :{WHITE}... mesto je neadekvatno -STR_ERROR_ALREADY_BUILT :{WHITE}... već izgrađeno +STR_ERROR_ALREADY_BUILT :{WHITE}... već je izgrađeno STR_ERROR_OWNED_BY :{WHITE}... je u vlasništvu igrača {STRING} STR_ERROR_AREA_IS_OWNED_BY_ANOTHER :{WHITE}... zemljište je u vlasništvu drugog preduzeća STR_ERROR_TERRAFORM_LIMIT_REACHED :{WHITE}... dostignuto ograničenje u izmeni reljefa @@ -4892,7 +4951,7 @@ STR_ERROR_CAN_T_LEVEL_LAND_HERE :{WHITE}Nije izv STR_ERROR_EXCAVATION_WOULD_DAMAGE :{WHITE}Iskopavanje bi oštetilo tunel STR_ERROR_ALREADY_AT_SEA_LEVEL :{WHITE}... teren je već na nivou mora STR_ERROR_TOO_HIGH :{WHITE}... previsoko -STR_ERROR_ALREADY_LEVELLED :{WHITE}... već je ravno +STR_ERROR_ALREADY_LEVELLED :{WHITE}... već je poravnato STR_ERROR_BRIDGE_TOO_HIGH_AFTER_LOWER_LAND :{WHITE}Posle toga most bi bio previše visok. # Company related errors @@ -4905,7 +4964,7 @@ STR_ERROR_LOAN_ALREADY_REPAYED :{WHITE}... nema STR_ERROR_CURRENCY_REQUIRED :{WHITE}... potrebno {CURRENCY_LONG} STR_ERROR_CAN_T_REPAY_LOAN :{WHITE}Nije moguće vratiti deo zajma... STR_ERROR_INSUFFICIENT_FUNDS :{WHITE}Nemoguće je dati novac koji je pozajmljen od banke... -STR_ERROR_CAN_T_GIVE_MONEY :{WHITE}Nemoguće je dati novac ovoj kompaniji... +STR_ERROR_CAN_T_GIVE_MONEY :{WHITE}Nemoguće je dati novac ovom preduzeću... STR_ERROR_CAN_T_BUY_COMPANY :{WHITE}Nije moguće kupiti preduzeće... STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS :{WHITE}Nije moguće izgraditi upravnu zgradu... STR_ERROR_CAN_T_BUY_25_SHARE_IN_THIS :{WHITE}Otkup 25% udela ovog preduzeća nije moguć... @@ -4921,16 +4980,17 @@ STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... prev STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... drugo naselje je previše blizu STR_ERROR_TOO_MANY_TOWNS :{WHITE}... ima previše naselja STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... više ne postoji slobodnog prostora na terenu -STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Naselje neće graditi kolovoze. Možete uključiti gradnju kolovoza preko Napredna Podešavalja->Ekonomija->Naselja +STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Naselje neće graditi kolovoze. Možete uključiti gradnju kolovoza preko Napredna Podešavanja->Okruženje->Naselja STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}Putni radovi u toku -STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Ovo naselje se ne može ukloniti...{}Stanica ili depo na zemljištvu naselja se ne može ukloniti -STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ne postoji prikladno mesto za spomenik u centru ovog naselja +STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}Nije moguće obrisati naselje...{}Stanica ili depo na zemljištvu naselja se ne može ukloniti +STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... ne postoji odgovarajuće mesto za spomenik u centru ovog naselja # Industry related errors STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... ima previše fabrika STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nemoguće stvaranje fabrika... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}{STRING} je nemoguće izgraditi ovde... -STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Nije moguće ovde izgraditi taj tip industrije... +STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Nije moguće ovde izgraditi tu vrstu fabrike... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Nije moguće istražiti fabriku... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... previše blizu druge fabrike STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... prvo bi trebalo podići naselje STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... dozvoljena je samo jedna ovakva gradnja po naselju @@ -4945,7 +5005,9 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... šum STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... može biti izgrađena samo iznad linije snega STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... može biti izgrađena samo ispod linije snega -STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Nije bilo odgovarajućih mesta za '{STRING}' fabrike +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Postavi šemu boja koja se koristi za preklapanje toka tereta. +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Nema odgovarajućih mesta za istraživanje ove fabrike +STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Nema odgovarajućih mesta za '{STRING}' fabrike STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Promena parametara generisanja karte za dobivanje bolje karte # Station construction related errors @@ -4962,7 +5024,7 @@ STR_ERROR_STATION_TOO_SPREAD_OUT :{WHITE}... stan STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Previše je stanica STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Previše delova železničke stanice STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Previše autobuskih stanica -STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Previše tovarnih stanica +STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Previše teretnih stanica STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Previše je blizu drugog pristaništa STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Previše je blizu drugog aerodroma STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Ova stanica ne može biti preimenovana... @@ -4985,7 +5047,7 @@ STR_ERROR_MUST_DEMOLISH_RAILROAD :{WHITE}Potrebno STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST :{WHITE}Potrebno je prvo srušiti autobusku stanicu STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST :{WHITE}Potrebno je prvo srušiti stanicu za utovar kamiona STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST :{WHITE}Prvo se mora ukloniti putnička tamvajska stanica -STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST :{WHITE}Prvo se mora ukloniti tovarna tamvajska stanica +STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST :{WHITE}Prvo se mora ukloniti teretna tramvajska stanica STR_ERROR_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Potrebno je prvo srušiti pristanište STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Potrebno je prvo srušiti aerodrom @@ -5112,10 +5174,11 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objekat STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... upravna zgrada preduzeća na putu STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Ovo zemljište se ne može kupiti... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... već pripada preduzeću! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... dostignuto ograničenje u gradnji objekata # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Grupa se ne može napraviti... -STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Grupa se ne može izbrisati... +STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Nije moguće obrisati grupu... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Grupa se ne može preimenovati... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Ne može se postaviti matična grupa... STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... petlje u hijerarhiji grupa nisu dozvoljene @@ -5129,37 +5192,37 @@ STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Deljena STR_ERROR_TRAIN_IN_THE_WAY :{WHITE}Voz se tu upravo nalazi STR_ERROR_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Drumsko vozilo na putu STR_ERROR_SHIP_IN_THE_WAY :{WHITE}Brod se tu upravo nalazi -STR_ERROR_AIRCRAFT_IN_THE_WAY :{WHITE}Letilica se tu nalazi +STR_ERROR_AIRCRAFT_IN_THE_WAY :{WHITE}Letelica na putu ###length VEHICLE_TYPES STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE :{WHITE}Šinsko vozilo nije dostupno STR_ERROR_ROAD_VEHICLE_NOT_AVAILABLE :{WHITE}Drumsko vozilo nije dostupno STR_ERROR_SHIP_NOT_AVAILABLE :{WHITE}Brod nije dostupan -STR_ERROR_AIRCRAFT_NOT_AVAILABLE :{WHITE}Letilica nije dostupna +STR_ERROR_AIRCRAFT_NOT_AVAILABLE :{WHITE}Letelica nije dostupna ###length VEHICLE_TYPES STR_ERROR_CAN_T_REFIT_TRAIN :{WHITE}Voz se ne može prepraviti... STR_ERROR_CAN_T_REFIT_ROAD_VEHICLE :{WHITE}Nemoguće prepravljanje drumskog vozila... STR_ERROR_CAN_T_REFIT_SHIP :{WHITE}Brod se ne može prepraviti... -STR_ERROR_CAN_T_REFIT_AIRCRAFT :{WHITE}Nemoguće je prepraviti letilicu... +STR_ERROR_CAN_T_REFIT_AIRCRAFT :{WHITE}Nemoguće je prepraviti letelicu... ###length VEHICLE_TYPES STR_ERROR_CAN_T_RENAME_TRAIN :{WHITE}Nemoguće nazvati voz... STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Ne može se promeniti naziv vozila... STR_ERROR_CAN_T_RENAME_SHIP :{WHITE}Ne može se promeniti naziv broda... -STR_ERROR_CAN_T_RENAME_AIRCRAFT :{WHITE}Ne može se promeniti naziv letilice... +STR_ERROR_CAN_T_RENAME_AIRCRAFT :{WHITE}Ne može se promeniti naziv letelice... ###length VEHICLE_TYPES STR_ERROR_CAN_T_STOP_START_TRAIN :{WHITE}Ne može se pokrenuti/zaustaviti voz... STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Ne može se pokrenuti/zaustaviti drumsko vozilo... STR_ERROR_CAN_T_STOP_START_SHIP :{WHITE}Ne može se pokrenuti/zaustaviti brod... -STR_ERROR_CAN_T_STOP_START_AIRCRAFT :{WHITE}Ne može se pokrenuti/zaustaviti letilica... +STR_ERROR_CAN_T_STOP_START_AIRCRAFT :{WHITE}Ne može se pokrenuti/zaustaviti letelica... ###length VEHICLE_TYPES STR_ERROR_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Voz ne može da ode u depo... STR_ERROR_CAN_T_SEND_ROAD_VEHICLE_TO_DEPOT :{WHITE}Vozilo ne može da ode u depo... STR_ERROR_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Brod ne može da ode u depo... -STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR :{WHITE}Letilica ne može da ode u hangar... +STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR :{WHITE}Letelica ne može da ode u hangar... ###length VEHICLE_TYPES STR_ERROR_CAN_T_BUY_TRAIN :{WHITE}Nemoguća kupovina šinskog vozila... @@ -5171,23 +5234,25 @@ STR_ERROR_CAN_T_BUY_AIRCRAFT :{WHITE}Ne može STR_ERROR_CAN_T_RENAME_TRAIN_TYPE :{WHITE}Nemoguća promena naziva vrste šinskog vozila... STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Nemoguća promena naziva vrste drumskog vozila... STR_ERROR_CAN_T_RENAME_SHIP_TYPE :{WHITE}Nemoguća promena naziva vrste broda... -STR_ERROR_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Nemoguća promena naziva vrste letilice... +STR_ERROR_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Nemoguća promena naziva vrste letelice... ###length VEHICLE_TYPES STR_ERROR_CAN_T_SELL_TRAIN :{WHITE}Ne može se prodati šinsko vozilo... STR_ERROR_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Nemoguća prodaja drumskog vozila... STR_ERROR_CAN_T_SELL_SHIP :{WHITE}Brod se ne može prodati... -STR_ERROR_CAN_T_SELL_AIRCRAFT :{WHITE}Letilica se ne može prodati... +STR_ERROR_CAN_T_SELL_AIRCRAFT :{WHITE}Letelica se ne može prodati... STR_ERROR_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Previše je vozila u igri STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Servisni interval nije moguće promeniti... STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vozilo je uništeno +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... nisu sva vozila identična + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Nijedno vozilo neće biti dostupno -STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Promenite konfiguraciju za NewGRF +STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Promeni podešavanja za NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Nijedno vozilo još uvek nije dostupno -STR_ERROR_NO_VEHICLES_AVAILABLE_YET_EXPLANATION :{WHITE}Pokrenite novu igru koja počinje posle {DATE_SHORT} ili koristite NewGRF koji omogućava ranija vozila +STR_ERROR_NO_VEHICLES_AVAILABLE_YET_EXPLANATION :{WHITE}Pokreni novu igru koja počinje posle {DATE_SHORT} ili koristi NewGRF koji omogućava ranija vozila # Specific vehicle errors STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}Nemoguć je prolaz voza na signal opasnosti... @@ -5196,26 +5261,30 @@ STR_ERROR_TRAIN_START_NO_POWER :Voz nema struju STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN :{WHITE}Drumsko vozilo ne može da se okrene... -STR_ERROR_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Letilica je u vazduhu +STR_ERROR_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Letelica je u vazduhu # Order related errors STR_ERROR_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Nema više mesta za naredbe STR_ERROR_TOO_MANY_ORDERS :{WHITE}Previše naredbi STR_ERROR_CAN_T_INSERT_NEW_ORDER :{WHITE}Ne može se dodati nova naredba... -STR_ERROR_CAN_T_DELETE_THIS_ORDER :{WHITE}Ne može da se izbriše ova naredba... +STR_ERROR_CAN_T_DELETE_THIS_ORDER :{WHITE}Nije moguće obrisati naredbu... STR_ERROR_CAN_T_MODIFY_THIS_ORDER :{WHITE}Ne može da se izmeni ova naredba... STR_ERROR_CAN_T_MOVE_THIS_ORDER :{WHITE}Ne može da se pomeri ova naredba... -STR_ERROR_CAN_T_SKIP_ORDER :{WHITE}Ne može se preskočiti tekuća naredba... -STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Ne može da se preskoči označena naredba... +STR_ERROR_CAN_T_SKIP_ORDER :{WHITE}Nije moguće preskočiti tekuću naredbu... +STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Nije moguće preskočiti označenu naredbu... STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}vozilo ne može da ide na sve stanice STR_ERROR_CAN_T_ADD_ORDER :{WHITE}vozilo ne može da ide na tu stanicu STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}vozilo koje takođe ima ovu naredbu ne može da ide na tu stanicu +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... nemaju sva vozila iste naredbe +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... ne dele sva vozila naredbe STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Lista naredbi se ne može deliti... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Deljenje naredbi se ne može prekinuti... STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Lista naredbi se ne može kopirati... STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... previše udaljeno od prethodne destinacije -STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... letilica nema dometa +STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... letelica nema dovoljan domet + +# Extra messages which go on the third line of errors, explaining why orders failed # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Raspored se ne može dodeliti vozilu... @@ -5226,7 +5295,7 @@ STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}Ovo vozi STR_ERROR_TOO_MANY_SIGNS :{WHITE}... ima previše znakova STR_ERROR_CAN_T_PLACE_SIGN_HERE :{WHITE}Ovde je nemoguće postaviti znak... STR_ERROR_CAN_T_CHANGE_SIGN_NAME :{WHITE}Ime znaka se ne može promeniti... -STR_ERROR_CAN_T_DELETE_SIGN :{WHITE}Nemoguće je izbrisati znak... +STR_ERROR_CAN_T_DELETE_SIGN :{WHITE}Nije moguće obrisati znak... # Translatable comment for OpenTTD's desktop shortcut ###external 1 @@ -5308,7 +5377,7 @@ STR_INDUSTRY_NAME_WATER_SUPPLY :{G=muški}Izvor STR_INDUSTRY_NAME_WATER_TOWER :{G=muški}Vodotoranj STR_INDUSTRY_NAME_FACTORY_2 :{G=ženski}Fabrika STR_INDUSTRY_NAME_FARM_2 :{G=ženski}Farma -STR_INDUSTRY_NAME_LUMBER_MILL :{G=muški}Drvni kombinat +STR_INDUSTRY_NAME_LUMBER_MILL :{G=muški}Pilana STR_INDUSTRY_NAME_COTTON_CANDY_FOREST :{G=ženski}Šuma šećerne vune STR_INDUSTRY_NAME_CANDY_FACTORY :{G=ženski}Fabrika slatkiša STR_INDUSTRY_NAME_BATTERY_FARM :{G=ženski}Farma baterija @@ -5394,198 +5463,198 @@ STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_30_ELECTRIC :SH '30' (elektr STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_40_ELECTRIC :SH '40' (električna) STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_T_I_M_ELECTRIC :'T.I.M.' (električna) STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_ASIASTAR_ELECTRIC :'AsiaStar' (električna) -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PASSENGER_CAR :Putnička Kola -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_MAIL_VAN :Poštanski Vagon -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COAL_CAR :Vagon za Ugalj -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_OIL_TANKER :Cisterna za Naftu -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_LIVESTOCK_VAN :Vagon za Živu Stoku -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_GOODS_VAN :Vagon za Robu -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_GRAIN_HOPPER :Vagon za Žito -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_WOOD_TRUCK :Vagon za Drvo -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_IRON_ORE_HOPPER :Vagon za Rude gvožđa -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_STEEL_TRUCK :Vagon za Čelik -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_ARMORED_VAN :Oklopljeni Vagon -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FOOD_VAN :Vagon za Hranu -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PAPER_TRUCK :Vagon za Papir -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COPPER_ORE_HOPPER :Vagon za Rude bakra -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_WATER_TANKER :Cisterna za Vodu -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FRUIT_TRUCK :Vagon za Voće -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_RUBBER_TRUCK :Vagon za Kaučuk -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_SUGAR_TRUCK :Vagon za Šećer -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COTTON_CANDY_HOPPER :Vagon za Šećernu vunu -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_TOFFEE_HOPPER :Vagon za Karamele -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_BUBBLE_VAN :Vagon za Mehuriće -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COLA_TANKER :Cisterna za Kolu -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_CANDY_VAN :Vagon za Slatkiše -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_TOY_VAN :Vagon za Igračke -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_BATTERY_TRUCK :Vagon za Baterije -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FIZZY_DRINK_TRUCK :Cisterna za Gazirana pića -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PLASTIC_TRUCK :Vagon za Plastiku +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PASSENGER_CAR :Putnička kola +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_MAIL_VAN :Poštanski vagon +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COAL_CAR :Vagon za ugalj +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_OIL_TANKER :Cisterna za naftu +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_LIVESTOCK_VAN :Stočni vagon +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_GOODS_VAN :Robni vagon +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_GRAIN_HOPPER :Vagon za žitarice +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_WOOD_TRUCK :Vagon za drvo +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_IRON_ORE_HOPPER :Vagon za rude gvožđa +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_STEEL_TRUCK :Vagon za čelik +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_ARMORED_VAN :Oklopni vagon +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FOOD_VAN :Vagon za hranu +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PAPER_TRUCK :Vagon za papir +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COPPER_ORE_HOPPER :Vagon za rude bakra +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_WATER_TANKER :Cisterna za vodu +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FRUIT_TRUCK :Vagon za voće +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_RUBBER_TRUCK :Vagon za kaučuk +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_SUGAR_TRUCK :Vagon za šećer +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COTTON_CANDY_HOPPER :Vagon za šećernu vunu +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_TOFFEE_HOPPER :Vagon za karamele +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_BUBBLE_VAN :Vagon za mehuriće +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COLA_TANKER :Cisterna za kolu +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_CANDY_VAN :Vagon za slatkiše +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_TOY_VAN :Vagon za igračke +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_BATTERY_TRUCK :Vagon za baterije +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FIZZY_DRINK_TRUCK :Cisterna za gazirana pića +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PLASTIC_TRUCK :Vagon za plastiku STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_X2001_ELECTRIC :'X2001' (električna) -STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Električna) +STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (električna) STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_WIZZOWOW_Z99 :Wizzowow Z99 -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PASSENGER_CAR :Putnička Kola -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_MAIL_VAN :Poštanski Vagon -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COAL_CAR :Vagon za Ugalj -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_OIL_TANKER :Cisterna za Naftu -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_LIVESTOCK_VAN :Vagon za Živu Stoku -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_GOODS_VAN :Vagon za Robu -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_GRAIN_HOPPER :Vagon za Žitarice -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_WOOD_TRUCK :Vagon za Drva -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_IRON_ORE_HOPPER :Vagon za Rude Gvožđa -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_STEEL_TRUCK :Vagon za Čelik -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_ARMORED_VAN :Oklopljeni Vagon -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FOOD_VAN :Vagon za Hranu -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PAPER_TRUCK :Vagon za Papir -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COPPER_ORE_HOPPER :Vagon za Rude Bakra -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_WATER_TANKER :Cisterna za Vodu -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FRUIT_TRUCK :Vagon za Voće -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_RUBBER_TRUCK :Vagon za Kaučuk -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_SUGAR_TRUCK :Vagon za Šećer -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COTTON_CANDY_HOPPER :Vagon za Šećernu Vatu -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOFFEE_HOPPER :Vagon za Karamele -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_BUBBLE_VAN :Vagon za Balone -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COLA_TANKER :Cisterna za Kolu -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_CANDY_VAN :Vagon za Slatkiše -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOY_VAN :Vagon za Igračke -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_BATTERY_TRUCK :Vagon za Baterije -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FIZZY_DRINK_TRUCK :Vagon za Bezalkoholna Pića -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PLASTIC_TRUCK :Vagon za Plastiku -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV1_LEVIATHAN_ELECTRIC :{G=ženski}Lev1 'Leviathan' (Electrična) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV2_CYCLOPS_ELECTRIC :{G=ženski}Lev2 'Cyclops' (Električna) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV3_PEGASUS_ELECTRIC :{G=ženski}Lev3 'Pegasus' (Električna) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV4_CHIMAERA_ELECTRIC :{G=ženski}Lev4 'Chimaera' (Električna) +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PASSENGER_CAR :Putnička kola +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_MAIL_VAN :Poštanski vagon +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COAL_CAR :Vagon za ugalj +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_OIL_TANKER :Cisterna za naftu +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_LIVESTOCK_VAN :Stočni vagon +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_GOODS_VAN :Robni vagon +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_GRAIN_HOPPER :Vagon za žitarice +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_WOOD_TRUCK :Vagon za drvo +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_IRON_ORE_HOPPER :Vagon za rude gvožđa +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_STEEL_TRUCK :Vagon za čelik +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_ARMORED_VAN :Oklopni vagon +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FOOD_VAN :Vagon za hranu +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PAPER_TRUCK :Vagon za papir +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COPPER_ORE_HOPPER :Vagon za rude bakra +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_WATER_TANKER :Cisterna za vodu +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FRUIT_TRUCK :Vagon za voće +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_RUBBER_TRUCK :Vagon za kaučuk +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_SUGAR_TRUCK :Vagon za šećer +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COTTON_CANDY_HOPPER :Vagon za šećernu vatu +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOFFEE_HOPPER :Vagon za karamele +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_BUBBLE_VAN :Vagon za mehuriće +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COLA_TANKER :Cisterna za kolu +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_CANDY_VAN :Vagon za slatkiše +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOY_VAN :Vagon za igračke +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_BATTERY_TRUCK :Vagon za baterije +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FIZZY_DRINK_TRUCK :Vagon za gazirana pića +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PLASTIC_TRUCK :Vagon za plastiku +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV1_LEVIATHAN_ELECTRIC :{G=ženski}Lev1 'Leviathan' (električna) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV2_CYCLOPS_ELECTRIC :{G=ženski}Lev2 'Cyclops' (električna) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV3_PEGASUS_ELECTRIC :{G=ženski}Lev3 'Pegasus' (električna) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV4_CHIMAERA_ELECTRIC :{G=ženski}Lev4 'Chimaera' (električna) STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PASSENGER_CAR :Putnička Kola -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_MAIL_VAN :Poštanski Vagon -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COAL_CAR :Vagon za Ugalj -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_OIL_TANKER :Cisterna za Naftu -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_LIVESTOCK_VAN :Vagon za Živu Stoku -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_GOODS_VAN :Vagon za Robu -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_GRAIN_HOPPER :Vagon za Žitarice -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_WOOD_TRUCK :Vagon za Drva -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_IRON_ORE_HOPPER :Vagon za Rude Gvožđa -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_STEEL_TRUCK :Vagon za Čelik -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_ARMORED_VAN :Oklopljeni Vagon -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FOOD_VAN :Vagon za Hranu -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PAPER_TRUCK :Vagon za Papir -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COPPER_ORE_HOPPER :Vagon za Rude Bakra -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_WATER_TANKER :Cisterna za Vodu -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FRUIT_TRUCK :Vagon za Voće -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_RUBBER_TRUCK :Vagon za Kaučuk -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_SUGAR_TRUCK :Vagon za Šećer -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COTTON_CANDY_HOPPER :Vagon za Šećernu Vunu -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_TOFFEE_HOPPER :Vagon za Karamele -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_BUBBLE_VAN :Vagon za Balone -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COLA_TANKER :Cisterna za Kolu -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_CANDY_VAN :Vagon za Slatkiš -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_TOY_VAN :Vagon za Igračke -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_BATTERY_TRUCK :Vagon za Baterije -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FIZZY_DRINK_TRUCK :Vagon za Bezalkoholna Pića -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PLASTIC_TRUCK :Vagon za Plastiku +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PASSENGER_CAR :Putnička kola +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_MAIL_VAN :Poštanski vagon +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COAL_CAR :Vagon za ugalj +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_OIL_TANKER :Cisterna za naftu +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_LIVESTOCK_VAN :Stočni vagon +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_GOODS_VAN :Robni vagon +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_GRAIN_HOPPER :Vagon za žitarice +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_WOOD_TRUCK :Vagon za drvo +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_IRON_ORE_HOPPER :Vagon za rude gvožđa +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_STEEL_TRUCK :Vagon za čelik +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_ARMORED_VAN :Oklopni vagon +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FOOD_VAN :Vagon za hranu +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PAPER_TRUCK :Vagon za papir +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COPPER_ORE_HOPPER :Vagon za rude bakra +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_WATER_TANKER :Cisterna za vodu +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FRUIT_TRUCK :Vagon za voće +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_RUBBER_TRUCK :Vagon za kaučuk +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_SUGAR_TRUCK :Vagon za šećer +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COTTON_CANDY_HOPPER :Vagon za šećernu vunu +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_TOFFEE_HOPPER :Vagon za karamele +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_BUBBLE_VAN :Vagon za mehuriće +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COLA_TANKER :Cisterna za kolu +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_CANDY_VAN :Vagon za slatkiše +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_TOY_VAN :Vagon za igračke +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_BATTERY_TRUCK :Vagon za baterije +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FIZZY_DRINK_TRUCK :Vagon za gazirana pića +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PLASTIC_TRUCK :Vagon za plastiku ###length 88 -STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_REGAL_BUS :MPS Regal Autobus -STR_VEHICLE_NAME_ROAD_VEHICLE_HEREFORD_LEOPARD_BUS :Hereford Leopard Autobus -STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_BUS :Foster Autobus +STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_REGAL_BUS :MPS Regal autobus +STR_VEHICLE_NAME_ROAD_VEHICLE_HEREFORD_LEOPARD_BUS :Hereford Leopard autobus +STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_BUS :Foster autobus STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_MKII_SUPERBUS :Foster MkII Superbus -STR_VEHICLE_NAME_ROAD_VEHICLE_PLODDYPHUT_MKI_BUS :Ploddyphut MkI Autobus -STR_VEHICLE_NAME_ROAD_VEHICLE_PLODDYPHUT_MKII_BUS :Ploddyphut MkII Autobus -STR_VEHICLE_NAME_ROAD_VEHICLE_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII Autobus -STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_COAL_TRUCK :Balogh Kamion za ugalj -STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_COAL_TRUCK :Uhl Kamion za ugalj -STR_VEHICLE_NAME_ROAD_VEHICLE_DW_COAL_TRUCK :DW Kamion za ugalj -STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_MAIL_TRUCK :MPS Kamion za poštu -STR_VEHICLE_NAME_ROAD_VEHICLE_REYNARD_MAIL_TRUCK :Reynard Poštanski Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_PERRY_MAIL_TRUCK :Perry Poštanski Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_MAIL_TRUCK :MightyMover Poštanski Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_MAIL_TRUCK :Powernaught Poštanski Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_MAIL_TRUCK :Wizzowow Poštanski Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_WITCOMBE_OIL_TANKER :Witcombe Naftna Cisterna -STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_OIL_TANKER :Foster Naftna Cisterna -STR_VEHICLE_NAME_ROAD_VEHICLE_PERRY_OIL_TANKER :Perry Naftna Cisterna -STR_VEHICLE_NAME_ROAD_VEHICLE_TALBOTT_LIVESTOCK_VAN :Talbott Stočni Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_LIVESTOCK_VAN :Uhl Stočni Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_LIVESTOCK_VAN :Foster Stočni Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_GOODS_TRUCK :Balogh Robni Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_CRAIGHEAD_GOODS_TRUCK :Craighead Robni Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_GOSS_GOODS_TRUCK :Goss Robni Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_HEREFORD_GRAIN_TRUCK :Hereford Kamion za žitarice -STR_VEHICLE_NAME_ROAD_VEHICLE_THOMAS_GRAIN_TRUCK :Thomas Kamion za žitarice -STR_VEHICLE_NAME_ROAD_VEHICLE_GOSS_GRAIN_TRUCK :Goss Kamion za žitarice -STR_VEHICLE_NAME_ROAD_VEHICLE_WITCOMBE_WOOD_TRUCK :Witcombe Kamion za drvo -STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_WOOD_TRUCK :Foster Kamion za drvo -STR_VEHICLE_NAME_ROAD_VEHICLE_MORELAND_WOOD_TRUCK :Moreland Kamion za drvo -STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_IRON_ORE_TRUCK :MPS Kamion za rude gvožđa -STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_IRON_ORE_TRUCK :Uhl Kamion za rude gvožđa -STR_VEHICLE_NAME_ROAD_VEHICLE_CHIPPY_IRON_ORE_TRUCK :Chippy Kamion za rude gvožđa -STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_STEEL_TRUCK :Balogh Kamion za čelik -STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_STEEL_TRUCK :Uhl Kamion za čelik -STR_VEHICLE_NAME_ROAD_VEHICLE_KELLING_STEEL_TRUCK :Kelling Kamion za čelik -STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_ARMORED_TRUCK :Balogh Oklopljeni Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_ARMORED_TRUCK :Uhl Oklopljeni Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_ARMORED_TRUCK :Foster Oklopljeni Kamion -STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_FOOD_VAN :Foster Kamion za hranu -STR_VEHICLE_NAME_ROAD_VEHICLE_PERRY_FOOD_VAN :Perry Kamion za hranu -STR_VEHICLE_NAME_ROAD_VEHICLE_CHIPPY_FOOD_VAN :Chippy Kamion za hranu -STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_PAPER_TRUCK :Uhl Kamion za papir -STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_PAPER_TRUCK :Balogh Kamion za papir -STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_PAPER_TRUCK :MPS Kamion za papir -STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_COPPER_ORE_TRUCK :MPS Kamion za rude bakra -STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_COPPER_ORE_TRUCK :Uhl Kamion za rude bakra -STR_VEHICLE_NAME_ROAD_VEHICLE_GOSS_COPPER_ORE_TRUCK :Goss Kamion za rude bakra -STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_WATER_TANKER :Uhl Cisterna za vodu -STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_WATER_TANKER :Balogh Cisterna za vodu -STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_WATER_TANKER :MPS Cisterna za vodu -STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_FRUIT_TRUCK :Balogh Kamion za voće -STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_FRUIT_TRUCK :Uhl Kamion za voće -STR_VEHICLE_NAME_ROAD_VEHICLE_KELLING_FRUIT_TRUCK :Kelling Kamion za voće -STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_RUBBER_TRUCK :Balogh Kamion za kaučuk -STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_RUBBER_TRUCK :Uhl Kamion za kaučuk -STR_VEHICLE_NAME_ROAD_VEHICLE_RMT_RUBBER_TRUCK :RMT Kamion za kaučuk -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover Kamion za šećer -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_SUGAR_TRUCK :Powernaught Kamion za šećer -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_SUGAR_TRUCK :Wizzowow Kamion za šećer -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_COLA_TRUCK :MightyMover Kamion za kolu -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_COLA_TRUCK :Powernaught Kamion za kolu -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_COLA_TRUCK :Wizzowow Kamion za kolu -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_COTTON_CANDY :MightyMover Kamion za šećernu vunu -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_COTTON_CANDY :Powernaught Kamion za šećernu vunu -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow Kamion za šećernu vunu -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover Kamion za karamele -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_TOFFEE_TRUCK :Powernaught Kamion za karamele -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_TOFFEE_TRUCK :Wizzowow Kamion za karamele -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_TOY_VAN :MightyMover Kamion za igračke -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_TOY_VAN :Powernaught Kamion za igračke -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_TOY_VAN :Wizzowow Kamion za igračke -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_CANDY_TRUCK :MightyMover Kamion za slatkiše -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_CANDY_TRUCK :Powernaught Kamion za slatkiše -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_CANDY_TRUCK :Wizzowow Kamion za slatkiše -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_BATTERY_TRUCK :MightyMover Kamion za baterije -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_BATTERY_TRUCK :Powernaught Kamion za baterije -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_BATTERY_TRUCK :Wizzowow Kamion za baterije -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_FIZZY_DRINK :MightyMover Kamion za gazirana pića -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_FIZZY_DRINK :Powernaught Kamion za gazirana pića -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow Kamion za gazirana pića -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover Kamion za plastiku -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_PLASTIC_TRUCK :Powernaught Kamion za plastiku -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_PLASTIC_TRUCK :Wizzowow Kamion za plastiku -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover Kamion za balone -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_BUBBLE_TRUCK :Powernaught Kamion za balone -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_BUBBLE_TRUCK :Wizzowow Kamion za balone +STR_VEHICLE_NAME_ROAD_VEHICLE_PLODDYPHUT_MKI_BUS :Ploddyphut MkI autobus +STR_VEHICLE_NAME_ROAD_VEHICLE_PLODDYPHUT_MKII_BUS :Ploddyphut MkII autobus +STR_VEHICLE_NAME_ROAD_VEHICLE_PLODDYPHUT_MKIII_BUS :Ploddyphut MkIII autobus +STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_COAL_TRUCK :Balogh kamion za ugalj +STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_COAL_TRUCK :Uhl kamion za ugalj +STR_VEHICLE_NAME_ROAD_VEHICLE_DW_COAL_TRUCK :DW kamion za ugalj +STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_MAIL_TRUCK :MPS kamion za poštu +STR_VEHICLE_NAME_ROAD_VEHICLE_REYNARD_MAIL_TRUCK :Reynard poštanski kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_PERRY_MAIL_TRUCK :Perry poštanski kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_MAIL_TRUCK :MightyMover poštanski kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_MAIL_TRUCK :Powernaught poštanski kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_MAIL_TRUCK :Wizzowow poštanski kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_WITCOMBE_OIL_TANKER :Witcombe naftna cisterna +STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_OIL_TANKER :Foster naftna cisterna +STR_VEHICLE_NAME_ROAD_VEHICLE_PERRY_OIL_TANKER :Perry naftna cisterna +STR_VEHICLE_NAME_ROAD_VEHICLE_TALBOTT_LIVESTOCK_VAN :Talbott stočni kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_LIVESTOCK_VAN :Uhl stočni kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_LIVESTOCK_VAN :Foster stočni kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_GOODS_TRUCK :Balogh robni kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_CRAIGHEAD_GOODS_TRUCK :Craighead robni kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_GOSS_GOODS_TRUCK :Goss robni kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_HEREFORD_GRAIN_TRUCK :Hereford kamion za žitarice +STR_VEHICLE_NAME_ROAD_VEHICLE_THOMAS_GRAIN_TRUCK :Thomas kamion za žitarice +STR_VEHICLE_NAME_ROAD_VEHICLE_GOSS_GRAIN_TRUCK :Goss kamion za žitarice +STR_VEHICLE_NAME_ROAD_VEHICLE_WITCOMBE_WOOD_TRUCK :Witcombe kamion za drvo +STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_WOOD_TRUCK :Foster kamion za drvo +STR_VEHICLE_NAME_ROAD_VEHICLE_MORELAND_WOOD_TRUCK :Moreland kamion za drvo +STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_IRON_ORE_TRUCK :MPS kamion za rude gvožđa +STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_IRON_ORE_TRUCK :Uhl kamion za rude gvožđa +STR_VEHICLE_NAME_ROAD_VEHICLE_CHIPPY_IRON_ORE_TRUCK :Chippy kamion za rude gvožđa +STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_STEEL_TRUCK :Balogh kamion za čelik +STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_STEEL_TRUCK :Uhl kamion za čelik +STR_VEHICLE_NAME_ROAD_VEHICLE_KELLING_STEEL_TRUCK :Kelling kamion za čelik +STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_ARMORED_TRUCK :Balogh oklopni kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_ARMORED_TRUCK :Uhl oklopni kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_ARMORED_TRUCK :Foster oklopni kamion +STR_VEHICLE_NAME_ROAD_VEHICLE_FOSTER_FOOD_VAN :Foster kamion za hranu +STR_VEHICLE_NAME_ROAD_VEHICLE_PERRY_FOOD_VAN :Perry kamion za hranu +STR_VEHICLE_NAME_ROAD_VEHICLE_CHIPPY_FOOD_VAN :Chippy kamion za hranu +STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_PAPER_TRUCK :Uhl kamion za papir +STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_PAPER_TRUCK :Balogh kamion za papir +STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_PAPER_TRUCK :MPS kamion za papir +STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_COPPER_ORE_TRUCK :MPS kamion za rude bakra +STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_COPPER_ORE_TRUCK :Uhl kamion za rude bakra +STR_VEHICLE_NAME_ROAD_VEHICLE_GOSS_COPPER_ORE_TRUCK :Goss kamion za rude bakra +STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_WATER_TANKER :Uhl cisterna za vodu +STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_WATER_TANKER :Balogh cisterna za vodu +STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_WATER_TANKER :MPS cisterna za vodu +STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_FRUIT_TRUCK :Balogh kamion za voće +STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_FRUIT_TRUCK :Uhl kamion za voće +STR_VEHICLE_NAME_ROAD_VEHICLE_KELLING_FRUIT_TRUCK :Kelling kamion za voće +STR_VEHICLE_NAME_ROAD_VEHICLE_BALOGH_RUBBER_TRUCK :Balogh kamion za kaučuk +STR_VEHICLE_NAME_ROAD_VEHICLE_UHL_RUBBER_TRUCK :Uhl kamion za kaučuk +STR_VEHICLE_NAME_ROAD_VEHICLE_RMT_RUBBER_TRUCK :RMT kamion za kaučuk +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_SUGAR_TRUCK :MightyMover kamion za šećer +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_SUGAR_TRUCK :Powernaught kamion za šećer +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_SUGAR_TRUCK :Wizzowow kamion za šećer +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_COLA_TRUCK :MightyMover kamion za kolu +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_COLA_TRUCK :Powernaught kamion za kolu +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_COLA_TRUCK :Wizzowow kamion za kolu +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_COTTON_CANDY :MightyMover kamion za šećernu vunu +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_COTTON_CANDY :Powernaught kamion za šećernu vunu +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_COTTON_CANDY_TRUCK :Wizzowow kamion za šećernu vunu +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_TOFFEE_TRUCK :MightyMover kamion za karamele +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_TOFFEE_TRUCK :Powernaught kamion za karamele +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_TOFFEE_TRUCK :Wizzowow kamion za karamele +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_TOY_VAN :MightyMover kamion za igračke +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_TOY_VAN :Powernaught kamion za igračke +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_TOY_VAN :Wizzowow kamion za igračke +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_CANDY_TRUCK :MightyMover kamion za slatkiše +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_CANDY_TRUCK :Powernaught kamion za slatkiše +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_CANDY_TRUCK :Wizzowow kamion za slatkiše +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_BATTERY_TRUCK :MightyMover kamion za baterije +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_BATTERY_TRUCK :Powernaught kamion za baterije +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_BATTERY_TRUCK :Wizzowow kamion za baterije +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_FIZZY_DRINK :MightyMover kamion za gazirana pića +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_FIZZY_DRINK :Powernaught kamion za gazirana pića +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_FIZZY_DRINK_TRUCK :Wizzowow kamion za gazirana pića +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_PLASTIC_TRUCK :MightyMover kamion za plastiku +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_PLASTIC_TRUCK :Powernaught kamion za plastiku +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_PLASTIC_TRUCK :Wizzowow kamion za plastiku +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_BUBBLE_TRUCK :MightyMover kamion za mehuriće +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_BUBBLE_TRUCK :Powernaught kamion za mehuriće +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_BUBBLE_TRUCK :Wizzowow kamion za mehuriće ###length 11 -STR_VEHICLE_NAME_SHIP_MPS_OIL_TANKER :MPS Naftni Tanker -STR_VEHICLE_NAME_SHIP_CS_INC_OIL_TANKER :CS-Inc. Naftni Tanker -STR_VEHICLE_NAME_SHIP_MPS_PASSENGER_FERRY :MPS Putnički Feribot -STR_VEHICLE_NAME_SHIP_FFP_PASSENGER_FERRY :FFP Putnički Feribot -STR_VEHICLE_NAME_SHIP_BAKEWELL_300_HOVERCRAFT :Bakewell 300 Hoverkraft -STR_VEHICLE_NAME_SHIP_CHUGGER_CHUG_PASSENGER :Chugger-Chug Putnički Feribot -STR_VEHICLE_NAME_SHIP_SHIVERSHAKE_PASSENGER_FERRY :Shivershake Putnički Feribot -STR_VEHICLE_NAME_SHIP_YATE_CARGO_SHIP :Yate Teretni brod -STR_VEHICLE_NAME_SHIP_BAKEWELL_CARGO_SHIP :Bakewell Teretni brod -STR_VEHICLE_NAME_SHIP_MIGHTYMOVER_CARGO_SHIP :MightyMover Teretni brod -STR_VEHICLE_NAME_SHIP_POWERNAUT_CARGO_SHIP :Powernaut Teretni brod +STR_VEHICLE_NAME_SHIP_MPS_OIL_TANKER :MPS naftni tanker +STR_VEHICLE_NAME_SHIP_CS_INC_OIL_TANKER :CS-Inc. naftni tanker +STR_VEHICLE_NAME_SHIP_MPS_PASSENGER_FERRY :MPS putnički trajekt +STR_VEHICLE_NAME_SHIP_FFP_PASSENGER_FERRY :FFP putnički trajekt +STR_VEHICLE_NAME_SHIP_BAKEWELL_300_HOVERCRAFT :Bakewell 300 hoverkraft +STR_VEHICLE_NAME_SHIP_CHUGGER_CHUG_PASSENGER :Chugger-Chug putnički trajekt +STR_VEHICLE_NAME_SHIP_SHIVERSHAKE_PASSENGER_FERRY :Shivershake putnički trajekt +STR_VEHICLE_NAME_SHIP_YATE_CARGO_SHIP :Yate teretni brod +STR_VEHICLE_NAME_SHIP_BAKEWELL_CARGO_SHIP :Bakewell teretni brod +STR_VEHICLE_NAME_SHIP_MIGHTYMOVER_CARGO_SHIP :MightyMover teretni brod +STR_VEHICLE_NAME_SHIP_POWERNAUT_CARGO_SHIP :Powernaut teretni brod ###length 41 STR_VEHICLE_NAME_AIRCRAFT_SAMPSON_U52 :Sampson U52 @@ -5613,7 +5682,7 @@ STR_VEHICLE_NAME_AIRCRAFT_AIRTAXI_A33 :Airtaxi A33 STR_VEHICLE_NAME_AIRCRAFT_YATE_AEROSPACE_YAE46 :Yate Aerospace YAe46 STR_VEHICLE_NAME_AIRCRAFT_DINGER_100 :Dinger 100 STR_VEHICLE_NAME_AIRCRAFT_AIRTAXI_A34_1000 :AirTaxi A34-1000 -STR_VEHICLE_NAME_AIRCRAFT_YATE_Z_SHUTTLE :Yate Z-Šatl +STR_VEHICLE_NAME_AIRCRAFT_YATE_Z_SHUTTLE :Yate Z-šatl STR_VEHICLE_NAME_AIRCRAFT_KELLING_K1 :Kelling K1 STR_VEHICLE_NAME_AIRCRAFT_KELLING_K6 :Kelling K6 STR_VEHICLE_NAME_AIRCRAFT_KELLING_K7 :Kelling K7 @@ -5626,9 +5695,9 @@ STR_VEHICLE_NAME_AIRCRAFT_PLODDYPHUT_500 :Ploddyphut 500 STR_VEHICLE_NAME_AIRCRAFT_FLASHBANG_X1 :Flashbang X1 STR_VEHICLE_NAME_AIRCRAFT_JUGGERPLANE_M1 :Juggerplane M1 STR_VEHICLE_NAME_AIRCRAFT_FLASHBANG_WIZZER :Flashbang Wizzer -STR_VEHICLE_NAME_AIRCRAFT_TRICARIO_HELICOPTER :Tricario Helikopter -STR_VEHICLE_NAME_AIRCRAFT_GURU_X2_HELICOPTER :Guru X2 Helikopter -STR_VEHICLE_NAME_AIRCRAFT_POWERNAUT_HELICOPTER :Powernaut Helikopter +STR_VEHICLE_NAME_AIRCRAFT_TRICARIO_HELICOPTER :Tricario helikopter +STR_VEHICLE_NAME_AIRCRAFT_GURU_X2_HELICOPTER :Guru X2 helikopter +STR_VEHICLE_NAME_AIRCRAFT_POWERNAUT_HELICOPTER :Powernaut helikopter ##id 0x8800 # Formatting of some strings diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 8b2e95be897fc..83a395d774627 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP} STR_UNITS_POWER_METRIC :{COMMA}{NBSP}匹马力 STR_UNITS_POWER_SI :{COMMA}{NBSP}千瓦 +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}匹/英吨 +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}匹/吨 +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}匹/兆克 +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}马力/英吨 +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}马力/吨 +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}马力/兆克 +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}千瓦/英吨 +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}千瓦/吨 +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}瓦/千克 + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}英吨 STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}吨 STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}千克 @@ -225,9 +235,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP} STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}米 # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}过滤字串: -STR_LIST_FILTER_OSKTITLE :{BLACK}输入过滤器字符串 -STR_LIST_FILTER_TOOLTIP :{BLACK}输入用以过滤此列表的关键词 +STR_LIST_FILTER_TITLE :{BLACK}关键字词: +STR_LIST_FILTER_OSKTITLE :{BLACK}输入关键字筛选 +STR_LIST_FILTER_TOOLTIP :{BLACK}输入关键字以筛选查找此列表 STR_TOOLTIP_GROUP_ORDER :{BLACK}选择分组次序 STR_TOOLTIP_SORT_ORDER :{BLACK}选择排序方法 (降序/升序) @@ -376,9 +386,9 @@ 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_PLANT_TREES :{BLACK}植树。Shift显示预计花费。 +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}植树。按 Ctrl 沿对角线建造,按 Shift 显示预计花费。 STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}放置标志 -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}放置物体,按住Shift键操作显示预计费用 +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}放置物体,按住Ctrl可沿对角线选择区域,按住Shift键操作显示预计费用 # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :退出 # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :游戏选项 STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :设置 -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI / 游戏脚本设定 +STR_SETTINGS_MENU_AI_SETTINGS :AI 设置 +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :游戏脚本设置 STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF 设置 STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :透明选项 STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :显示城镇名称 @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :印度卢布( STR_GAME_OPTIONS_CURRENCY_IDR :印尼盾 (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :马来西亚林吉特 (MYR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}选择城镇名称的命名风格 - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :英国 (原始的) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :法国 -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :德国 -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :英国 (增强的) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :美式拉丁 -STR_GAME_OPTIONS_TOWN_NAME_SILLY :搞笑地名 -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :瑞典 -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :荷兰 -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :芬兰 -STR_GAME_OPTIONS_TOWN_NAME_POLISH :波兰 -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :斯洛伐克 -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :挪威 -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :匈牙利 -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :澳大利亚 -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :罗马尼亚 -STR_GAME_OPTIONS_TOWN_NAME_CZECH :捷克 -STR_GAME_OPTIONS_TOWN_NAME_SWISS :瑞士 -STR_GAME_OPTIONS_TOWN_NAME_DANISH :丹麦 -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :土耳其 -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :意大利 -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :加泰罗尼亚 - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}自动保存 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}选择自动保存的周期 @@ -1027,21 +1008,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}点击 STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}使用中的驱动程序: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}界面大小 -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}选择使用的界面元素大小 +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}界面大小 +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}拖动滑块以设置界面大小。按住 Ctrl 进行连续调整 +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}自动检测大小 +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}选中此框可自动检测界面大小 -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(自动检测) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :正常大小 -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :两倍大小 -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :四倍大小 +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}适应边框大小 +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}选中此框使边框大小随界面大小而缩放 -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}字体大小 -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}选择此字体大小 - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(自动检测) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :正常 -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :两倍大小 -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :四倍大小 +STR_GAME_OPTIONS_GUI_SCALE_1X :1倍 +STR_GAME_OPTIONS_GUI_SCALE_2X :2倍 +STR_GAME_OPTIONS_GUI_SCALE_3X :3倍 +STR_GAME_OPTIONS_GUI_SCALE_4X :4倍 +STR_GAME_OPTIONS_GUI_SCALE_5X :5倍 STR_GAME_OPTIONS_GRAPHICS :{BLACK}图像 @@ -1093,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}预览 STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 英磅(£) 兑换自定义货币的数量 STR_CURRENCY_CHANGE_PARAMETER :{BLACK}改变当前的货币参数 -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}最大竞争对手个数:{ORANGE}{COMMA} - STR_NONE :没有 STR_FUNDING_ONLY :不生成 STR_MINIMAL :每种仅一个 @@ -1144,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :温带景观 +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :寒带景观 +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :沙漠景观 +STR_CLIMATE_TOYLAND_LANDSCAPE :奇幻景观 + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :非常平整 STR_TERRAIN_TYPE_FLAT :平整 @@ -1163,7 +1146,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}无合 # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}设置 -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}关键字过滤: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}关键字搜索: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}展开全部 STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}关闭全部 STR_CONFIG_SETTING_RESET_ALL :{BLACK}重置所有值 @@ -1223,6 +1206,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :右侧 STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :最大初始贷款: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :公司最大贷款额(不考虑通货膨胀的影响) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :无贷款 {RED}需要有游戏脚本以提供初始资金 STR_CONFIG_SETTING_INTEREST_RATE :贷款利率: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :贷款利率;如果通货膨胀启用,将同时影响通货膨胀率。 @@ -1449,6 +1435,8 @@ 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_SHOW_CARGO_IN_LISTS :在列表窗口中显示车辆可以携带的货物 {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :如果启用,车辆的可运输负载将出现在车辆列表的上方 STR_CONFIG_SETTING_LANDSCAPE :景观: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :此设置决定基本的游戏场景、有什么货物可供运输,以及城镇发展的所需条件。然而,NewGRF 及游戏脚本可以比此设置更加细致地设置游戏场景 @@ -1503,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :增强的 STR_CONFIG_SETTING_ROAD_SIDE :道路车辆: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :选择道路通行方向 +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :左侧通行 +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :右侧通行 + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :高度图旋转:{STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :逆时针 @@ -1936,9 +1928,9 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :容许系统用 STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :当刷新货物分配图时,系统会创建一条线程。此处设定的数值即该线程的持续时间。{}赋值越小,线程越有可能在应当停止的时候还未完成,游戏会暂停运作至线程完成工作。相反,赋值越大,则货物分配功能需要较长时间反映线路网变动的影晌。 STR_CONFIG_SETTING_DISTRIBUTION_PAX :乗客分配方式:{STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的乗客数量與乙站往甲站的乗客数量大致相同。“不对称”指任何一站往另一站的乗客数量皆由系统随意决定。“手动”指系统不会自动分配乗客的目的地。 +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的乗客数量与乙站往甲站的乘客数量大致相同。“不对称”指任何一站往另一站的乘客数量皆由系统随意决定。“手动”指系统不会自动分配乘客的目的地。 STR_CONFIG_SETTING_DISTRIBUTION_MAIL :邮件分配方式:{STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的邮件数量與乙站往甲站的邮件数量大致相同。“不对称”指任何一站往另一站的邮件数量皆由系统随意决定。“手动”指系统不会自动分配邮件的目的地。 +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的邮件数量与乙站往甲站的邮件数量大致相同。“不对称”指任何一站往另一站的邮件数量皆由系统随意决定。“手动”指系统不会自动分配邮件的目的地。 STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :装甲货物分配方式:{STRING} STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :“装甲货物”包括温带场景的“贵重品”、寒带场景的“金块”及沙漠场景的“钻石”。使用 NewGRF 可能会改变以上设置。{} 假设有交通路线连接甲、乙两站。“对称”指甲站往乙站的货物数量与乙站往甲站的装甲货物数量大致相同。“不对称”指任何一站往另一站的装甲货物数量皆由系统随意决定。“手动”指系统不会自动分配装甲货物的目的地。{} 建议在温带及沙漠场景使用“对称”,因为银行之间会相互发送贵重品或钻石;在寒带则应使用“不对称”,因为银行不会把金块送回金矿。 STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :其他货物分配方式:{STRING} @@ -2037,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :遇到红灯时 STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :当列车在信号灯前长时间等待时,允许掉头 ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(推荐) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(推荐) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}改变设置值 @@ -2080,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK}高分 STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}设置 STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF 设置 STR_INTRO_ONLINE_CONTENT :{BLACK}在线查找扩展包 -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI / 脚本 设定 +STR_INTRO_AI_SETTINGS :{BLACK}AI 设置 +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}游戏脚本设置 STR_INTRO_QUIT :{BLACK}退出 STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}开始新游戏. 单击的同时按住Ctrl以跳过地图设置界面 @@ -2100,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}显示 STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}显示设置 STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}显示GRF设定 STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}连接服务器并查找扩展包 -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}查看AI和脚本设定 +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}显示AI设置 +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}显示游戏脚本设置 STR_INTRO_TOOLTIP_QUIT :{BLACK}退出 'OpenTTD' STR_INTRO_BASESET :{BLACK}当前选定的基础图形组缺少 {NUM} 个子画面。请检查基础图形组有无更新。 @@ -2132,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}改变 STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}改变当前年份 STR_CHEAT_SETUP_PROD :{LTBLUE}开启可调整产量模式:{ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :温带景观 -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :寒带景观 -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :沙漠景观 -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :奇幻景观 - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} 的色彩方案 @@ -2370,7 +2358,6 @@ 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_CLIENT_COMPANY_COUNT :{BLACK}{NUM}个客户端 / {NUM}个公司 # Matches ConnectionType ###length 5 @@ -2497,13 +2484,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :等待货物分 STR_NETWORK_MESSAGE_CLIENT_LEAVING :离开 STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} 已加入游戏 -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} 加入了游戏 (Client #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} 已加入 #{2:NUM} 公司 +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} 加入了游戏 (Client #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} 已加入 #{2:NUM} 公司 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_CLIENT_COMPANY_NEW :*** {0:STRING} 成立了新公司 (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} 已离开游戏 ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} 已更改姓名为 {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} 给予 {1:STRING} {2:CURRENCY_LONG} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} 给予 {1:STRING} {2:CURRENCY_LONG} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}服务器关闭了进程 STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}服务器正在重新启动。{}请等待…… STR_NETWORK_MESSAGE_KICKED :*** {STRING} 被踢出服务器。原因:({STRING}) @@ -2617,6 +2604,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}饱和 STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}超载 +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}每月有{CARGO_LONG}待从{STATION}运输到{STATION}(运载能力的{COMMA}%){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}有{CARGO_LONG}要运回(运载能力的{COMMA}%) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}平均行驶时间: {NUM}{NBSP}天 + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}显示覆盖区域 STR_STATION_BUILD_COVERAGE_OFF :{BLACK}关闭 @@ -2625,6 +2617,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}不显 STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}显示可以覆盖的区域 STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}接受:{GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}供给: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}维护成本: {GOLD}{CURRENCY_SHORT}/年 # Join station window STR_JOIN_STATION_CAPTION :{WHITE}合并车站 @@ -2707,8 +2700,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}增加 STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}选择铁路桥 STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}选择公路桥梁 STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}选择桥梁 - 点击选择喜欢的桥梁进行建设 -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :钢制悬索 STR_BRIDGE_NAME_GIRDER_STEEL :钢制桁桥 STR_BRIDGE_NAME_CANTILEVER_STEEL :钢制悬臂 @@ -2812,11 +2807,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}景观 STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}降低地块的一角 STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}升高地块的一角 STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}拉平地面 -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}购买土地以备将来使用,按住 Shift 键操作可以显示所需资金 +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}购买土地以备将来使用。按 Ctrl 键可选择对角线区域。按 Shift 键可以预览所需资金。 # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}物体选单 -STR_OBJECT_BUILD_TOOLTIP :{BLACK}选择建设项目. 按住SHIFT键建设可以显示建设费用 +STR_OBJECT_BUILD_TOOLTIP :{BLACK}选择建设项目.。按住Ctrl可沿对角线选择区域。按住Shift键建设可以显示建设费用 STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}选择要建造的物件类型 STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}物件预览 STR_OBJECT_BUILD_SIZE :{BLACK}大小: {GOLD}{NUM} x {NUM} 瓦 @@ -2828,7 +2823,7 @@ STR_OBJECT_CLASS_TRNS :发射机 STR_PLANT_TREE_CAPTION :{WHITE}树木 STR_PLANT_TREE_TOOLTIP :{BLACK}选择要种植的树木类型。如果格子内已经有树木,将种植随机类型的树木 STR_TREES_RANDOM_TYPE :{BLACK}随机类型的树木 -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}种植随机类型的树木,按住 Shift 键可以显示所需资金 +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}种植随机类型的树木。按 Ctrl 键沿对角线建造,按住 Shift 键可以显示所需资金 STR_TREES_RANDOM_TREES_BUTTON :{BLACK}随机树木 STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}随机地种植一些树木 STR_TREES_MODE_NORMAL_BUTTON :{BLACK}正常 @@ -2860,6 +2855,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}随机 STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}随机新增一个城镇 STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}大量随机城镇 STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}在地图上随机创建大量城镇 +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}扩展所有城镇 +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}使所有城镇略微成长 STR_FOUND_TOWN_NAME_TITLE :{YELLOW}城镇名称: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}输入城镇名称 @@ -3124,7 +3121,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}游戏 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_FILTER_TITLE :{BLACK}过滤字串: +STR_SAVELOAD_FILTER_TITLE :{BLACK}关键字词: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}覆盖文件 STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}你确定要覆盖已有文件吗? STR_SAVELOAD_DIRECTORY :{STRING} (目录) @@ -3138,6 +3135,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}地图 STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}选择地图尺寸(单位:格)。可用的数值会略小。 STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}城镇数量: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}城镇名称: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}选择城镇名称的命名风格 STR_MAPGEN_DATE :{BLACK}日期: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}工业数量: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}最高峰: @@ -3151,13 +3150,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}沙漠 STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}增加 10% 沙漠覆盖率 STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}减少 10% 沙漠覆盖率 STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}生成地形: STR_MAPGEN_TERRAIN_TYPE :{BLACK}地形特点: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}海洋面积: +STR_MAPGEN_SEA_LEVEL :{BLACK}海洋面积: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}河流数量: STR_MAPGEN_SMOOTHNESS :{BLACK}平滑度: STR_MAPGEN_VARIETY :{BLACK}多样的分发: STR_MAPGEN_GENERATE :{WHITE}生成 +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF设置 +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}显示NewGRF设置 +STR_MAPGEN_AI_SETTINGS :{BLACK}AI 设置 +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}显示AI设置 +STR_MAPGEN_GS_SETTINGS :{BLACK}游戏脚本设置 +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}显示游戏脚本设置 + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :英国 (原始的) +STR_MAPGEN_TOWN_NAME_FRENCH :法国 +STR_MAPGEN_TOWN_NAME_GERMAN :德国 +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :英国 (增强的) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :美式拉丁 +STR_MAPGEN_TOWN_NAME_SILLY :搞笑地名 +STR_MAPGEN_TOWN_NAME_SWEDISH :瑞典 +STR_MAPGEN_TOWN_NAME_DUTCH :荷兰 +STR_MAPGEN_TOWN_NAME_FINNISH :芬兰 +STR_MAPGEN_TOWN_NAME_POLISH :波兰 +STR_MAPGEN_TOWN_NAME_SLOVAK :斯洛伐克 +STR_MAPGEN_TOWN_NAME_NORWEGIAN :挪威 +STR_MAPGEN_TOWN_NAME_HUNGARIAN :匈牙利 +STR_MAPGEN_TOWN_NAME_AUSTRIAN :澳大利亚 +STR_MAPGEN_TOWN_NAME_ROMANIAN :罗马尼亚 +STR_MAPGEN_TOWN_NAME_CZECH :捷克 +STR_MAPGEN_TOWN_NAME_SWISS :瑞士 +STR_MAPGEN_TOWN_NAME_DANISH :丹麦 +STR_MAPGEN_TOWN_NAME_TURKISH :土耳其 +STR_MAPGEN_TOWN_NAME_ITALIAN :意大利 +STR_MAPGEN_TOWN_NAME_CATALAN :加泰罗尼亚 # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}地图边缘: @@ -3216,7 +3243,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}NewGRF STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}激活 NewGRF STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}停用 NewGRF STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}选择预设 -STR_NEWGRF_FILTER_TITLE :{ORANGE}过滤器字符串: +STR_NEWGRF_FILTER_TITLE :{ORANGE}关键字词搜索: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}装载选定的预定义 STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}保存预定义 STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}将当前组保存为预定义 @@ -3303,6 +3330,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}上一 STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}继续处理上一个正常的图形元素,略过任何虚位/重新着色/文字字型相关的图形元素;并且在处理到第一个图形元素后,返回最后的图形元素继续处理。 STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}显示目前选取的 sprite。当 sprite 正在描绘时会忽略其定位。 STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}从 X 及 Y 座标方向移动图形元素。如按住 Ctrl 键再点击,可一次移动 8 个单位 + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}偏移居中 +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}贴图居中 + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}十字准星 + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}重置相关 STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}重置当前相关偏移 STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X 偏移: {NUM}, Y 偏移: {NUM} (绝对) @@ -3317,18 +3351,16 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}警告:{SILVER}{STRING} 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} 是为 {STRING} 版 TTD 开发的。 -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} 应当与 {STRING} 配合 -STR_NEWGRF_ERROR_INVALID_PARAMETER :{1:STRING} 参数错误:参数 {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} 必须在 {STRING} 前加载。 -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} 必须在 {STRING} 后加载。 -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} 需要OpenTTD V {STRING} 或更高版本 +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} 是为 {2:STRING} 版 TTD 开发的。 +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} 应当与 {2:STRING} 配合 +STR_NEWGRF_ERROR_INVALID_PARAMETER :{1:STRING} 参数错误:参数 {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} 必须在 {2:STRING} 之前加载。 +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} 必须在 {2:STRING} 后加载。 +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} 需要OpenTTD {2:STRING} 或更高版本 STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF 被设计为可平移 STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :加载的NewGRF太多 -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :使用 {1:STRING} 为静态 NewGRF 与 {STRING} 可能造成同步错误 +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :载入 {1:STRING} 为静态 NewGRF 时载入 {2:STRING} 可能造成同步错误 STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :异常sprite (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :未知的Action 0 属性 {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :尝试使用非法ID (sprite {3:NUM}) @@ -3460,14 +3492,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :购买运输专 STR_LOCAL_AUTHORITY_ACTION_BRIBE :贿赂地方政府 ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}进行小型的广告宣传,以吸引更多的旅客和货物选择贵公司的服务。{}为位于该城镇中心较近距离内的车站提供暂时的评分增益。{}费用:{CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}进行中型的广告宣传,以吸引更多的旅客和货物选择贵公司的服务。{}为位于该城镇中心中等距离内的车站提供暂时的评分增益。{}费用:{CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}进行大型的广告宣传,以吸引更多的旅客和货物选择贵公司的服务。{}为位于该城镇中心较远距离内的车站提供暂时的评分增益。{}费用:{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} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}进行小型的广告宣传,以吸引更多的旅客和货物选择贵公司的服务。{}为位于该城镇中心较近距离内的车站提供暂时的评分增益。{}{POP_COLOUR}费用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}进行中型的广告宣传,以吸引更多的旅客和货物选择贵公司的服务。{}为位于该城镇中心中等距离内的车站提供暂时的评分增益。{}{POP_COLOUR}费用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}进行大型的广告宣传,以吸引更多的旅客和货物选择贵公司的服务。{}为位于该城镇中心较远距离内的车站提供暂时的评分增益。{}{POP_COLOUR}费用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}资助市政道路进行重建。{}将造成市内交通阻断 6 个月。{}{POP_COLOUR}费用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}以公司的名义设立一尊塑像。{}为位于该城镇的车站提供永久的评分增益。{}{POP_COLOUR}费用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}资助市内建设新的商业设施。{}为城镇提供暂时的成长速度增益。{}{POP_COLOUR}费用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}购买该市一年的运输专营权。{}其间该市的乘客及货物只允许选用贵公司的运输服务。{}{POP_COLOUR}费用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}贿赂地方政府以提高评价,但有被发现后严厉惩罚的风险。{}{POP_COLOUR}费用:{CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} 目标 @@ -3640,15 +3672,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}船只 STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}贷款利息 STR_FINANCES_SECTION_OTHER :{GOLD}其他费用 +STR_FINANCES_TOTAL_CAPTION :{WHITE}总计 STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}净利润 +STR_FINANCES_PROFIT :{WHITE}利润 STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}流动资金 STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}自有资金 STR_FINANCES_LOAN_TITLE :{WHITE}已贷款额 STR_FINANCES_INTEREST_RATE :{WHITE}贷款利息: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}最大贷款额度:{BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}贷款 {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}贷款{}Ctrl+点击 可贷款最大额度 STR_FINANCES_REPAY_BUTTON :{BLACK}还款 {CURRENCY_LONG} @@ -3749,7 +3784,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}产出 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 :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} 等待中{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}改变产量 @@ -3779,6 +3814,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}向所 STR_VEHICLE_LIST_REPLACE_VEHICLES :替换车辆/飞机/船只 STR_VEHICLE_LIST_SEND_FOR_SERVICING :进行保养 STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}今年利润:{CURRENCY_LONG} (去年利润:{CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :前往列车车库 STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :前往汽车车库 @@ -3870,6 +3907,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}最大 STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}航行距离: {GOLD}{COMMA} 格 STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}飞机类型: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :所有货物类型 +STR_CARGO_TYPE_FILTER_FREIGHT :货运 +STR_CARGO_TYPE_FILTER_NONE :没有 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}列车车辆选择列表。点击车辆查看详细信息,或者按住 Ctrl 键再点击以切换是否隐藏车辆的种类 STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}路面车辆选择列表。点击车辆查看详细信息,或者按住 Ctrl 键再点击以切换是否隐藏车辆的种类 @@ -4038,7 +4080,7 @@ 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_MAX_TE :{BLACK}售价:{CURRENCY_LONG} 重量:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER} 最大牵引力:{6:FORCE}{}运行费用{4:CURRENCY_LONG}/年{}运载能力:{5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}售价:{0:CURRENCY_LONG} 重量:{1:WEIGHT_SHORT}{}速度:{2:VELOCITY} 功率:{3: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_CAP_CAP_RUNCOST :{BLACK}售价:{CURRENCY_LONG} 最大速度:{VELOCITY}{}飞机类型:{STRING}{}运载能力:{CARGO_LONG}, {CARGO_LONG}{}运行成本: {CURRENCY_LONG}/年 STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}售价: {CURRENCY_LONG} 最大速度: {VELOCITY}{}飞机类型: {STRING}{}运载能力: {CARGO_LONG}{}运行成本: {CURRENCY_LONG}/年 @@ -4197,12 +4239,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}重量 STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}重量:{LTBLUE}{WEIGHT_SHORT} {BLACK}功率:{LTBLUE}{POWER}{BLACK} 最大速度:{LTBLUE}{VELOCITY} {BLACK}最大牵引力:{LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}今年利润:{LTBLUE}{CURRENCY_LONG} (去年利润:{CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}今年利润: {LTBLUE}{CURRENCY_LONG} (去年利润: {CURRENCY_LONG}) {BLACK}最小功率: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}可靠性:{LTBLUE}{COMMA}% {BLACK}上次保养后抛锚的次数:{LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}建造年份:{LTBLUE}{NUM}{BLACK} 价值:{LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}运载能力: {LTBLUE}无{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}运载能力:{LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}运载能力:{LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}运载能力:{LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}运载能力:{LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}运载能力:{LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}转运成本: {LTBLUE}{CURRENCY_LONG} @@ -4468,25 +4511,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}此时 STR_TIMETABLE_STATUS_START_AT :{BLACK}此时刻表将于 {STRING} 开始 STR_TIMETABLE_STARTING_DATE :{BLACK}起始日期 -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}选择此时刻表开始实施的日期。如果时刻表每一项指令皆已指定持续时间,Ctrl+左击会使系统为每个共用此时刻表的运具赋予一个开始实施时刻表的日期,使它们之间的时间间距一致 +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}选择一个时间作为此时间表的起始日期。按住Ctrl键单击将会给所有共享此时刻表的车辆指定一个时间,以使所有共享车辆保持运行间隔,但前提是时间表已为所有命令设定计划执行时间。 STR_TIMETABLE_CHANGE_TIME :{BLACK}改变时间 -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}改变高亮选择的命令执行的时间 +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}改变高亮选择的命令执行的时间,按住Ctrl单击可为所有命令设置时间 STR_TIMETABLE_CLEAR_TIME :{BLACK}清除时间 -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}清除高亮选择的命令的执行时间 +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}清除高亮选择的命令的执行时间。按住Ctrl键单击可清除所有命令的执行时间 STR_TIMETABLE_CHANGE_SPEED :{BLACK}更改限速 -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}更改高亮调度命令的最高限速 +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}更改高亮调度命令的最高限速。按住Ctrl键单击可为所有命令设置速度 STR_TIMETABLE_CLEAR_SPEED :{BLACK}取消限速 -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}清除高亮调度命令的最高限速 +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}清除高亮调度命令的最高限速。按住 Ctrl 键单击可以清除所有命令的最高限速 STR_TIMETABLE_RESET_LATENESS :{BLACK}清除晚点计数器 STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}重置晚点计数器,从而使车辆准时到达 STR_TIMETABLE_AUTOFILL :{BLACK}自动填充 -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}根据下一次运行的时间自动填充时间表{}(CRTL+单击 可保持等候时间) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}根据下一次运行的时间自动填充时间表。按住Ctrl单击可保持等候时间 STR_TIMETABLE_EXPECTED :{BLACK}预期时间 STR_TIMETABLE_SCHEDULED :{BLACK}表定时间 @@ -4530,12 +4573,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}您使 STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI调试窗口只对服务器可用 # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI 设置 +STR_AI_CONFIG_CAPTION_AI :{WHITE}AI配置 +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}游戏脚本配置 STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}下局游戏将启用这些脚本 STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}下局游戏将启用这些AI STR_AI_CONFIG_HUMAN_PLAYER :玩家 STR_AI_CONFIG_RANDOM_AI :随机 AI STR_AI_CONFIG_NONE :(无) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}最大竞争对手个数:{ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}上移 STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}在列表中将选择的AI上移 @@ -4543,15 +4588,14 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}下移 STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}在列表中将选择的AI下移 STR_AI_CONFIG_GAMESCRIPT :{SILVER}游戏脚本 +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}参数 STR_AI_CONFIG_AI :{SILVER}AI -STR_AI_CONFIG_CHANGE :{BLACK}选择{STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :游戏脚本 +STR_AI_CONFIG_CHANGE_AI :{BLACK}选择 AI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}选择游戏脚本 STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}装在另一脚本 STR_AI_CONFIG_CONFIGURE :{BLACK}设定 -STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}设定AI特征 +STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}设定脚本参数 # Available AIs window STR_AI_LIST_CAPTION :{WHITE}可用{STRING} @@ -4576,9 +4620,9 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}全地 STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}高度图截图 STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}小地图截图 -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} 参数 -STR_AI_SETTINGS_CAPTION_AI :AI +STR_AI_SETTINGS_CAPTION_AI :{WHITE}AI参数 STR_AI_SETTINGS_CAPTION_GAMESCRIPT :游戏脚本 STR_AI_SETTINGS_CLOSE :{BLACK}关闭 STR_AI_SETTINGS_RESET :{BLACK}重设 @@ -4743,6 +4787,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}…… STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}不能生成工业设施…… STR_ERROR_CAN_T_BUILD_HERE :{WHITE}不能在这里建设 {STRING} …… STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}不能在此处建设这种类型的工业设施…… +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}无法勘探工业... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}距离另一工业设施过近…… STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}必须先建设一个城镇…… STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}每个城镇只能建设一个…… @@ -4757,6 +4802,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}林场 STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... 只能在雪线以上建造 STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... 只能在雪线以下建造 +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}由于运气不好,勘探失败了;请再试一次 +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}没有合适的地方勘探这种工业 STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}没有合适的地方建设 “{STRING}” 工业设施 STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}请更改参数以生成较好的场景 @@ -4885,7 +4932,7 @@ STR_ERROR_CAN_T_BUILD_LOCKS :{WHITE}不能 STR_ERROR_CAN_T_PLACE_RIVERS :{WHITE}不能在这里加设河流... STR_ERROR_MUST_BE_BUILT_ON_WATER :{WHITE}必须在水上建造…… STR_ERROR_CAN_T_BUILD_ON_WATER :{WHITE}不能在水上建造…… -STR_ERROR_CAN_T_BUILD_ON_SEA :{WHITE}...不能建築在公海上 +STR_ERROR_CAN_T_BUILD_ON_SEA :{WHITE}...不能建在公海上 STR_ERROR_CAN_T_BUILD_ON_CANAL :{WHITE}... 不能在运河上建设 STR_ERROR_CAN_T_BUILD_ON_RIVER :{WHITE}... 不能在河流上建造…… STR_ERROR_MUST_DEMOLISH_CANAL_FIRST :{WHITE}请先移除运河 @@ -4924,6 +4971,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}目标 STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}目标处有公司总部 STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}不能购买这个地块! STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}你已经拥有此地块! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}...对象构造达到极限 # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}无法新建分组…… @@ -4996,6 +5044,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}不能 STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... 运具已撞毁 +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}...并非所有车辆都相同 + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}没有可用的运输工具 STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}请改动您的 NewGRF 设置 STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}暂时沒有可用的运输工具 @@ -5022,6 +5072,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}不能 STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}车辆无法到达全部站点 STR_ERROR_CAN_T_ADD_ORDER :{WHITE}车辆无法到达那个车站 STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}一个共享此调度计划的载具无法到达那个车站 +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}...并不是所有的车辆都有相同的指令 +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}...并不是所有的车辆都有相同的指令 STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}不能共享调度计划…… STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}不能停止共享调度计划…… @@ -5029,6 +5081,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}不能 STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}……距离前一目的地太远 STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... 飞机航行距离不足 +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}不能给车辆编制时间表… STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}车辆只能在站内等候。 diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 0b06b732f24fa..04dcfaa3cd0a1 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -264,6 +264,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}hp STR_UNITS_POWER_METRIC :{COMMA}hp STR_UNITS_POWER_SI :{COMMA}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}kg @@ -289,9 +299,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA} m STR_UNITS_HEIGHT_SI :{COMMA} m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filtrovací reťazec: -STR_LIST_FILTER_OSKTITLE :{BLACK}Vložiť filtrovací reťazec -STR_LIST_FILTER_TOOLTIP :{BLACK}Vložiť kľúčové slovo pre filtrovanie zoznamu +STR_LIST_FILTER_TITLE :{BLACK}Filter: +STR_LIST_FILTER_OSKTITLE :{BLACK}Vložiť aspoň jedno klúčové slovo pre filtrovanie +STR_LIST_FILTER_TOOLTIP :{BLACK}Vložiť aspoň jedno klúčové slovo pre filtrovanie STR_TOOLTIP_GROUP_ORDER :{BLACK}Zvoľ druh zoskupenia STR_TOOLTIP_SORT_ORDER :{BLACK}Spôsob triedenia (zostupný/vzostupný) @@ -352,8 +362,8 @@ STR_SORT_BY_PRODUCTION :Produkcia STR_SORT_BY_TYPE :Typ STR_SORT_BY_TRANSPORTED :Prepravené STR_SORT_BY_NUMBER :Číslo -STR_SORT_BY_PROFIT_LAST_YEAR :Profit v minulom roku -STR_SORT_BY_PROFIT_THIS_YEAR :Profit v tomto roku +STR_SORT_BY_PROFIT_LAST_YEAR :Zisk v minulom roku +STR_SORT_BY_PROFIT_THIS_YEAR :Zisk v tomto roku STR_SORT_BY_AGE :Vek STR_SORT_BY_RELIABILITY :Spoľahlivosť STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE :Kapacita podľa typu nákladu @@ -380,10 +390,10 @@ STR_SORT_BY_RANGE :Rozsah STR_SORT_BY_POPULATION :Populácia STR_SORT_BY_RATING :Hodnotenie STR_SORT_BY_NUM_VEHICLES :Počet vozidiel -STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR :Celkový profit v minulom roku -STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR :Celkový profit v tomto roku -STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :Priemerný profit v minulom roku -STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR :Priemerný profit v tomto roku +STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR :Celkový zisk v minulom roku +STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR :Celkový zisk v tomto roku +STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :Priemerný zisk v minulom roku +STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR :Priemerný zisk v tomto roku # Group by options for vehicle list STR_GROUP_BY_NONE :Žiadne @@ -440,9 +450,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Generova STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Generovanie priemyslu STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Stavba cesty STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Výstavba električkovej trate -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Sadiť stromy. Shift zobrazí odhadovanú cenu +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Sadiť stromy. Ctrl označí oblasť diagonálne. Shift zobrazí odhadovanú cenu STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Umiestniť popis -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Umiestniť objekt. Shift zobrazí odhadovanú cenu +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Umiestniť objekt. Ctrl označí oblasť diagonálne. Shift zobrazí odhadovanú cenu # Scenario editor file menu ###length 7 @@ -455,10 +465,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Ukončiť # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Možnosti hry STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Nastavenia -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Nastavenia AI/skriptu +STR_SETTINGS_MENU_AI_SETTINGS :Nastavenia AI +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Nastavenia skriptu STR_SETTINGS_MENU_NEWGRF_SETTINGS :Nastavenia NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Nastavenia priehľadnosti STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Zobraziť názvy miest @@ -497,7 +508,7 @@ STR_SUBSIDIES_MENU_SUBSIDIES :Dotácie # Graph menu ###length 6 -STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH :Graf prevádzkového profitu +STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH :Graf prevádzkového zisku STR_GRAPH_MENU_INCOME_GRAPH :Graf tržieb STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH :Graf prepraveného nákladu STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH :Graf hodnotenia výkonu @@ -652,7 +663,7 @@ STR_GRAPH_X_LABEL_MONTH_YEAR :{TINY_FONT}{STR STR_GRAPH_Y_LABEL :{TINY_FONT}{STRING} STR_GRAPH_Y_LABEL_NUMBER :{TINY_FONT}{COMMA} -STR_GRAPH_OPERATING_PROFIT_CAPTION :{WHITE}Graf prevádzkového profitu +STR_GRAPH_OPERATING_PROFIT_CAPTION :{WHITE}Graf prevádzkového zisku STR_GRAPH_INCOME_CAPTION :{WHITE}Graf tržieb STR_GRAPH_CARGO_DELIVERED_CAPTION :{WHITE}Graf prepraveného nákladu (jednotiek nákladu) STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION :{WHITE}Graf hodnotenia výkonu (najvyššie hodnotenie je 1000) @@ -698,7 +709,7 @@ STR_PERFORMANCE_DETAIL_SELECT_COMPANY_TOOLTIP :{BLACK}Ukázať ###length 10 STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vozidlá: STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Stanice: -STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. profit: +STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Min. zisk: STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Min. príjem: STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Max. príjem: STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Prepravené: @@ -710,7 +721,7 @@ STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Spolu: ###length 10 STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP :{BLACK}Počet vozidiel, ktoré dosiahli v minulom roku zisk. Patria sem cestné vozidlá, vlaky, lode a lietadlá STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP :{BLACK}Počet nedávno obsluhovaných staníc. Železničné stanice, autobusové zastávky, letiská a pod. sa počítajú oddelene aj keď patria do rovnakej stanice -STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP :{BLACK}Profit vozidla s najnižšími tržbami (zo všetkých vozidiel starších ako 2 roky) +STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP :{BLACK}Zisk vozidla s najnižšími tržbami (zo všetkých vozidiel starších ako 2 roky) STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Množstvo peňazí zarobených v kvartáli s najmenším ziskom v posledných 12 kvartáloch STR_PERFORMANCE_DETAIL_MAX_INCOME_TOOLTIP :{BLACK}Množstvo peňazí zarobených v kvartáli s najväčším ziskom v posledných 12 kvartáloch STR_PERFORMANCE_DETAIL_DELIVERED_TOOLTIP :{BLACK}Počet jednotiek nákladu prepravených v posledných štyroch kvartáloch @@ -882,9 +893,9 @@ STR_NEWS_FIRST_AIRCRAFT_ARRIVAL :{BIG_FONT}{BLAC STR_NEWS_TRAIN_CRASH :{BIG_FONT}{BLACK}Vlakové nešťastie!{}{COMMA} mŕtv{P i i ych} pri požiari po kolízii STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER :{BIG_FONT}{BLACK}Dopravná nehoda!{}Vodič zomrel po kolízii s vlakom -STR_NEWS_ROAD_VEHICLE_CRASH :{BIG_FONT}{BLACK}Dopravná nehoda!{}{COMMA} mŕtvych po kolízii s vlakom +STR_NEWS_ROAD_VEHICLE_CRASH :{BIG_FONT}{BLACK}Dopravná nehoda!{}{COMMA} mŕtv{P i i ych} po kolízii s vlakom STR_NEWS_AIRCRAFT_CRASH :{BIG_FONT}{BLACK}Letecké nešťastie!{}{COMMA} mŕtv{P y i ych} po požiari na {STATION} -STR_NEWS_PLANE_CRASH_OUT_OF_FUEL :{BIG_FONT}{BLACK}Letecké nešťastie!{}Lietadlu došlo palivo, {COMMA} mŕtvych pri požiari +STR_NEWS_PLANE_CRASH_OUT_OF_FUEL :{BIG_FONT}{BLACK}Letecké nešťastie!{}Lietadlu došlo palivo, {COMMA} mŕtv{P y i ych} pri požiari STR_NEWS_DISASTER_ZEPPELIN :{BIG_FONT}{BLACK}Zeppelin zničený pri nehode na {STATION}! STR_NEWS_DISASTER_SMALL_UFO :{BIG_FONT}{BLACK}Cestné vozidlo bolo zničené pri kolízii s 'UFO' @@ -892,7 +903,7 @@ STR_NEWS_DISASTER_AIRPLANE_OIL_REFINERY :{BIG_FONT}{BLAC STR_NEWS_DISASTER_HELICOPTER_FACTORY :{BIG_FONT}{BLACK}Za nejasných okolností bola zničená továreň neďaleko mesta {TOWN}! STR_NEWS_DISASTER_BIG_UFO :{BIG_FONT}{BLACK}'UFO' pristálo neďaleko mesta {TOWN}! STR_NEWS_DISASTER_COAL_MINE_SUBSIDENCE :{BIG_FONT}{BLACK}Zával v uhoľnej bani neďaleko mesta {TOWN}! -STR_NEWS_DISASTER_FLOOD_VEHICLE :{BIG_FONT}{BLACK}Povodeň!{}Najmenej {COMMA} ľudí je nezvestných alebo mŕtvych po obrovských záplavách! +STR_NEWS_DISASTER_FLOOD_VEHICLE :{BIG_FONT}{BLACK}Povodeň!{}Najmenej {COMMA} {P človek ľudia ľudí} {P je sú je} nezvestn{P ý í ých} alebo mŕtv{P y i ych} po obrovských záplavách! STR_NEWS_COMPANY_IN_TROUBLE_TITLE :{BIG_FONT}{BLACK}Dopravná spoločnosť má problémy! STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION :{BIG_FONT}{BLACK}{STRING} bude predaná alebo vyhlási bankrot pokiaľ čoskoro nezvýši produktivitu! @@ -1033,36 +1044,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indická rupia STR_GAME_OPTIONS_CURRENCY_IDR :Indonézska rupia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malajzijský ringgit (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Jazdia naľavo -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Jazdia napravo - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Názvy miest: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Výber štýlu názvov miest - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Anglické (pôvodné) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francúzske -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Nemecké -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Anglické (ďalšie) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latinsko-Americké -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Anglické (hlúpe) -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Švédske -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holandské -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Fínske -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Poľské -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovenské -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Nórske -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Maďarské -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Rakúske -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumunské -STR_GAME_OPTIONS_TOWN_NAME_CZECH :České -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Švajčiarské -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dánske -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turecké -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Talianské -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalánske - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatické ukladanie STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Výber intervalu automatického ukladania @@ -1093,22 +1074,21 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Nastaven STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Zaškrtnite toto políčko, aby ste povolili vertikálnu synchronizáciu. Zmeny budú uplatnené až po reštarte hry. Funguje iba ak je zapnutá hardvérová akcelerácia. +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Aktuálny ovládač: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Veľkosť rozhrania -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Výber veľkosti prvkov rozhrania +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Veľkosť rozhrania +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Potiahnutím posúvača nastavte veľkosť rozhrania. Pre plynulé nastavenie podržte Ctrl +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Detekovať rozmery automaticky +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Začiarknutím tohto políčka automaticky zistiť veľkosť rozhrania -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(automaticky zistené) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normálna -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dvojnásobná veľkosť -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Štvornásobná veľkosť +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Mierkové úkosy +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Začiarknutím tohto políčka zmeníte úkosy podľa veľkosti rozhrania -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Veľkosť písma -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Výber veľkosti písma v rozhraní - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(automaticky zistené) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normálna -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dvojnásobná veľkosť -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Štvornásobná veľkosť +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafika @@ -1160,8 +1140,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Náhľa STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 libier (£) vo vašej mene STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Zmeniť parametre vlastnej meny -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maximálny počet konkurentov: {ORANGE}{COMMA} - STR_NONE :Žiadny STR_FUNDING_ONLY :Iba financovanie STR_MINIMAL :Minimálny @@ -1211,6 +1189,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Krajina mierneho pásma +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subpolárna krajina +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Subtropická krajina +STR_CLIMATE_TOYLAND_LANDSCAPE :Krajina hračiek + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Veľmi rovný STR_TERRAIN_TYPE_FLAT :Rovný @@ -1221,15 +1205,16 @@ STR_TERRAIN_TYPE_CUSTOM :Vlastná výšk STR_TERRAIN_TYPE_CUSTOM_VALUE :Vlastná výška ({NUM}) ###length 4 +STR_CITY_APPROVAL_LENIENT :Zhovievavý STR_CITY_APPROVAL_TOLERANT :Tolerantný STR_CITY_APPROVAL_HOSTILE :Odmietavý -STR_CITY_APPROVAL_PERMISSIVE :Pozitívny +STR_CITY_APPROVAL_PERMISSIVE :Povoľný (nemá vplyv na akcie spoločnosti) STR_WARNING_NO_SUITABLE_AI :{WHITE}Nieje dostupné žiadne použiteľné AI...{}Niekoľko AI je možné stiahnuť cez 'Online obsah' # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Nastavenia -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrovací reťazec: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filter: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Rozbaliť všetko STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Zabaliť všetko STR_CONFIG_SETTING_RESET_ALL :Resetovať všetky hodnoty @@ -1289,6 +1274,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :vpravo STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maximálny počiatočný úver: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximálna množstvo peňazí ktoré si môže spoločnosť požičať (bez inflácie) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Žiadny úver {RED}Vyžaduje Herný skript na poskytnutie počiatočných prostriedkov STR_CONFIG_SETTING_INTEREST_RATE :Úroková sadzba: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Úroková sadzba úveru; kontroluje infláciu ak je povolená @@ -1324,8 +1312,8 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :Ak je povolené STR_CONFIG_SETTING_DISASTERS :Havárie: {STRING} STR_CONFIG_SETTING_DISASTERS_HELPTEXT :Vypne alebo zapne katastrofy, ktoré môžu občas zablokovať alebo zničiť vozidlá alebo infraštruktúru -STR_CONFIG_SETTING_CITY_APPROVAL :Postoj mestskej správy k reštrukturalizácii v oblasti: {STRING} -STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Zvoľte ako veľmi ovplyvňuje hluk a poškodzovanie prostredia spoločnosťami ich hodnotenie v meste a ich budúce možnosti výstavby v oblasti vlastnenej mestom +STR_CONFIG_SETTING_CITY_APPROVAL :Postoj miestnej samosprávy: {STRING} +STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Zvoľte ako veľmi ovplyvňuje hluk a poškodzovanie prostredia spoločnosťami ich hodnotenie v meste a ich budúce možnosti výstavby v meste STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT :Limit výšky mapy: {STRING} STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_HELPTEXT :Zvoľte maximálnu výšku terénu na mape. S "(automatický)" bude vybraná správna hodnota podľa generátora krajiny @@ -1479,7 +1467,7 @@ STR_CONFIG_SETTING_ORDER_REVIEW_OFF :Nie STR_CONFIG_SETTING_ORDER_REVIEW_EXDEPOT :Áno, okrem zastavených vozidiel STR_CONFIG_SETTING_ORDER_REVIEW_ON :U všetkých vozidiel -STR_CONFIG_SETTING_WARN_INCOME_LESS :Varovať, ak je vozidlo stratové: {STRING} +STR_CONFIG_SETTING_WARN_INCOME_LESS :Varovať ak je vozidlo stratové: {STRING} STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT :Ak je zapnuté, zobrazí sa správa ak vozidlo nevykázalo žiaden zisk za predošlý rok. STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :Nikdy neprestať s výrobou starých vozidiel: {STRING} @@ -1515,6 +1503,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Hrúbka čiar v STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Zobraziť názov NewGRF v okne vozidiel: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Pridá riadok do zoznamu vozidiel, ktorý ukazuje z akého NewGRF vozidlo pochádza. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Zobraziť náklad, ktorý môžu vozidlá prepravovať v oknách zoznamu {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Ak je zapnuté, v zoznamoch vozidiel sa nad ňou zobrazí prepravovateľný náklad vozidla STR_CONFIG_SETTING_LANDSCAPE :Krajina: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Krajiny definujú základný herný scenár s rôznymi druhmi nákladu a požiadavkami na rast miest. NewGRF a herné skripty umožňujú ich lepšiu kontrolu @@ -1569,6 +1559,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Vylepšený STR_CONFIG_SETTING_ROAD_SIDE :Cestné vozidlá: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Vyberte jazdnú stranu +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Jazdia naľavo +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Jazdia napravo + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Orientácia výškovej mapy: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Proti smeru hodinových ručičiek @@ -1595,7 +1589,13 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Zelená STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Tmavozelená STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Fialová +STR_CONFIG_SETTING_LINKGRAPH_COLOURS :Farby prekrytia toku nákladu: {STRING} +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_HELPTEXT :Nastavte farebnú schému použitú pre prekrytie toku nákladu. ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :Zelenočervená +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Zelenomodrá +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Sivá až červená +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :Odtiene šedej STR_CONFIG_SETTING_SCROLLMODE :Správanie pohľadu pri posúvaní myšou: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Reakcia na posúvanie (scrollovanie) na mape @@ -1877,8 +1877,8 @@ STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Ak je zapnuté, STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Minimálny vek spoločnosti na obchodovanie s podielmi: {STRING} STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Určuje minimálny vek spoločnosti na to, aby od nej mohli ostatné spoločnosti kupovať a predavať podiely. -STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Percentáž profitu na zaplatenie podávacieho systému: {STRING} -STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Percento príjmov dať na strednú ´nohu´ vo feeder systémoch, získate väčšiu kontrolu nad príjmamy +STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Percentáž zisku na zaplatenie podávacieho systému: {STRING} +STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Percento príjmov dať na strednú ´nohu´ vo feeder systémoch, získate väčšiu kontrolu nad príjmami STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Pri ťahaní, umiestni návestidlo každé: {STRING} STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_HELPTEXT :Nastaviť vzdialenosť návestidiel, akou budú umiestnené na trati po najbližšiu prekážku (návestidlo, križovatku), pri stavbe ťahaním @@ -1996,13 +1996,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Použiť {STRIN STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Čas potrebný pre každé prepočítanie grafu spojov. Pri štarte prepočtu je vytvorené vlákno, ktoré môže bežať uvedený počet dní. Čím menej nastavíte, tým je pravdepodobnejšie, že vlákno nestihne skončiť, kým je to možné. Potom sa hra na nejaký čas zasekne. Čím viac nastavíte, tým dlhšie trvá aktualizácia rozdelenia po zmene trasy. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Druh distribúcie pre cestujúcich: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symetricky" znamená, že približne rovnaké množstvo pasažierov bude cestovať zo stanice A do stanice B ako z B do A. "asymetricky"znamená, že v oboch smeroch môže cestovať ľubovoľné množstvo pasažierov. "manuálne" znamená, že sa pre pasažierov nevykoná automatická distribúcia. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symetricky" znamená, že približne rovnaké množstvo pasažierov bude cestovať zo stanice A do stanice B ako z B do A. "Asymetricky" znamená, že v oboch smeroch môže cestovať ľubovoľné množstvo pasažierov. "Manuálne" znamená, že sa pre pasažierov nevykoná automatická distribúcia. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Druh distribúcie pre poštu: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"symetricky" znamená, že približne rovnaké množstvo pošty bude odoslané zo stanice A do stanice B ako z B do A. "asymetricky"znamená, že v oboch smeroch môže byť odoslané ľubovoľné množstvo pošty. "manuálne" znamená, že sa pre poštu nevykoná automatická distribúcia. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Symetricky" znamená, že približne rovnaké množstvo pošty bude odoslané zo stanice A do stanice B ako z B do A. "Asymetricky" znamená, že v oboch smeroch môže byť odoslané ľubovoľné množstvo pošty. "Manuálne" znamená, že sa pre poštu nevykoná automatická distribúcia. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Druh distribúcie pre náklad prevážaný obrnenými vozidlami: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Náklad prevážaný obrnenými vozidlami sú cennosti v miernom, diamanty v subtropickom alebo zlato v subarktickom podnebí. NewGRF to môže zmeniť. "symetricky" znamená, že rovnaké množstvo nákladu bude odoslané zo stanice A do stanice B a naopak. "asymetricky" znamená, že v oboch smeroch môže byť odoslané ľubovoľné množstvo nákladu. "manuálne" znamená, že sa pre náklad nevykoná automatická distribúcia. Doporučuje sa nastaviť na "asymetricky" alebo "manuálne" pri hraní v subarktickom, pretože banky neodošlú žiadne zlato do zlatých baní. Pre mierne a subtropické si môžete vybrať aj "symetricky", pretože banky budú posielať cennosti späť do pôvodnej banky, ktorá ich odoslala. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Náklad prevážaný obrnenými vozidlami sú cennosti v miernom, diamanty v subtropickom alebo zlato v subarktickom podnebí. NewGRF to môže zmeniť. "Symetricky" znamená, že rovnaké množstvo nákladu bude odoslané zo stanice A do stanice B a naopak. "Asymetricky" znamená, že v oboch smeroch môže byť odoslané ľubovoľné množstvo nákladu. "Manuálne" znamená, že sa pre náklad nevykoná automatická distribúcia. Doporučuje sa nastaviť na "asymetricky" alebo "manuálne" pri hraní v subarktickom alebo subtropickom, pretože banky prijímajú náklad iba v týchto podnebiach. Pre mierne podnebie si môžete vybrať aj "symetricky", pretože banky budú posielať cennosti späť do pôvodnej banky, ktorá ich odoslala. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Druh distribúcie pre ostatné druhy nákladu: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asymetricky"znamená, že v oboch smeroch môže byť odoslané ľubovoľné množstvo nákladu. "manuálne" znamená, že sa pre náklad nevykoná automatická distribúcia. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asymetricky" znamená, že v oboch smeroch môže byť odoslané ľubovoľné množstvo nákladu. "Manuálne" znamená, že sa pre náklad nevykoná automatická distribúcia. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuálne STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asymetricky @@ -2097,7 +2097,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Automatické ob STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Povoliť vlakom otočiť sa na návestidlách, ak tam čakajú dlhý čas ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(odporučený) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(odporučený) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Zmeniť hodnotu nastavenia @@ -2140,7 +2140,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Najvyš STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Nastavenia STR_INTRO_NEWGRF_SETTINGS :{BLACK}Nastavenia NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Skontrolovať online obsah -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Nastavenia AI/skriptu +STR_INTRO_AI_SETTINGS :{BLACK}Nastavenia AI +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Nastavenia skriptu STR_INTRO_QUIT :{BLACK}Ukončiť STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Spustiť novú hru. Ctrl+klik preskočí nastavenie mapy @@ -2160,7 +2161,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Zobrazi STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Zobraziť nastavenia STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Zobraziť nastavenia NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Skontrolovať nový a aktualizovaný obsah pre stiahnutie -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Zobraziť nastavenia AI/skriptu +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Zobraziť AI nastavenia +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Zobraz nastavenia skriptu STR_INTRO_TOOLTIP_QUIT :{BLACK}Ukončiť 'OpenTTD' STR_INTRO_BASESET :{BLACK}Vo vybranej základnej sade grafiky chýba {NUM} prv{P ok ky kov}. Prosím skontrolujte aktualizácie sady grafiky. @@ -2192,12 +2194,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Zmeniť STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Zmeniť súčasný rok STR_CHEAT_SETUP_PROD :{LTBLUE}Povoliť zmenu objemu výroby: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Krajina mierneho pásma -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Subpolárna krajina -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Subtropická krajina -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Krajina hračiek - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Farebná schéma @@ -2430,7 +2426,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nová spoločn STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Založiť novú spoločnosť a pripojiť sa k nej STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Toto ste vy STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Toto je hosť hry -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" "i" "ov"} / {NUM} spoločnos{P "ť" "ti" "tí"} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" "i" "ov"} - {NUM}/{NUM} spoločnos{P "ť" "ti" "tí"} +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Počet aktuálne pripojených klientov, počet spoločností a maximálny počet spoločností povolený správcom servera # Matches ConnectionType ###length 5 @@ -2557,13 +2554,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :čaká sa na ak STR_NETWORK_MESSAGE_CLIENT_LEAVING :odchádza STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} vstúpil do hry -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} vstúpil do hry (klient č. {2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} sa pripojil do spoločnosti č. {2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} vstúpil do hry (klient č. {2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} sa pripojil do spoločnosti č. {2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} sa pripojil k pozorovateľom -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} založil novú spoločnosť (č. {2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} opustil hru ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} založil novú spoločnosť (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} opustil hru ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} zmenil/-a svoje meno na {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} dal {2:CURRENCY_LONG} spoločnosti {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} dal {2:CURRENCY_LONG} spoločnosti {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server ukončil reláciu STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server sa reštartuje...{}Čakajte prosím... STR_NETWORK_MESSAGE_KICKED :*** Hráč {STRING} bol vyhodený. Dôvod: ({STRING}) @@ -2677,6 +2674,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}vyťažené STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}preťažené +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} na prepravu za mesiac z {STATION} do {STATION} ({COMMA}% kapacity){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} na prepravu naspäť ({COMMA}% kapacity) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Priemerný čas cesty: {NUM}{NBSP}d{P eň ni ní} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Ukázať oblasť pokrytia STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Vyp. @@ -2685,6 +2687,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Nezvýra STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Zobraziť oblasť pokrytia stavanej plochy STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Prijíma: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Dodáva: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Náklady na údržbu: {GOLD}{CURRENCY_SHORT}/rok # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Spojiť stanicu @@ -2767,8 +2770,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Zvýšit STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Vyber železničný most STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Vyber cestný most STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Výber mostu - pre postavanie zvoľ typ mostu -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Závesný oceľový STR_BRIDGE_NAME_GIRDER_STEEL :Pilierový oceľový STR_BRIDGE_NAME_CANTILEVER_STEEL :Visutý oceľový @@ -2872,11 +2877,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Úprava STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Znížiť roh políčka. Ťahaním znížite prvý vybraný roh a vyrovnáte celú vybranú oblasť na novú výšku. Ctrl označí oblasť diagonálne. Shift zobrazí odhadovanú cenu STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Zvýšiť roh políčka. Ťahaním zvýšite prvý vybraný roh a vyrovnáte celú vybranú oblasť na novú výšku. Ctrl označí oblasť diagonálne. Shift zobrazí odhadovanú cenu STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Vyrovnať výšku terénu podľa vybraného rohu. Ctrl označí oblasť diagonálne. Shift zobrazí odhadovanú cenu -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Zakúpiť pozemok pre budúce použitie. Shift zobrazí odhadovanú cenu +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Zakúpiť pozemok pre budúce použitie. Ctrl označí oblasť diagonálne. Shift zobrazí odhadovanú cenu # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Výber objektu -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Vyberte objekt na vybudovanie. Shift zobrazí odhadovanú cenu +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Vyberte objekt na vybudovanie. Ctrl označí oblasť diagonálne. Shift zobrazí odhadovanú cenu STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Vyberte triedu objektu na vybudovanie STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Náhľad objektu STR_OBJECT_BUILD_SIZE :{BLACK}Rozmery: {GOLD}{NUM} x {NUM} políčok @@ -2888,7 +2893,7 @@ STR_OBJECT_CLASS_TRNS :Vysielače STR_PLANT_TREE_CAPTION :{WHITE}Stromy STR_PLANT_TREE_TOOLTIP :{BLACK}Vybrať druh stromu na sadenie. Ak sa už strom na políčku nachádza, pridá sa viac stromov zmiešaných druhov nezávisle od vybraného druhu STR_TREES_RANDOM_TYPE :{BLACK}Náhodný druh stromov -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Umiestniť stromy náhodného druhu. Shift zobrazí odhadovanú cenu +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Umiestniť stromy náhodného druhu. Ctrl označí oblasť diagonálne. Shift zobrazí odhadovanú cenu STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Náhodné stromy STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Zasadiť stromy náhodne po celej krajine STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normálne @@ -2920,6 +2925,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Nahodné STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Postaviť mesto na náhodnej pozícii STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Veľa náhodných miest STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Pokryť mapu náhodne umiestnenými mestami +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Rozbaliť všetky mestá +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Nechať všetky mestá mierne rásť STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Meno mesta: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Vložte meno mesta @@ -3184,7 +3191,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detaily STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Informácia nie je k dispozícii STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtrovací reťazec: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filter: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Prepísanie súboru STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Ste si istý, že chcete prepísať existujúci súbor? STR_SAVELOAD_DIRECTORY :{STRING} (Priečinok) @@ -3198,6 +3205,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Veľkos STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Výber veľkosti mapy v políčkach. Počet dostupných políčok bude o trochu nižší STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Počet miest: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Názvy miest: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Výber štýlu názvov miest STR_MAPGEN_DATE :{BLACK}Rok: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Počet priemyslu: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Najvyšší vrchol: @@ -3211,13 +3220,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Pokrytie STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Zvýšiť pokrytie púšťou o desať percent STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Znížiť pokrytie púšťou o desať percent STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Generátor krajiny: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Typ terénu: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Rozloha mora: +STR_MAPGEN_SEA_LEVEL :{BLACK}Rozloha mora: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Rieky: STR_MAPGEN_SMOOTHNESS :{BLACK}Členitosť: STR_MAPGEN_VARIETY :{BLACK}Rozmanitosť distribúcie: STR_MAPGEN_GENERATE :{WHITE}Generovať +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Nastavenia NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Zobraziť nastavenia NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Nastavenia AI +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Zobraziť AI nastavenia +STR_MAPGEN_GS_SETTINGS :{BLACK}Nastavenia skriptu +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Zobraz nastavenia skriptu + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Anglické (pôvodné) +STR_MAPGEN_TOWN_NAME_FRENCH :Francúzske +STR_MAPGEN_TOWN_NAME_GERMAN :Nemecké +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Anglické (ďalšie) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latinsko-Americké +STR_MAPGEN_TOWN_NAME_SILLY :Anglické (hlúpe) +STR_MAPGEN_TOWN_NAME_SWEDISH :Švédske +STR_MAPGEN_TOWN_NAME_DUTCH :Holandské +STR_MAPGEN_TOWN_NAME_FINNISH :Fínske +STR_MAPGEN_TOWN_NAME_POLISH :Poľské +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovenské +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Nórske +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Maďarské +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Rakúske +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumunské +STR_MAPGEN_TOWN_NAME_CZECH :České +STR_MAPGEN_TOWN_NAME_SWISS :Švajčiarské +STR_MAPGEN_TOWN_NAME_DANISH :Dánske +STR_MAPGEN_TOWN_NAME_TURKISH :Turecké +STR_MAPGEN_TOWN_NAME_ITALIAN :Talianské +STR_MAPGEN_TOWN_NAME_CATALAN :Katalánske # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Okraje mapy: @@ -3276,7 +3313,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Detailn STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Aktívne NewGRF súbory STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Neaktívne NewGRF súbory STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Vybrať predvoľbu: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtrovací reťazec: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filter: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Nahrať vybraný zoznam STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Uložit zoznam STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Uložiť aktuálne nastavenie ako zoznam @@ -3363,6 +3400,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Predchá STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Prejsť na predchádzajúci normálny sprite, vynechajúc akékoľvek falošné/prefarbené sprites a sprites fontu použité na začiatku STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Reprezentuje aktuálne zvolený sprite. Zarovnanie je ignorované pri vykresľovaní sprite-u STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Posúvajte sprite, so súčasnou zmenou X a Y súradnice. Ctrl+klik posunie sprite o osem jednotiek súčasne + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Offset v strede +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite zarovnávač v strede + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Zameriavací kríž + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Resetovať relatívne STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Resetovať aktuálne relatívne posunutie STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X offset: {NUM}, Y offset: {NUM} (absolútne) @@ -3377,18 +3421,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Upozornenie: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Chyba: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Kritická chyba: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Nastala závažná chyba NewGRF:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Vyskytla sa chyba NewGRF:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}NewGRF "{STRING}" vrátil fatálnu chybu:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF "{STRING}" vrátil chybu:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} nebude fungovať s TTDPatch verziou nahlásenou OpenTTD. -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} je pre verziu {STRING} TTD. -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} je navrhnutý pre použitie s {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Neplatný parameter {1:STRING}: parameter {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} musí byť načítaný pred {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} musí byť načítaný po {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} vyžaduje verziu OpenTTD {STRING} alebo vyššiu. +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} je pre verziu {2:STRING} TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} je navrhnutý pre použitie s {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Neplatný parameter {1:STRING}: parameter {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} musí byť načítaný pred {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} musí byť načítaný po {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} vyžaduje verziu OpenTTD {2:STRING} alebo vyššiu STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF súbor bol navrhnutý na preklad STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Načítaných priveľa súborov NewGRF. -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Načítanie {1:STRING} ako statického NewGRF s {STRING} môže spôsobiť chybné zobrazenie. +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Načítanie {1:STRING} ako statického NewGRF s {2:STRING} môže spôsobiť chybné zobrazenie STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Neočakávaný sprite (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Neznáma vlastnosť Action 0 {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Pokus o použitie neplatného ID (sprite {3:NUM}) @@ -3520,14 +3564,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Zakúpiť exklu STR_LOCAL_AUTHORITY_ACTION_BRIBE :Podplatiť miestnu správu ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Spustiť malú reklamnú kampaň, ktorá priláka viac cestujúcich a nákladu k vašej spoločnosti.{}Zabezpečí dočasné zvýšenie hodnotenia staníc v malom okruhu okolo centra mesta.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Spustiť strednú reklamnú kampaň, ktorá priláka viac cestujúcich a nákladu k vašej spoločnosti.{}Zabezpečí dočasné zvýšenie hodnotenia staníc v stredne veľkom okruhu okolo centra mesta.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Spustiť veľkú reklamnú kampaň, ktorá priláka viac cestujúcich a nákladu k vašej spoločnosti.{}Zabezpečí dočasné zvýšenie hodnotenia staníc vo veľkom okruhu okolo centra mesta.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Financovať rekonštrukciu mestskej cestnej siete.{}Spôsobí dopravný chaos a zápchy trvajúce ďalších 6 mesiacov.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Postaviť sochu na počesť vašej spoločnosti.{}Zabezpečí trvalé zvýšenie hodnotenia staníc v tomto meste.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Financovať výstavbu nových budov v meste.{}Zabezpečí dočasné zrýchlenie rastu tohto mesta.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Zakúpiť exkluzívne dopravné práva v meste na 1 rok.{}Miestna správa nedovolí cestujúcim a nákladu používať stanice konkurentov.{}Cena: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Podplatiť miestnu správu pre zvýšenie hodnotenia vašej spoločnosti, s rizikom ťažkého postihu pri odhalení.{}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Spustiť malú reklamnú kampaň, ktorá priláka viac cestujúcich a nákladu k vašej spoločnosti.{}Zabezpečí dočasné zvýšenie hodnotenia staníc v malom okruhu okolo centra mesta.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Spustiť strednú reklamnú kampaň, ktorá priláka viac cestujúcich a nákladu k vašej spoločnosti.{}Zabezpečí dočasné zvýšenie hodnotenia staníc v stredne veľkom okruhu okolo centra mesta.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Spustiť veľkú reklamnú kampaň, ktorá priláka viac cestujúcich a nákladu k vašej spoločnosti.{}Zabezpečí dočasné zvýšenie hodnotenia staníc vo veľkom okruhu okolo centra mesta.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Financovať rekonštrukciu mestskej cestnej siete.{}Spôsobí dopravný chaos a zápchy trvajúce ďalších 6 mesiacov.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Postaviť sochu na počesť vašej spoločnosti.{}Zabezpečí trvalé zvýšenie hodnotenia staníc v tomto meste.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Financovať výstavbu nových budov v meste.{}Zabezpečí dočasné zrýchlenie rastu tohto mesta.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Zakúpiť exkluzívne dopravné práva v meste na 1 rok.{}Miestna správa nedovolí cestujúcim a nákladu používať stanice konkurentov.{}{POP_COLOUR}Cena: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Podplatiť miestnu správu pre zvýšenie hodnotenia vašej spoločnosti, s rizikom ťažkého postihu pri odhalení.{}{POP_COLOUR}Cena: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Ciele @@ -3680,24 +3724,38 @@ STR_FINANCES_CAPTION :{WHITE}Financie STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}Výnosy +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Prevádzkové náklady +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Kapitálové výdavky ###length 13 STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Výstavba STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Nové vozidlá -STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Prevádzka vlakov -STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Prevádzka cestných vozidiel -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Prevádzka lietadiel -STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Prevádzka lodí +STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Vlaky +STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Cestné vozidlá +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Lietadlá +STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Lode +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Infraštruktúra +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Vlaky +STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}Cestné vozidlá +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Lietadlá +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Lode STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Úroky STR_FINANCES_SECTION_OTHER :{GOLD}Ostatné -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} -STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_TOTAL_CAPTION :{WHITE}Spolu +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} +STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Zisk STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Zostatok na účte v banke +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Vlastné prostriedky STR_FINANCES_LOAN_TITLE :{WHITE}Úver +STR_FINANCES_INTEREST_RATE :{WHITE}Úroky: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maximálny úver: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Požičať {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Zvýšiť veľkosť úveru. Crtl+klik požičia koľko sa dá STR_FINANCES_REPAY_BUTTON :{BLACK}Splatiť {CURRENCY_LONG} @@ -3798,7 +3856,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produkuj STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Vyžaduje: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} čak{P á ajú á}{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Zmeniť produkciu (násobky 8, až do 2040) @@ -3827,7 +3885,9 @@ STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}Možnost STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Zadať príkazy všetkým vozidlám v zozname STR_VEHICLE_LIST_REPLACE_VEHICLES :Vymeniť vozidlá STR_VEHICLE_LIST_SEND_FOR_SERVICING :Vykonať servis -STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Profit tento rok: {CURRENCY_LONG} (minulý rok: {CURRENCY_LONG}) +STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Zisk tento rok: {CURRENCY_LONG} (minulý rok: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Poslať do depa STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Poslať do garáže @@ -3870,8 +3930,8 @@ STR_GROUP_REMOVE_ALL_VEHICLES :Odstrániť vš STR_GROUP_RENAME_CAPTION :{BLACK}Premenovať skupinu -STR_GROUP_PROFIT_THIS_YEAR :Profit v tomto roku: -STR_GROUP_PROFIT_LAST_YEAR :Profit v minulom roku: +STR_GROUP_PROFIT_THIS_YEAR :Zisk v tomto roku: +STR_GROUP_PROFIT_LAST_YEAR :Zisk v minulom roku: STR_GROUP_OCCUPANCY :Súčasné využitie: STR_GROUP_OCCUPANCY_VALUE :{NUM}% @@ -3919,6 +3979,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. tra STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Dolet: {GOLD}{COMMA} políčok STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Typ lietadla: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Všetky druhy nákladu +STR_CARGO_TYPE_FILTER_FREIGHT :Nákladné +STR_CARGO_TYPE_FILTER_NONE :Žiadne + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Výber vlakov. Pre získanie informácií klikni na vlak. CTRL+klik prepne skrytie typu vlaku. STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Výber cestných vozidiel. Pre získanie informácií klikni na vozidlo. CTRL+klik prepne skrytie typu vozidla. @@ -4087,7 +4152,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :{G=s}lietadlo STR_ENGINE_PREVIEW_SHIP :{G=z}loď STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cena: {CURRENCY_LONG} Hmotnosť: {WEIGHT_SHORT}{}Rýchlosť: {VELOCITY} Výkon: {POWER}{}Prevádzkové náklady: {CURRENCY_LONG}/rok{}Kapacita: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cena: {CURRENCY_LONG} Hmotnosť: {WEIGHT_SHORT}{}Rýchlosť: {VELOCITY} Sila: {POWER} Max. T.E.: {6:FORCE}{}Prevádzkové náklady: {4:CURRENCY_LONG}/yr{}Kapacita: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cena: {0:CURRENCY_LONG} Váha: {1:WEIGHT_SHORT}{}Rýchlosť: {2:VELOCITY} Výkon: {3:POWER} Max. trakčná sila: {6:FORCE}{}Prevádzkové náklady: {4:CURRENCY_LONG}/rok{}Kapacita: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Max. Rýchlosť: {VELOCITY}{}Kapacita: {CARGO_LONG}{}Prevádzkové náklady: {CURRENCY_LONG}/rok STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Rýchlosť: {VELOCITY}{}Typ lietadla: {STRING}{}Kapacita: {CARGO_LONG}, {CARGO_LONG}{}Prevádzkové náklady: {CURRENCY_LONG}/rok STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Rýchlosť: {VELOCITY}{}Typ lietadla: {STRING}{}Kapacita: {CARGO_LONG}{}Prevádzkové náklady: {CURRENCY_LONG}/rok @@ -4196,7 +4261,7 @@ STR_VEHICLE_VIEW_SHIP_STATE_STATUS_STOP_TOOLTIP :{BLACK}Činnos STR_VEHICLE_VIEW_AIRCRAFT_STATUS_START_STOP_TOOLTIP :{BLACK}Činnosť aktuálneho lietadla - kliknite na zastavenie/spustenie lietadla # Messages in the start stop button in the vehicle view -STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}Nakláda / Vykláda +STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}Nakladá / Vykladá STR_VEHICLE_STATUS_LEAVING :{LTBLUE}Opúšta STR_VEHICLE_STATUS_CRASHED :{RED}Zničené! STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}Pokazený @@ -4245,13 +4310,14 @@ STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Rýchlos STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Hmotnosť: {LTBLUE}{WEIGHT_SHORT} {BLACK}Sila: {LTBLUE}{POWER}{BLACK} Max. rýchlosť: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Hmotnosť: {LTBLUE}{WEIGHT_SHORT} {BLACK}Sila: {LTBLUE}{POWER}{BLACK} Max. rýchlosť: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} -STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Profit tento rok: {LTBLUE}{CURRENCY_LONG} (minulý rok: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Zisk v tomto roku: {LTBLUE}{CURRENCY_LONG} (minulý rok: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Zisk v tomto roku: {LTBLUE}{CURRENCY_LONG} (minulý rok: {CURRENCY_LONG}) {BLACK}Min. výkon: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Spoľahlivosť: {LTBLUE}{COMMA}% {BLACK}Poruchy od posledného servisu: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Vyrobený: {LTBLUE}{NUM}{BLACK} Cena: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Kapacita: {LTBLUE}Žiadna{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapacita: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapacita: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapacita: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Kapacita: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transfer kredity: {LTBLUE}{CURRENCY_LONG} @@ -4277,8 +4343,8 @@ STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Hodnota: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Celkový náklad (kapacita) tohto vlaku: -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}Prázdny STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} z {STATION} @@ -4455,7 +4521,7 @@ STR_ORDER_TRANSFER_NO_LOAD :(Prelož a nech STR_ORDER_NO_UNLOAD :(Nevykladaj a nalož) STR_ORDER_NO_UNLOAD_FULL_LOAD :(Nevykladaj a čakaj na plné naloženie) STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY :(Nevykladaj a čakaj na plné naloženie čohokoľvek) -STR_ORDER_NO_UNLOAD_NO_LOAD :(Žiadne vykládanie ani nakládanie) +STR_ORDER_NO_UNLOAD_NO_LOAD :(Žiadne vykladanie ani nakladanie) STR_ORDER_AUTO_REFIT :(Prestavať na {STRING}) STR_ORDER_FULL_LOAD_REFIT :(Plne nalož s prestavbou na {STRING}) @@ -4517,25 +4583,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Tento ce STR_TIMETABLE_STATUS_START_AT :{BLACK}Tento cestovný poriadok začne {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Začiatočný dátum -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Vyberte dátum začiatku cestovného poriadku. Ctrl+klik nastaví počiatočný dátum tohto cestovného poriadku pre všetky vozidlá zdieľajúce tieto príkazy na základe ich relatívneho poradia, ak je cestovný poriadok kompletne vyplnený +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Vyberte dátum začiatku cestovného poriadku. Ctrl+klik rozdelí od daného dátumu rovnomerne všetky vozidlá zdieľajúce tieto príkazy na základe ich relatívneho poradia, ak je cestovný poriadok kompletne vyplnený STR_TIMETABLE_CHANGE_TIME :{BLACK}Zmeniť čas -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Zmeniť dĺžku trvania označeného príkazu +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Zmeniť dĺžku trvania označeného príkazu. Ctrl+klik nastaví čas pre všetky príkazy STR_TIMETABLE_CLEAR_TIME :{BLACK}Odstrániť čas -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Odstrániť dĺžku trvania označeného príkazu +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Odstrániť dĺžku trvania označeného príkazu. Ctrl+klik vymaže čas pre všetky príkazy STR_TIMETABLE_CHANGE_SPEED :{BLACK}Zmeniť maximálnu rýchlosť -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Zmeniť maximálnu rýchlosť označeného príkazu +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Zmeniť maximálnu rýchlosť označeného príkazu. Ctrl+klik nastaví rýchlosť pre všetky príkazy STR_TIMETABLE_CLEAR_SPEED :{BLACK}Odstrániť rýchlostné obmedzenie -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Odstrániť obmedzenie maximánej rýchlosti označeného príkazu +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Odstrániť obmedzenie maximánej rýchlosti označeného príkazu. Ctrl+klik vymaže rýchlosť pre všetky príkazy STR_TIMETABLE_RESET_LATENESS :{BLACK}Reset meškania -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Vynulovať počítadlo meškania, takže vozidlo pôjde presne +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Vynulovať počítadlo meškania, takže vozidlo pôjde presne. Ctrl+klik vynuluje celú skupinu, takže posledné vozidlo bude bez meškania a ostatné prídu skôr STR_TIMETABLE_AUTOFILL :{BLACK}Automaticky vyplniť -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Vyplniť časový plán automaticky s hodnotami z nasledujúcej trasy (Ctrl+klik - pokúsiť sa udržať čakacie doby) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Vyplniť časový plán automaticky s hodnotami z nasledujúcej trasy. Ctrl+klik - pokúsiť sa udržať čakacie doby STR_TIMETABLE_EXPECTED :{BLACK}Očakávané STR_TIMETABLE_SCHEDULED :{BLACK}Plánované @@ -4579,12 +4645,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Jeden z STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Okno ladenia AI/skriptu je dostupné len pre server # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Nastavenia AI/skriptu +STR_AI_CONFIG_CAPTION_AI :{WHITE}Konfigurácia AI +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Konfigurácia skriptu STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Skript, ktorý bude načítaný v ďalšej hre STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AI, ktoré budú načítané v ďalšiej hre STR_AI_CONFIG_HUMAN_PLAYER :Človek STR_AI_CONFIG_RANDOM_AI :Náhodná AI STR_AI_CONFIG_NONE :(žiadne) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maximálny počet konkurentov: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Posunúť vyššie STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Posunúť vyššie vybrané AI v zozname @@ -4592,12 +4660,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Posunú STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Posunúť nižšie vybrané AI v zozname STR_AI_CONFIG_GAMESCRIPT :{SILVER}Herný skript +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametre STR_AI_CONFIG_AI :{SILVER}AI (umelá inteligencia) -STR_AI_CONFIG_CHANGE :{BLACK}Vybrať {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Skript +STR_AI_CONFIG_CHANGE_AI :{BLACK}Vyber AI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Vyber skript STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Spusti ďalší skript STR_AI_CONFIG_CONFIGURE :{BLACK}Nastaviť STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Nastaviť parametre skriptu @@ -4625,10 +4692,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Snímka STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Snímka výškovej mapy STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Snímka minimapy -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametre -STR_AI_SETTINGS_CAPTION_AI :Umelá inteligencia -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Skript +STR_AI_SETTINGS_CAPTION_AI :AI +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Herný skript STR_AI_SETTINGS_CLOSE :{BLACK}Zavrieť STR_AI_SETTINGS_RESET :{BLACK}Resetovať STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4792,6 +4859,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... prí STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Nemožno vygenerovať priemysel... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}{STRING} sa tu nedá postaviť... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Nemôžete tu postaviť tento typ priemyslu... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Nemôžem hľadať priemysel... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... príliš blízko iného priemyslu STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... najskôr je potrebné založiť mesto STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... povolené len jedno pre každé mesto @@ -4806,6 +4874,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... les STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... môže byť postavené len nad hranicou snehu STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... môže byť postavené len pod hranicou snehu +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Financovanie sa nepodarilo nájsť pre smolu; skúste to znova +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Nenašli sa žiadne vhodné miesta na vyhliadku pre toto odvetvie STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Nenašli sa žiadne vhodné miesta pre '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Pre získanie lepšej mapy zmeňte parametre jej generovania @@ -4973,6 +5043,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}V ceste STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... sídlo spoločnosti v ceste STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Tento pozemok nie je možné kúpiť... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... už to vlastníš! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... dosiahnutý stavebný limit objektu # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Nie je možné vytvoriť skupinu... @@ -5045,6 +5116,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Nemožno STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vozidlo je zničené +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... nie všetky vozidlá sú rovnaké + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Žiadne vozidlá nebudú k dispozícii STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Zmena vašej konfigurácie NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Zatiaľ nie sú dostupné žiadne vozidlá @@ -5071,6 +5144,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Nie je m STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... vozidlo nemôže ísť do všetkých staníc STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... vozidlo nemôže ísť do tejto stanice STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... vozidlo zdieľajúce tento príkaz nemôže ísť do stanice +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... nie všetky vozidlá majú rovnaké príkazy +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... nie všetky vozidlá zdieľajú príkazy STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Nemožno zdieľať zoznam príkazov ... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Nie je možné prestať zdieľať zoznam príkazov... @@ -5078,6 +5153,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Nemožno STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... príliš ďaleko z predchádzajúceho cieľa STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... lietadlo nemá dostatočný dosah +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Nenašla sa žiadna železničná stanica +STR_ERROR_NO_BUS_STATION :{WHITE}Nenašla sa žiadna autobusová stanica +STR_ERROR_NO_TRUCK_STATION :{WHITE}Nenašla sa žiadna nakladacia rampa +STR_ERROR_NO_DOCK :{WHITE}Nenašiel sa žiadny prístav +STR_ERROR_NO_AIRPORT :{WHITE}Nenašlo sa žiadne letisko/heliport +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Nenašli sa žiadne zastávky s kompatibilným typom cesty +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Nenašli sa žiadne zastávky s kompatibilným typom električky +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Nenašli sa žiadne zastávky vhodné pre kĺbové cestné vozidlá.{}Kĺbové cestné vozidlá vyžadujú prejazdovú zastávku, nie zastávku v zálive +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Toto lietadlo nemôže pristáť na tomto heliporte +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Táto helikoptéra nemôže pristáť na tomto letisku +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Nenašiel sa žiadny železničný smerový bod +STR_ERROR_NO_BUOY :{WHITE}Nenašla sa žiadna bója + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Vozidlu nie je možné zadať cestovný poriadok ... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Vozidlá možu cakat len v staniciach. diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index 249509bdd855e..0484a7ebab583 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -350,6 +350,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}KM STR_UNITS_POWER_METRIC :{COMMA}KM STR_UNITS_POWER_SI :{COMMA} kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA} t STR_UNITS_WEIGHT_SHORT_SI :{COMMA} kg @@ -528,10 +529,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Izhod # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Možnosti igre STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Nastavitve -STR_SETTINGS_MENU_SCRIPT_SETTINGS :UI/Nastavitve skriptov igre STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF nastavitve STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Nastavitve prozornega pogleda STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Imena mest prikazana @@ -1081,36 +1081,6 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Gruzijski Lari STR_GAME_OPTIONS_CURRENCY_IRR :Iranski Rial (IRR) STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kongški dolar (HKD) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Vožnja po levi -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Vožnja po desni - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Imena mest -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Izberi slog imena mest - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Angleška (Originalna) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francoska -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Nemška -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Angleška (Dodatna) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latinsko-Ameriška -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Butasta -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Švedska -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Nizozemska -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finska -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Poljska -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovaška -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norveška -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Madžarska -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Avstrijska -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romunska -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Češka -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Švicarska -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danska -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turška -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italijanska -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalonska - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Samodejno shrani STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Izberi časovni interval samodejnega shranjevanja igre @@ -1135,16 +1105,9 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :drugo -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Velikost vmesnika -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Izberi velikost elementa vmesnika -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normalno -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dvojna velikost -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Velikost kvadrata -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(samodejno zaznaj) - STR_GAME_OPTIONS_BASE_GRF :{BLACK}Osnovni komplet grafik @@ -1190,8 +1153,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Predogl STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 funtov (£) v tvoji valuti STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Zamenjaj parameter valute po meri -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Največje število tekmecev: {ORANGE}{COMMA} - STR_NONE :Brez STR_FUNDING_ONLY :Samo financiranje STR_MINIMAL :Minimalno @@ -1241,6 +1202,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Zmerno podnebje +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub arktično podnebje +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub tropsko podnebje +STR_CLIMATE_TOYLAND_LANDSCAPE :Pokrajina v deželi igrač + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Zelo raven STR_TERRAIN_TYPE_FLAT :Raven @@ -1314,6 +1281,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Desno STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Najvišje začetno posojilo: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Najvišji znesek, ki si ga podjetje lahko izposodi (ni vključen izračun inflacije) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Obrestna mera: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Obrestna mera; kontrolira tudi inflacijo, če je omogočena. @@ -1574,6 +1542,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Izboljšan STR_CONFIG_SETTING_ROAD_SIDE :Cestna vozila: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Izberi stran vožnje +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Vožnja po levi +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Vožnja po desni + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Zasuk višinskega zemljevida: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Nasprotno urini smeri @@ -2053,7 +2025,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Avtomatično ob STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Dovoli vlakom obračanje na signalih, če so tam čakali že dolgo. ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Priporočeno) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Priporočeno) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Spremeni vrednost @@ -2094,7 +2066,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Tabela n STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Nastavitve STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF nastavitve STR_INTRO_ONLINE_CONTENT :{BLACK}Preveri razpoložljive vsebine -STR_INTRO_SCRIPT_SETTINGS :{BLACK}UI / Nastavitve skriptov igre STR_INTRO_QUIT :{BLACK}Izhod STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Začni novo igro. Ctrl+Klik preskoči konfiguracijo sveta @@ -2114,7 +2085,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Prikaži STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Nastavitve zaslona STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Prikaži nastavitve NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Preveri posodobljene vsebine na strežniku,{} ki so na voljo za prenos -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Prikaži UI in Nastavitve skriptov igre STR_INTRO_TOOLTIP_QUIT :{BLACK}Izhod iz 'OpenTTD' STR_INTRO_TRANSLATION :{BLACK}Temu prevodu manjka {NUM} vnos{P "" a i ov}. Prosimo pomagaj izboljšati OpenTTD in se vpiši za prevajanje. Preveri readme.txt za podrobnosti. @@ -2143,12 +2113,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Spremen STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Spremeni trenutno leto STR_CHEAT_SETUP_PROD :{LTBLUE}Omogoči spreminjanje proizvodnih vrednosti: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Zmerno podnebje -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub arktično podnebje -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub tropsko podnebje -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Pokrajina v deželi igrač - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Barvna shema @@ -2553,6 +2517,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}nasičeno STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}prenasičeno +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Osvetlitev območja zajema STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Izključeno @@ -2641,8 +2607,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Povečaj STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Izberi železniski most STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Izberi cestni most STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Izbira mostu - klikni na željeni most za izgradnjo -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Viseč, Jeklen STR_BRIDGE_NAME_GIRDER_STEEL :Nosilni, Jeklen STR_BRIDGE_NAME_CANTILEVER_STEEL :Nosilni križi, Jeklen @@ -2998,16 +2962,40 @@ STR_MAPGEN_MAPSIZE :{BLACK}Velikost STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Izberi velikost zemljevida v ploščah. Število plošč na voljo bo nekoliko nižje. STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Število mest: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Imena mest +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Izberi slog imena mest STR_MAPGEN_DATE :{BLACK}Datum: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Število industrij: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Ustvarjalec terena: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tip terena: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Morska gladina: +STR_MAPGEN_SEA_LEVEL :{BLACK}Morska gladina: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Reke: STR_MAPGEN_SMOOTHNESS :{BLACK}Glajenje: STR_MAPGEN_VARIETY :{BLACK}Raznolika distribucija: STR_MAPGEN_GENERATE :{WHITE}Ustvari +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Angleška (Originalna) +STR_MAPGEN_TOWN_NAME_FRENCH :Francoska +STR_MAPGEN_TOWN_NAME_GERMAN :Nemška +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Angleška (Dodatna) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latinsko-Ameriška +STR_MAPGEN_TOWN_NAME_SILLY :Butasta +STR_MAPGEN_TOWN_NAME_SWEDISH :Švedska +STR_MAPGEN_TOWN_NAME_DUTCH :Nizozemska +STR_MAPGEN_TOWN_NAME_FINNISH :Finska +STR_MAPGEN_TOWN_NAME_POLISH :Poljska +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovaška +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norveška +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Madžarska +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Avstrijska +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romunska +STR_MAPGEN_TOWN_NAME_CZECH :Češka +STR_MAPGEN_TOWN_NAME_SWISS :Švicarska +STR_MAPGEN_TOWN_NAME_DANISH :Danska +STR_MAPGEN_TOWN_NAME_TURKISH :Turška +STR_MAPGEN_TOWN_NAME_ITALIAN :Italijanska +STR_MAPGEN_TOWN_NAME_CATALAN :Katalonska + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Robovi ozemlja: STR_MAPGEN_NORTHWEST :{BLACK}Severozahod @@ -3143,6 +3131,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Prejšnj STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Nadaljuj k prejšnji navadni sličici, zanemari vse navidezne/pobarvane/besedilne sličice in okvir na koncu STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Predstavitev trenutno izbrane sličice. Zamik je zanemarjen pri risanju te sličice STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Premakni sličico naokrog s spreminjanjem X in Y osi. Ctrl-Klik za premik sličice 8 enot v koraku + +###length 2 + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Resetiraj relativno STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Resetiraj zdajšne relativne odmike STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X odmik: {NUM}, Y odmik: {NUM} (Absolutno) @@ -3157,7 +3149,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Pozor: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Napaka: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Usodno: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Zgodila se je usodna NewGRF napaka:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} ne deluje s TTDPatch različico prijavljeno v OpenTTD STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} je za {STRING} različico TTD-ja STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} je izdelano za uporabo v {STRING} kombinaciji @@ -3654,6 +3645,8 @@ STR_PURCHASE_INFO_ALL_BUT :Vse, razen {CAR STR_PURCHASE_INFO_MAX_TE :{BLACK}Največja vlečna moč: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Domet: {GOLD}{COMMA} polj +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Seznam železniških vozil - klikni na vozilo za informacije STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Seznam cestnih vozil - klikni na vozilo za informacije @@ -4278,12 +4271,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Ena izme STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Okno razhroščevanja UI / skripte je na voljo samo za strežnik # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Nastavitve UI / skript igre STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Skript igre, ki bo naložen v naslednji igri STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}UI, ki bodo naložene v naslednji igri STR_AI_CONFIG_HUMAN_PLAYER :Igralec STR_AI_CONFIG_RANDOM_AI :Naključni UI STR_AI_CONFIG_NONE :(brez) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Največje število tekmecev: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Premakni višje STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Premakni izbran UI višje po seznamu @@ -4293,8 +4286,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Premakni STR_AI_CONFIG_GAMESCRIPT :{SILVER}Skripta igre STR_AI_CONFIG_AI :{SILVER}UI-ji -STR_AI_CONFIG_CHANGE :{BLACK}Izberi {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :UI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Skripta igre STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Naloži drugi skript @@ -4317,10 +4308,8 @@ STR_AI_LIST_CANCEL :{BLACK}Preklič STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ne spremeni skripte -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametri +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :UI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Skripta igre STR_AI_SETTINGS_CLOSE :{BLACK}Zapri STR_AI_SETTINGS_RESET :{BLACK}Resetiraj STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4726,6 +4715,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Ni mogo STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vozilo je uničeno + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Sploh ni razpoložljivih vozil STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Zamenjaj svojo NewGRF konfiguracijo STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Ni še vozil na razpolago. @@ -4759,6 +4749,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Ni mogo STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... predaleč od prejšnjega cilja STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... letalo nima dovolj dometa +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Ni mogoče določiti časa vozilu... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Vozila lahko čakajo le na postajah diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 8bdca47f1e399..2282c597ffdc2 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}cv STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}cv/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}cv/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}cv/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -226,9 +236,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Patrón de filtrado: -STR_LIST_FILTER_OSKTITLE :{BLACK}Escribe un patrón de filtrado -STR_LIST_FILTER_TOOLTIP :{BLACK}Introduzca una palabra clave para filtrar la lista +STR_LIST_FILTER_TITLE :{BLACK}Filtro: +STR_LIST_FILTER_OSKTITLE :{BLACK}Introduce texto para filtrar +STR_LIST_FILTER_TOOLTIP :{BLACK}Introduce una o varias palabras clave para filtrar la lista STR_TOOLTIP_GROUP_ORDER :{BLACK}Selecciona la orden de agrupamiento STR_TOOLTIP_SORT_ORDER :{BLACK}Selecciona el orden de clasificación (descendiente/ascendiente) @@ -317,7 +327,7 @@ STR_SORT_BY_RANGE :Alcance STR_SORT_BY_POPULATION :Población STR_SORT_BY_RATING :Calificación STR_SORT_BY_NUM_VEHICLES :Número de vehículos -STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR :Beneficio total del último año +STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR :Beneficio total del año anterior STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR :Beneficio total este año STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :Beneficio medio el año pasado STR_SORT_BY_AVERAGE_PROFIT_THIS_YEAR :Beneficio medio este año @@ -377,9 +387,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Creació STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Generación de industria STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Construcción de carreteras STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Construcción de tranvía -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantar árboles. Mayús permite mostrar una estimación del precio +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantar árboles. Ctrl permite seleccionar un área diagonalmente. Mayús permite mostrar una estimación del precio STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Colocar letrero -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar objeto. Mayús permite mostrar una estimación del precio +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar objeto. Ctrl permite seleccionar un área diagonalmente. Mayús permite mostrar una estimación del precio # Scenario editor file menu ###length 7 @@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Salir # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Opciones de juego STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Configuración -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Configuración de Scripts +STR_SETTINGS_MENU_AI_SETTINGS :Configuración de IA +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :{BLACK}Configuración de script de juego STR_SETTINGS_MENU_NEWGRF_SETTINGS :Configuración NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opciones de transparencia STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Ver nombres de municipios @@ -437,14 +448,14 @@ STR_SUBSIDIES_MENU_SUBSIDIES :Subvenciones STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH :Gráfica de beneficio operativo STR_GRAPH_MENU_INCOME_GRAPH :Gráfica de ingresos STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH :Gráfica de carga entregada -STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH :Gráfica de rendimiento +STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH :Gráfica de desempeño STR_GRAPH_MENU_COMPANY_VALUE_GRAPH :Gráfica del valor de la empresa -STR_GRAPH_MENU_CARGO_PAYMENT_RATES :Tarifas de pagos por carga +STR_GRAPH_MENU_CARGO_PAYMENT_RATES :Tarifas de pago de cargas # Company league menu ###length 3 STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE :Tabla de clasificación de empresas -STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING :Detalles del rendimiento +STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING :Calificación detallada de desempeño STR_GRAPH_MENU_HIGHSCORE :Tabla de puntuaciones # Industry menu @@ -494,7 +505,7 @@ STR_NEWS_MENU_DELETE_ALL_MESSAGES :Borrar todos lo STR_ABOUT_MENU_LAND_BLOCK_INFO :Información del terreno STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Activar consola -STR_ABOUT_MENU_AI_DEBUG :Depuración de Script de juego / IA +STR_ABOUT_MENU_AI_DEBUG :Depuración de script de juego/IA STR_ABOUT_MENU_SCREENSHOT :Captura de pantalla STR_ABOUT_MENU_SHOW_FRAMERATE :Mostrar fotogramas por segundo - FPS STR_ABOUT_MENU_ABOUT_OPENTTD :Acerca de 'OpenTTD' @@ -592,20 +603,20 @@ STR_GRAPH_Y_LABEL_NUMBER :{TINY_FONT}{COM STR_GRAPH_OPERATING_PROFIT_CAPTION :{WHITE}Gráfica de Beneficio Operativo STR_GRAPH_INCOME_CAPTION :{WHITE}Gráfica de Ingresos STR_GRAPH_CARGO_DELIVERED_CAPTION :{WHITE}Unidades de carga entregadas -STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION :{WHITE}Calificaciones de rendimiento de empresas (máximo=1000) +STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION :{WHITE}Nivel de desempeño de empresas (máximo=1000) STR_GRAPH_COMPANY_VALUES_CAPTION :{WHITE}Valor de la empresa -STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Tarifa de pago por carga +STR_GRAPH_CARGO_PAYMENT_RATES_CAPTION :{WHITE}Tarifas de pago de cargas STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL :{TINY_FONT}{BLACK}Días en tránsito -STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Pago por entregar 10 unidades (o 1,000 litros) de carga a una distancia de 20 casillas +STR_GRAPH_CARGO_PAYMENT_RATES_TITLE :{TINY_FONT}{BLACK}Pago por entregar 10 unidades (o 10 000 litros) de carga a una distancia de 20 casillas STR_GRAPH_CARGO_ENABLE_ALL :{TINY_FONT}{BLACK}Activar todos STR_GRAPH_CARGO_DISABLE_ALL :{TINY_FONT}{BLACK}Desactivar todos -STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}Mostrar todos los tipos de carga en la gráfica de tarifas de pagos por carga -STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Ocultar todos los tipos de carga en la gráfica de tarifas de pagos por carga -STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Mostrar/Ocultar gráfica para este tipo de carga +STR_GRAPH_CARGO_TOOLTIP_ENABLE_ALL :{BLACK}Muestra todos los tipos de carga en la gráfica de tarifas de pago de cargas +STR_GRAPH_CARGO_TOOLTIP_DISABLE_ALL :{BLACK}Oculta todos los tipos de carga en la gráfica de tarifas de pago de cargas +STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO :{BLACK}Alterna entre mostrar/ocultar la gráfica para este tipo de carga STR_GRAPH_CARGO_PAYMENT_CARGO :{TINY_FONT}{BLACK}{STRING} -STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Muestra detalles del rendimiento +STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP :{BLACK}Muestra detalles del nivel de desempeño # Graph key window STR_GRAPH_KEY_CAPTION :{WHITE}Leyenda de las gráficas @@ -625,21 +636,21 @@ STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_PRESIDENT :Presidente STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TYCOON :Magnate # Performance detail window -STR_PERFORMANCE_DETAIL :{WHITE}Detalle de rendimiento +STR_PERFORMANCE_DETAIL :{WHITE}Detalle de nivel de desempeño STR_PERFORMANCE_DETAIL_KEY :{BLACK}Detalle STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY :{BLACK}({CURRENCY_SHORT}/{CURRENCY_SHORT}) STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA}/{COMMA}) STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}% -STR_PERFORMANCE_DETAIL_SELECT_COMPANY_TOOLTIP :{BLACK}Mostrar detalles de esta empresa +STR_PERFORMANCE_DETAIL_SELECT_COMPANY_TOOLTIP :{BLACK}Muestra detalles para esta empresa ###length 10 STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Vehículos: STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Estaciones: STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Beneficio Mín.: -STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Ingreso Mín.: -STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Ingreso Máx.: +STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Beneficio Mín.: +STR_PERFORMANCE_DETAIL_MAX_INCOME :{BLACK}Beneficio Máx.: STR_PERFORMANCE_DETAIL_DELIVERED :{BLACK}Entregado: -STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Carga: +STR_PERFORMANCE_DETAIL_CARGO :{BLACK}Cargas: STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Dinero: STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Préstamo: STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total: @@ -647,14 +658,14 @@ STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total: ###length 10 STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP :{BLACK}Cantidad de vehículos que obtuvieron beneficios el año pasado. Incluye vehículos de carretera, trenes, barcos y aeronaves STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP :{BLACK}Cantidad de partes de estación que han tenido servicio. Las estaciones de tren, paradas de autobús, aeropuertos y demás son contabilizadas por separado, incluso si pertenecen a la misma estación -STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP :{BLACK}Beneficio del vehículo con menores ingresos (considerando sólo vehículos con más de 2 años) -STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Cantidad de dinero ganado en el trimestre con el beneficio más bajo de los pasados 12 trimestres -STR_PERFORMANCE_DETAIL_MAX_INCOME_TOOLTIP :{BLACK}Cantidad de dinero ganado en el trimestre con el beneficio más alto de los pasados 12 trimestres -STR_PERFORMANCE_DETAIL_DELIVERED_TOOLTIP :{BLACK}Unidades de carga entregadas en los pasados cuatro trimestres +STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP :{BLACK}Beneficio del vehículo menos rentable (considerando sólo vehículos con más de 2 años) +STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Cantidad de dinero ganado en el trimestre con el menor beneficio de los últimos 12 trimestres +STR_PERFORMANCE_DETAIL_MAX_INCOME_TOOLTIP :{BLACK}Cantidad de dinero ganado en el trimestre con el mayor beneficio de los últimos 12 trimestres +STR_PERFORMANCE_DETAIL_DELIVERED_TOOLTIP :{BLACK}Unidades de carga entregadas en los cuatro últimos trimestres STR_PERFORMANCE_DETAIL_CARGO_TOOLTIP :{BLACK}Número de tipos de carga entregados en el último trimestre STR_PERFORMANCE_DETAIL_MONEY_TOOLTIP :{BLACK}Cantidad de dinero que esta empresa tiene en el banco STR_PERFORMANCE_DETAIL_LOAN_TOOLTIP :{BLACK}Cantidad de dinero que esta empresa ha recibido como préstamo -STR_PERFORMANCE_DETAIL_TOTAL_TOOLTIP :{BLACK}Total de puntos ganados del máximo posible +STR_PERFORMANCE_DETAIL_TOTAL_TOOLTIP :{BLACK}Total de puntos obtenidos del máximo posible # Music window STR_MUSIC_JAZZ_JUKEBOX_CAPTION :{WHITE}Selección de Jazz @@ -966,36 +977,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rupia india (IN STR_GAME_OPTIONS_CURRENCY_IDR :Rupia indonesia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit malasio (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Conducir por la izquierda -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Conducir por la derecha - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nombres de municipios: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Selección del estilo del nombre de los municipios - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Inglés -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francés -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Alemán -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Inglés (Adicional) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latinoamericano -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Tontos/Absurdos -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Sueco -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holandés -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandés -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polaco -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Eslovaco -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Noruego -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Húngaro -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austríaco -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumano -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Checo -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Suizo -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danés -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turco -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiano -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalán - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Autoguardado STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selección del intervalo entre guardados automáticos del juego @@ -1012,7 +993,7 @@ STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Seleccio STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM}% completo) STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Pantalla completa -STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Marca esta opción para jugar OpenTTD a pantalla completa +STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Marca esta casilla para jugar OpenTTD a pantalla completa STR_GAME_OPTIONS_RESOLUTION :{BLACK}Resolución de pantalla STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}Selecciona la resolución de pantalla a usar @@ -1028,21 +1009,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Marca es STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Controlador actual: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Tamaño de la interfaz -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Selecciona el tamaño de los elementos de la interfaz a usar +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Tamaño de la interfaz +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Mueve el control deslizante para seleccionar el tamaño de la interfaz. Presiona Ctrl para seleccionar de forma continua +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Autodetectar tamaño +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marca esta casilla para detectar automáticamente el tamaño de la interfaz -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(autodetectar) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Tamaño doble -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Tamaño cuádruple +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Escalar bordes +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marca esta casilla para escalar los bordes según el tamaño de la interfaz -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Tamaño de fuente -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Selecciona el tamaño de fuente a utilizar en la interfaz - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(autodetectar) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Tamaño doble -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Tamaño cuádruple +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Gráficos @@ -1090,12 +1069,10 @@ STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Configur STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Cambia al Euro antes STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Cambia al Euro después -STR_CURRENCY_PREVIEW :{LTBLUE}Previa: {ORANGE}{CURRENCY_LONG} +STR_CURRENCY_PREVIEW :{LTBLUE}Vista preliminar: {ORANGE} {CURRENCY_LONG} STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Libras(£) en tu moneda STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Cambiar parámetro de moneda personalizada -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Núm. máximo de jugadores: {ORANGE}{COMMA} - STR_NONE :Ninguno STR_FUNDING_ONLY :Solo fundadas STR_MINIMAL :Mínimo @@ -1145,6 +1122,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Terreno templado +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Terreno subártico +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Terreno subtropical +STR_CLIMATE_TOYLAND_LANDSCAPE :Terreno juguetelandia + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Muy llano STR_TERRAIN_TYPE_FLAT :Llano @@ -1155,7 +1138,7 @@ STR_TERRAIN_TYPE_CUSTOM :Altura personal STR_TERRAIN_TYPE_CUSTOM_VALUE :Altura personalizada ({NUM}) ###length 4 -STR_CITY_APPROVAL_LENIENT :Tolerante +STR_CITY_APPROVAL_LENIENT :Indulgente STR_CITY_APPROVAL_TOLERANT :Tolerante STR_CITY_APPROVAL_HOSTILE :Hostil STR_CITY_APPROVAL_PERMISSIVE :Permisiva (sin efecto sobre las acciones de las compañías) @@ -1164,7 +1147,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}No se ha # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Configuración -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Patrón de filtrado: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtro: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Expandir todos STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Colapsar todos STR_CONFIG_SETTING_RESET_ALL :{BLACK}Restablecer valores @@ -1224,6 +1207,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Derecha STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Préstamo máximo inicial: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Cantidad máxima que una empresa puede recibir como préstamo (sin tener en cuenta la inflación) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Sin préstamo {RED} Se necesita un script de juego para proporcionar fondos iniciales STR_CONFIG_SETTING_INTEREST_RATE :Porcentaje de interés: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Porcentaje de interés de los préstamos; también controla la inflación, en caso de que esté activada @@ -1450,6 +1436,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Grosor de las l STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Mostrar el nombre del NewGRF en la ventana de compra de vehículos: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Añade una línea a la ventana de compra de vehículos, mostrando a qué NewGRF pertenece el vehículo seleccionado. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Mostrar las cargas que pueden llevar los vehículos en las ventanas con listas {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Si se activa, las cargas que los vehículos pueden transportar aparecerán encima de éstos en las listas de vehículos STR_CONFIG_SETTING_LANDSCAPE :Terreno: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Los terrenos definen escenarios con diferentes tipos de carga y requisitos de crecimiento de municipios. Es posible modificarlos empleando NewGRF y scripts de juego @@ -1504,6 +1492,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Mejorado STR_CONFIG_SETTING_ROAD_SIDE :Vehículos de carretera: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Selecciona el lado de conducción +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Conducir por la izquierda +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Conducir por la derecha + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotación del Mapa de alturas: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Sentido antihorario @@ -1628,7 +1620,7 @@ STR_CONFIG_SETTING_TIMETABLE_IN_TICKS :Mostrar horario STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT :Muestra los tiempos de viaje en los horarios en tics en lugar de en días STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :Mostrar salidas y llegadas en los horarios: {STRING} -STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Muestra tiempos de llegada y salida adelantados en los horarios +STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Muestra fechas de llegada y salida previstas en los horarios STR_CONFIG_SETTING_QUICKGOTO :Creación rápida de órdenes para vehículos: {STRING} STR_CONFIG_SETTING_QUICKGOTO_HELPTEXT :Preselecciona el cursor "Ir a" al abrir la ventana de órdenes @@ -1704,7 +1696,7 @@ STR_CONFIG_SETTING_AI_BUILDS_SHIPS :Desactivar barc STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :Activa esta opción para deshabilitar la construcción de barcos para las IA STR_CONFIG_SETTING_AI_PROFILE :Perfil por defecto: {STRING} -STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Selecciona el perfil a usar para IA aleatorias o para los valores iniciales cuando se añade una nueva IA o un Script de juego +STR_CONFIG_SETTING_AI_PROFILE_HELPTEXT :Selecciona el perfil a usar para IA aleatorias o para los valores iniciales cuando se añade una nueva IA o un script de juego ###length 3 STR_CONFIG_SETTING_AI_PROFILE_EASY :Fácil STR_CONFIG_SETTING_AI_PROFILE_MEDIUM :Intermedio @@ -1937,11 +1929,11 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Usar {STRING}{N STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tiempo a emplear en el cálculo de cada uno de los componentes del grafo de distribución. Cuanto menor sea este valor, más probable es que se produzca ralentización en el juego. Cuanto mayor sea, más tiempo tardará la distribución en actualizarse cuando se producen cambios en las rutas. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modo de distribución para pasajeros: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :En una distribución "simétrica", se envía la misma cantidad de pasajeros de la estación A a la B que de la B a la A. En una distribución "asimétrica" se pueden enviar cantidades arbitrarias de pasajeros en ambas direcciones. "Manual" significa que no se realiza una distribución automática para los pasajeros +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :En una distribución "Simétrica", se envía la misma cantidad de pasajeros de la estación A a la B que de la B a la A. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de pasajeros en ambas direcciones. "Manual" significa que no se realiza una distribución automática para los pasajeros. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Modo de distribución para el correo: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :En una distribución "simétrica", se envía la misma cantidad de carga de la estación A a la B que de la B a la A. En una distribución "asimétrica" se pueden enviar cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no se realiza una distribución automática para el correo +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :En una distribución "Simétrica", se envía la misma cantidad de carga de la estación A a la B que de la B a la A. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no se realiza una distribución automática para el correo. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Modo de distribución para la clase de carga BLINDADA: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La clase de carga BLINDADA contiene objetos de valor en el clima templado, diamantes en el clima subtropical y oro en el clima subártico. Los NewGRFs pueden modificar esto. En una distribución "simétrica", se envía la misma cantidad de carga de la estación A a la B que de la B a la A. En una distribución "asimétrica" se pueden enviar cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no se realiza una distribución automática para esta carga. Se recomienda fijar esta distribución en "asimétrica" o en "manual" al jugar en clima subártico, ya que así los bancos no enviarán oro de vuelta a sus minas de procedencia. En los climas templado y subtropical es factible escoger "simétrica" ya que los bancos pueden enviar de vuelta objetos de valor al banco origen de los mismos. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :El tipo de carga BLINDADA contiene objetos de valor en el clima templado, diamantes en el clima subtropical y oro en el clima subártico. Los NewGRFs pueden modificar esto. En una distribución "Simétrica", se envía la misma cantidad de carga de la estación A a la B que de la B a la A. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no se realiza una distribución automática para esta carga. Se recomienda fijar esta distribución en "Asimétrica" o en "Manual" al jugar en los clima subártico y subtropical, ya que los bancos sólo reciben carga en esos climas. En el clima templado es factible escoger "Simétrica" ya que los bancos pueden enviar objetos de valor de vuelta al banco de origen. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modo de distribución para otras clases de carga: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimétrico" significa que se pueden mover cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no habrá distribución automática para estos tipos de carga. ###length 3 @@ -2004,7 +1996,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrico (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) STR_CONFIG_SETTING_LOCALISATION :{ORANGE}Localización -STR_CONFIG_SETTING_GRAPHICS :{ORANGE}Gráficas +STR_CONFIG_SETTING_GRAPHICS :{ORANGE}Gráficos STR_CONFIG_SETTING_SOUND :{ORANGE}Efectos de sonido STR_CONFIG_SETTING_INTERFACE :{ORANGE}Interfaz STR_CONFIG_SETTING_INTERFACE_GENERAL :{ORANGE}General @@ -2038,7 +2030,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Cambio de senti STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Permite a los trenes darse la vuelta ante una señal, si han esperado durante un tiempo lo suficientemente largo ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomendado) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recomendado) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Cambiar valor de la opción @@ -2081,7 +2073,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Tabla de STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Configuración STR_INTRO_NEWGRF_SETTINGS :{BLACK}Configuración NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Contenido Online -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Configuración de Scripts +STR_INTRO_AI_SETTINGS :{BLACK}Configuración de IA +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Scripts de Juego STR_INTRO_QUIT :{BLACK}Salir STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Comeenza una partida nueva. Ctrl+clic omite la configuración del escenario @@ -2099,9 +2092,10 @@ STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Seleccio STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Muestra las opciones de juego STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Muestra la tabla de puntuaciones STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Muestra la configuración -STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Muestra los ajustes de NewGRF +STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Muestra la configuración de NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Comprueba si hay contenidos nuevos y actualizados para descargar -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Muestra la configuración de Scripts de juego e IA +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Muestra la configuración de IA +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Muestra la configuración de script de juego STR_INTRO_TOOLTIP_QUIT :{BLACK}Salir de 'OpenTTD' STR_INTRO_BASESET :{BLACK}El conjunto de gráficos base actualmente seleccionado no encuentra {NUM} sprite{P "" s}. Comprueba si hay actualizaciones para el conjunto base, o usa otro totalmente actualizado. @@ -2133,12 +2127,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Cambiar STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Cambiar año actual STR_CHEAT_SETUP_PROD :{LTBLUE}Permitir modificar los valores de producción: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Terreno templado -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Terreno subártico -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Terreno subtropical -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Terreno juguetelandia - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Esquema de Color @@ -2371,7 +2359,6 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nueva empresa) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Crea una nueva empresa y te une a ella STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Éste eres tú STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Éste es el servidor de la partida -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s} / {NUM} empresa{P "" s} # Matches ConnectionType ###length 5 @@ -2498,13 +2485,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :esperando actua STR_NETWORK_MESSAGE_CLIENT_LEAVING :abandonando STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} se ha unido a la partida -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} se ha unido a la partida (Cliente #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} se ha unido a la empresa #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} se ha unido a la partida (Cliente #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} se ha unido a la empresa #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} se ha unido como espectador -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} ha creado una empresa nueva (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} ha abandonado el juego ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} ha creado una empresa nueva (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} ha abandonado el juego ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} ha cambiado su nombre a {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} ha dado {2:CURRENCY_LONG} a {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} ha transferido {2:CURRENCY_LONG} a {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}El servidor ha cerrado la sesión STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}El servidor está reiniciando...{}Espera por favor... STR_NETWORK_MESSAGE_KICKED :*** {STRING} ha sido expulsado. Razón: ({STRING}) @@ -2525,13 +2512,13 @@ STR_CONTENT_SELECT_ALL_CAPTION :{BLACK}Seleccio STR_CONTENT_SELECT_ALL_CAPTION_TOOLTIP :{BLACK}Marca todo el contenido para descarga STR_CONTENT_SELECT_UPDATES_CAPTION :{BLACK}Seleccionar actualizaciones STR_CONTENT_SELECT_UPDATES_CAPTION_TOOLTIP :{BLACK}Marca para descargar todo el contenido que es una actualizacion del contenido existente -STR_CONTENT_UNSELECT_ALL_CAPTION :{BLACK}Desmarcar todas -STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP :{BLACK}Marca todo el contenido para no ser descargado +STR_CONTENT_UNSELECT_ALL_CAPTION :{BLACK}Deseleccionar todo +STR_CONTENT_UNSELECT_ALL_CAPTION_TOOLTIP :{BLACK}Selecciona todo el contenido para no ser descargado STR_CONTENT_SEARCH_EXTERNAL :{BLACK}Buscar en páginas externas STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP :{BLACK}Busca contenido no disponible en el servicio de contenido de OpenTTD en páginas externas no asociadas con OpenTTD STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}¡Estás abandonando OpenTTD! STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER :{WHITE}Los términos y condiciones para descargar contenido de páginas externas varían.{}Será necesario consultar dichas páginas para obtener instrucciones de cómo instalar el contenido en OpenTTD.{}¿Desea continuar? -STR_CONTENT_FILTER_TITLE :{BLACK}Etiqueta/nombre del filtro +STR_CONTENT_FILTER_TITLE :{BLACK}Filtro de etiqueta/nombre: STR_CONTENT_OPEN_URL :{BLACK}Visitar web STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Visitar la página web de este contenido STR_CONTENT_DOWNLOAD_CAPTION :{BLACK}Descargar @@ -2607,7 +2594,7 @@ STR_TRANSPARENT_LOADING_TOOLTIP :{BLACK}Ajustar STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Establece los objetos como invisibles en vez de transparentes # Linkgraph legend window -STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Leyenda de Flujos de Carga +STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Leyenda de flujos de carga STR_LINKGRAPH_LEGEND_ALL :{BLACK}Todas STR_LINKGRAPH_LEGEND_NONE :{BLACK}Ninguna STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Seleccione las empresas a mostrar @@ -2618,6 +2605,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}saturado STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}sobrecargado +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} para ser transportad{G 0 o a}{P 0 "" s} al mes desde {STATION} a {STATION} ({COMMA}% de la capacidad){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} para ser transportad{G 0 o a}{P 0 "" s} de vuelta ({COMMA}% de la capacidad) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Tiempo de viaje promedio: {NUM}{NBSP}día{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Mostrar área de cobertura STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Desactivado @@ -2626,6 +2618,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Oculta e STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Muestra área de cobertura del lugar propuesto STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Acepta: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Suministra: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Coste de mantenimiento: {GOLD}{CURRENCY_SHORT}/año # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Unir estación @@ -2708,8 +2701,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Incremen STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Selección de Puente de Ferrocarril STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Selección de Cuente de Carretera STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Selección de puente - Clica en el puente elegido para construirlo -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Colgante, Acero STR_BRIDGE_NAME_GIRDER_STEEL :Tirantes, Acero STR_BRIDGE_NAME_CANTILEVER_STEEL :Cantiléver, Acero @@ -2813,11 +2808,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Terreno STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Baja una esquina del terreno. Arrastrando se reduce la esquina seleccionada y se nivela el resto del terreno seleccionado a dicha altura. Ctrl permite seleccionar un área diagonalmente. Mayús permite mostrar una estimación del precio STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Sube una esquina del terreno. Arrastrando se eleva la esquina seleccionada y se nivela el resto del terreno seleccionado a dicha altura. Ctrl permite seleccionar un área diagonalmente. Mayús permite mostrar una estimación del precio STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Nivela un área de terreno a la altura de la primera esquina seleccionada. Ctrl permite seleccionar un área diagonalmente. Mayús permite mostrar una estimación del precio -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Compra el terreno para futuros usos. Mayús permite mostrar una estimación del precio +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Compra el terreno para futuros usos. Ctrl permite seleccionar un área diagonalmente. Mayús permite mostrar una estimación del precio # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Selección de Objeto -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selecciona el objeto a construir. Mayús permite mostrar una estimación del precio +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selecciona el objeto a construir. Ctrl permite seleccionar un área diagonalmente. Mayús permite mostrar una estimación del precio STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Selecciona el tipo de objeto a construir STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Vista previa del objeto STR_OBJECT_BUILD_SIZE :{BLACK}Tamaño: {GOLD}{NUM} x {NUM} casillas @@ -2829,7 +2824,7 @@ STR_OBJECT_CLASS_TRNS :Transmisor STR_PLANT_TREE_CAPTION :{WHITE}Árboles STR_PLANT_TREE_TOOLTIP :{BLACK}Selecciona el tipo de árboles a plantar. Si la casilla ya tiene un árbol, se añadirán más árboles de distintos tipos sin importar el tipo elegido STR_TREES_RANDOM_TYPE :{BLACK}Tipo aleatorio -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Planta distintos árboles al azar. Mayús permite mostrar una estimación del precio +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Planta distintos árboles al azar. Ctrl permite seleccionar un área diagonalmente. Mayús permite mostrar una estimación del precio STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Árboles al azar STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Planta árboles al azar en el terreno STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2861,6 +2856,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Municipi STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Funda un municipio en un lugar aleatorio STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Varios municipios al azar STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cubre el mapa con municipios colocados al azar +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Expandir todos los municipios +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Expande levemente todos los municipios STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nombre del municipio: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Introducir nombre de municipio @@ -2905,14 +2902,14 @@ STR_FUND_INDUSTRY_REMOVE_ALL_INDUSTRIES_QUERY :{YELLOW}¿Está STR_INDUSTRY_CARGOES_INDUSTRY_CAPTION :{WHITE}Cadena de industrias para la industria {STRING} STR_INDUSTRY_CARGOES_CARGO_CAPTION :{WHITE}Cadena de industrias para la carga {STRING} STR_INDUSTRY_CARGOES_PRODUCERS :{WHITE}Industrias proveedoras -STR_INDUSTRY_CARGOES_CUSTOMERS :{WHITE}Industrias clientes +STR_INDUSTRY_CARGOES_CUSTOMERS :{WHITE}Industrias consumidoras STR_INDUSTRY_CARGOES_HOUSES :{WHITE}Casas STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP :{BLACK}Clica en la industria para ver sus proveedores y clientes -STR_INDUSTRY_CARGOES_CARGO_TOOLTIP :{BLACK}{STRING}{}Clica en la carga para mostrar sus proveedores y clientes +STR_INDUSTRY_CARGOES_CARGO_TOOLTIP :{BLACK}{STRING}{}Clica en la carga para mostrar sus proveedores y consumidores STR_INDUSTRY_DISPLAY_CHAIN :{BLACK}Mostrar cadena STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP :{BLACK}Muestra industrias que suministran o aceptan la carga -STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP :{BLACK}Enlazar al mapa -STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP :{BLACK}Muestra las industrias seleccionadas también en el minimapa +STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP :{BLACK}Mostrar en el minimapa +STR_INDUSTRY_CARGOES_NOTIFY_SMALLMAP_TOOLTIP :{BLACK}Muestra las industrias seleccionadas en el minimapa STR_INDUSTRY_CARGOES_SELECT_CARGO :{BLACK}Seleccionar carga STR_INDUSTRY_CARGOES_SELECT_CARGO_TOOLTIP :{BLACK}Selecciona el tipo de carga a mostrar STR_INDUSTRY_CARGOES_SELECT_INDUSTRY :{BLACK}Seleccionar industria @@ -3125,7 +3122,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalles STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No hay información disponible STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Patrón de filtrado: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtro: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Sobrescribir Archivo STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}¿Estás seguro de que quieres sobrescribir el archivo existente? STR_SAVELOAD_DIRECTORY :{STRING} (Directorio) @@ -3139,6 +3136,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Tamaño STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Selecciona el tamaño del mapa en casillas. El número de casillas disponible en el mapa será ligeramente inferior STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}No. de municipios: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nombres de municipios: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Selección del estilo del nombre de los municipios STR_MAPGEN_DATE :{BLACK}Fecha: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}No. de industrias: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Punto más alto: @@ -3152,13 +3151,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Extensi STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Incrementar la extensión del desierto en un diez por ciento STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Reducir la extensión del desierto en un diez por ciento STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Generador terreno: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tipo de terreno -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Nivel del mar: +STR_MAPGEN_SEA_LEVEL :{BLACK}Nivel del mar: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Ríos: STR_MAPGEN_SMOOTHNESS :{BLACK}Uniformidad: STR_MAPGEN_VARIETY :{BLACK}Variedad: STR_MAPGEN_GENERATE :{WHITE}Generar +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Configuración de NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Muestra la configuración de NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Configuración de IA +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Muestra la configuración de IA +STR_MAPGEN_GS_SETTINGS :{BLACK}Configuración de script de juego +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Muestra la configuración de script de juego + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Inglés +STR_MAPGEN_TOWN_NAME_FRENCH :Francés +STR_MAPGEN_TOWN_NAME_GERMAN :Alemán +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Inglés (Adicional) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latinoamericano +STR_MAPGEN_TOWN_NAME_SILLY :Tontos/Absurdos +STR_MAPGEN_TOWN_NAME_SWEDISH :Sueco +STR_MAPGEN_TOWN_NAME_DUTCH :Holandés +STR_MAPGEN_TOWN_NAME_FINNISH :Finlandés +STR_MAPGEN_TOWN_NAME_POLISH :Polaco +STR_MAPGEN_TOWN_NAME_SLOVAK :Eslovaco +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Noruego +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Húngaro +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austríaco +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumano +STR_MAPGEN_TOWN_NAME_CZECH :Checo +STR_MAPGEN_TOWN_NAME_SWISS :Suizo +STR_MAPGEN_TOWN_NAME_DANISH :Danés +STR_MAPGEN_TOWN_NAME_TURKISH :Turco +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiano +STR_MAPGEN_TOWN_NAME_CATALAN :Catalán # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Bordes del mapa: @@ -3217,7 +3244,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Informac STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Archivos NewGRF activos STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Archivos NewGRF inactivos STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Seleccionar configuración: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Patrón de filtrado: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtro: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Cargar la configuración seleccionada STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Guardar STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Guardar la lista actual como configuración @@ -3227,8 +3254,8 @@ STR_NEWGRF_SETTINGS_ADD :{BLACK}Añadir STR_NEWGRF_SETTINGS_ADD_FILE_TOOLTIP :{BLACK}Añade el NewGRF seleccionado a tu configuración STR_NEWGRF_SETTINGS_RESCAN_FILES :{BLACK}Actualizar archivos STR_NEWGRF_SETTINGS_RESCAN_FILES_TOOLTIP :{BLACK}Actualiza la lista de archivos NewGRF disponibles -STR_NEWGRF_SETTINGS_REMOVE :{BLACK}Quitar -STR_NEWGRF_SETTINGS_REMOVE_TOOLTIP :{BLACK}Quita el NewGRF seleccionado de la lista +STR_NEWGRF_SETTINGS_REMOVE :{BLACK}Retirar +STR_NEWGRF_SETTINGS_REMOVE_TOOLTIP :{BLACK}Retira el NewGRF seleccionado de la lista STR_NEWGRF_SETTINGS_MOVEUP :{BLACK}Mover Arriba STR_NEWGRF_SETTINGS_MOVEUP_TOOLTIP :{BLACK}Mueve el NewGRF seleccionado hacia arriba STR_NEWGRF_SETTINGS_MOVEDOWN :{BLACK}Mover Abajo @@ -3304,6 +3331,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Sprite a STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Salta al sprite anterior (ignorando pseudosprites, sprites recoloreados y sprites de fuente) y pasa del primer al último sprite STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representa el sprite seleccionado. Su alineamiento es ignorado al dibujarlo STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Mover el sprite, cambiando los ajustes X e Y. Ctrl+clic mueve el sprite ocho unidades de una sola vez + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Desviación (offset) centrada +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centrado + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Punto de mira + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Reiniciar coordenadas relativas STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Reinicia las coordenadas relativas actuales STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Coordenada X: {NUM}, Coordenada Y: {NUM} (Absoluta) @@ -3318,18 +3352,16 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Atención: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Error: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Error Fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Ha ocurrido un error fatal de NewGRF:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Ha ocurrido un error de NewGRF:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} no funcionará con la con la versión de TTDPatch informada por OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} es para la versión {STRING} de TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} está diseñado para ser usado con {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Parámetro incorrecto para {1:STRING}: párametro {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} debe ser cargado antes de {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} debe ser cargado después de {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} necesita la versión {STRING} ó superior de OpenTTD +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} es para la versión {2:STRING} of TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} está diseñado para ser usado con {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Parámetro incorrecto para {1:STRING}: párametro {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} debe cargarse antes de {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} debe cargarse después de {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requiere la versión {2:STRING} ó superior de OpenTTD STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :el archivo GRF ha sido diseñado para ser traducido STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Se han cargado demasiados NewGRF -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Cargar {1:STRING} como NewGRF estático con {STRING} puede causar desincronizaciones +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Cargar {1:STRING} como NewGRF estático con {2:STRING} puede causar desincronizaciones STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Sprite inesperado (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Propiedad de Acción 0 desconocida {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Intento de usar una ID inválida (sprite {3:NUM}) @@ -3461,14 +3493,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Comprar derecho STR_LOCAL_AUTHORITY_ACTION_BRIBE :Sobornar a la autoridad local ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Inicia una campaña publicitaria local pequeña para atraer más pasajeros y carga a sus servicios de transporte.{}Proporciona un incremento temporal en la calificación de las estaciones en un radio pequeño alrededor del centro del municipio.{}Coste: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Inicia una campaña publicitaria local mediana para atraer más pasajeros y carga a sus servicios de transporte.{}Proporciona un incremento temporal en la calificación de las estaciones en un radio mediano alrededor del centro del municipio.{}Coste: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Inicia una campaña publicitaria local grande para atraer más pasajeros y carga a sus servicios de transporte.{}Proporciona un incremento temporal en la calificación de las estaciones en un radio grande alrededor del centro del municipio.{}Coste: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Paga la reconstrucción de las carreteras locales.{}Provoca considerables complicaciones de tráfico durante 6 meses.{}Coste: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Construye una estatua en honor a su empresa.{}Proporciona un incremento permanente en la calificación de las estaciones de este municipio.{}Coste: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Paga la construcción de nuevos edificios comerciales en el municipio.{}Proporciona un incremento temporal en el crecimiento del municipio.{}Coste: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Compra derechos de transporte exclusivos en este municipio durante un año.{}Las autoridades no permitirán el uso de las estaciones de la competencia.{}Coste: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Soborna a las autoridades locales para aumentar su calificación, con el riesgo de sufrir una penalización severa si es descubierto.{}Coste: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inicia una campaña publicitaria local pequeña para atraer más pasajeros y carga a sus servicios de transporte.{}Proporciona un incremento temporal en la calificación de las estaciones en un radio pequeño alrededor del centro del municipio.{}{POP_COLOUR}Coste: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inicia una campaña publicitaria local mediana para atraer más pasajeros y carga a sus servicios de transporte.{}Proporciona un incremento temporal en la calificación de las estaciones en un radio mediano alrededor del centro del municipio.{}{POP_COLOUR}Coste: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inicia una campaña publicitaria local grande para atraer más pasajeros y carga a sus servicios de transporte.{}Proporciona un incremento temporal en la calificación de las estaciones en un radio grande alrededor del centro del municipio.{}{POP_COLOUR}Coste: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Paga la reconstrucción de las carreteras locales.{}Provoca considerables complicaciones de tráfico durante 6 meses.{}{POP_COLOUR}Coste: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Construye una estatua en honor a su empresa.{}Proporciona un incremento permanente en la calificación de las estaciones de este municipio.{}{POP_COLOUR}Coste: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Paga la construcción de nuevos edificios comerciales en el municipio.{}Proporciona un incremento temporal en el crecimiento del municipio.{}{POP_COLOUR}Coste: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Compra derechos de transporte exclusivos en este municipio durante un año.{}Las autoridades no permitirán el uso de las estaciones de la competencia.{}{POP_COLOUR}Coste: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Soborna a las autoridades locales para aumentar su calificación, con el riesgo de sufrir una penalización severa si es descubierto.{}{POP_COLOUR}Coste: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}Objetivos de {COMPANY} @@ -3597,10 +3629,10 @@ STR_CARGO_RATING_OUTSTANDING :Excepcional STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}Centrar vista en la posición de la estación. Ctrl+clic abre un punto de vista en dicha posición STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}Cambia el nombre de la estación -STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}Muestra todos los trenes que tienen esta estación en su horario -STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP :{BLACK}Muestra todos los vehículos de carretera que tienen esta estación en su horario -STR_STATION_VIEW_SCHEDULED_AIRCRAFT_TOOLTIP :{BLACK}Muestra todas las aeronaves que tienen esta estación en su horario -STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP :{BLACK}Muestra todos los barcos que tienen esta estación en su horario +STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}Muestra todos los trenes que tienen esta estación en sus órdenes +STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP :{BLACK}Muestra todos los vehículos de carretera que tienen esta estación en sus órdenes +STR_STATION_VIEW_SCHEDULED_AIRCRAFT_TOOLTIP :{BLACK}Muestra todas las aeronaves que tienen esta estación en sus órdenes +STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP :{BLACK}Muestra todos los barcos que tienen esta estación en sus órdenes STR_STATION_VIEW_RENAME_STATION_CAPTION :Renombrar estación/zona de carga @@ -3641,15 +3673,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Barcos STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Intereses de Préstamo STR_FINANCES_SECTION_OTHER :{GOLD}Otros +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Beneficio neto -STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Saldo en Banco +STR_FINANCES_PROFIT :{WHITE}Beneficio +STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Saldo bancario STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Fondos propios STR_FINANCES_LOAN_TITLE :{WHITE}Préstamo STR_FINANCES_INTEREST_RATE :{WHITE}Tipo de interés del préstamo: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Préstamo Máximo: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Pedir Préstamo {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Incrementa el préstamo. Ctrl+clic solicita todo el préstamo posible STR_FINANCES_REPAY_BUTTON :{BLACK}Pagar Préstamo {CURRENCY_LONG} @@ -3750,7 +3785,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produce: STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Necesita: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} esperando{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Cambiar producción (múltiplos de 8, máximo 2040) @@ -3779,7 +3814,9 @@ STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}Administ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Envia instrucciones a todos los vehículos de la lista STR_VEHICLE_LIST_REPLACE_VEHICLES :Reemplazar vehículos STR_VEHICLE_LIST_SEND_FOR_SERVICING :Enviar para Mantenimiento -STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Beneficio este año: {CURRENCY_LONG} (último año: {CURRENCY_LONG}) +STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Beneficio este año: {CURRENCY_LONG} (año anterior: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Enviar a Depósito STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Enviar a Depósito @@ -3823,7 +3860,7 @@ STR_GROUP_REMOVE_ALL_VEHICLES :Quitar todos lo STR_GROUP_RENAME_CAPTION :{BLACK}Renombrar un grupo STR_GROUP_PROFIT_THIS_YEAR :Beneficio este año: -STR_GROUP_PROFIT_LAST_YEAR :Beneficio del año pasado: +STR_GROUP_PROFIT_LAST_YEAR :Beneficio del año anterior: STR_GROUP_OCCUPANCY :Utilización actual: STR_GROUP_OCCUPANCY_VALUE :{NUM}% @@ -3871,6 +3908,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}F.T. má STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Alcance: {GOLD}{COMMA} casillas STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipo de aeronave: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Todos los tipos +STR_CARGO_TYPE_FILTER_FREIGHT :Carga +STR_CARGO_TYPE_FILTER_NONE :Ninguno + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Lista de selección de los vehículos de ferrocarril. Clica en el vehículo para más información. Pulsa Ctrl+clic para mostrar/ocultar el tipo del vehículo STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Lista de selección de vehículos de carretera. Clica en el vehículo para más información. Pulsa Ctrl+clic para mostrar/ocultar el tipo del vehículo @@ -4039,7 +4081,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :{G=f}aeronave STR_ENGINE_PREVIEW_SHIP :{G=m}barco STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Precio: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocidad: {VELOCITY} Potencia: {POWER}{}Coste Mantenimiento: {CURRENCY_LONG}/año{}Capacidad: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Precio: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocidad: {VELOCITY} Potencia: {POWER} F.T. Máxima: {6:FORCE}{}Coste Mantenimiento: {4:CURRENCY_LONG}/año{}Capacidad: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Precio: {0:CURRENCY_LONG} Peso: {1:WEIGHT_SHORT}{}Velocidad: {2:VELOCITY} Potencia: {3:POWER} F.T. Máxima: {6:FORCE}{}Coste Mantenimiento: {4:CURRENCY_LONG}/año{}Capacidad: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Precio: {CURRENCY_LONG} Velocidad Máx.: {VELOCITY}{}Capacidad: {CARGO_LONG}{}Coste Mantenimiento: {CURRENCY_LONG}/año STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Precio: {CURRENCY_LONG} Velocidad Máx.: {VELOCITY}{}Tipo de aeronave: {STRING}{}Capacidad: {CARGO_LONG}, {CARGO_LONG}{}Coste Mantenimiento: {CURRENCY_LONG}/año STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Precio: {CURRENCY_LONG} Velocidad Máx.: {VELOCITY}{}Tipo de aeronave: {STRING}{}Capacidad: {CARGO_LONG}{}Coste Mantenimiento: {CURRENCY_LONG}/año @@ -4197,13 +4239,14 @@ STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Velocida STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potencia: {LTBLUE}{POWER}{BLACK} Velocidad Máx.: {LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potencia: {LTBLUE}{POWER}{BLACK} Velocidad Máx.: {LTBLUE}{VELOCITY} {BLACK}F.T. Máx.: {LTBLUE}{FORCE} -STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Beneficio este año: {LTBLUE}{CURRENCY_LONG} (último año: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Beneficio este año: {LTBLUE}{CURRENCY_LONG} (año anterior: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Beneficio este año: {LTBLUE}{CURRENCY_LONG} (año anterior: {CURRENCY_LONG}) {BLACK}Potencia específica mín.: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidad: {LTBLUE}{COMMA}% {BLACK}Averías desde el último mantenimiento: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Construido: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacidad: {LTBLUE}Ninguna{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidad: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacidad: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidad: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacidad: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacidad: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Créditos de Transferencia: {LTBLUE}{CURRENCY_LONG} @@ -4364,7 +4407,7 @@ STR_ORDER_CONDITIONAL :Salto de orden STR_ORDER_SHARE :Compartir órdenes STR_ORDERS_GO_TO_TOOLTIP :{BLACK}Añade una nueva orden antes de la orden resaltada, o la añade al final de la lista. Ctrl sobre estaciones ordena 'Carga completa de cualquier carga', sobre puntos de ruta ordena 'sin paradas' y sobre depósitos ordena 'mantenimiento'. Ctrl o Compartir órdenes permite a este vehículo compartir órdenes con el vehículo seleccionado. Clica sobre un vehículo copia las órdenes. Una órden de depósito desactiva el mantenimiento automático del vehículo -STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Muestra todos los vehículos con el mismo horario +STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}Muestra todos los vehículos que comparten estas órdenes y este horario # String parts to build the order string STR_ORDER_GO_TO_WAYPOINT :Ir vía {WAYPOINT} @@ -4444,54 +4487,54 @@ STR_TIMETABLE_ORDER_VIEW_TOOLTIP :{BLACK}Cambia a STR_TIMETABLE_TOOLTIP :{BLACK}Horario - Clica en una orden para resaltarla -STR_TIMETABLE_NO_TRAVEL :Sin viaje +STR_TIMETABLE_NO_TRAVEL :No viajar STR_TIMETABLE_NOT_TIMETABLEABLE :Viajar (automático; programado por la próxima orden manual) STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :Viajar (sin programar) STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED :Viajar (sin programar) a {2:VELOCITY} como máximo STR_TIMETABLE_TRAVEL_FOR :Viajar durante {STRING} STR_TIMETABLE_TRAVEL_FOR_SPEED :Viajar durante {STRING} a {VELOCITY} como máximo -STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Viajando (durante {STRING}, sin programar) -STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :Viajando (durante {STRING}, sin programar) a {VELOCITY} como máximo -STR_TIMETABLE_STAY_FOR_ESTIMATED :(permaneciendo {STRING}, sin programar) -STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :(viajando durante {STRING}, sin programar) -STR_TIMETABLE_STAY_FOR :y esperar {STRING} +STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Viajar (durante {STRING}, sin programar) +STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :Viajar (durante {STRING}, sin programar) a {VELOCITY} como máximo +STR_TIMETABLE_STAY_FOR_ESTIMATED :(permanecer {STRING}, sin programar) +STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :(viajar durante {STRING}, sin programar) +STR_TIMETABLE_STAY_FOR :y permanecer {STRING} STR_TIMETABLE_AND_TRAVEL_FOR :y viajar durante {STRING} STR_TIMETABLE_DAYS :{COMMA}{NBSP}día{P "" s} STR_TIMETABLE_TICKS :{COMMA}{NBSP}tic{P "" s} -STR_TIMETABLE_TOTAL_TIME :{BLACK}El horario tardará {STRING} en completarse -STR_TIMETABLE_TOTAL_TIME_INCOMPLETE :{BLACK}El horario tardará al menos {STRING} en completarse (no todas las órdenes) +STR_TIMETABLE_TOTAL_TIME :{BLACK}El horario tardará {STRING} en recorrerse +STR_TIMETABLE_TOTAL_TIME_INCOMPLETE :{BLACK}El horario tardará al menos {STRING} en recorrerse (no todas las órdenes) -STR_TIMETABLE_STATUS_ON_TIME :{BLACK}Este vehículo está actualmente en hora -STR_TIMETABLE_STATUS_LATE :{BLACK}Este vehículo está actualmente retrasado {STRING} -STR_TIMETABLE_STATUS_EARLY :{BLACK}Este vehículo está actualmente adelantado {STRING} +STR_TIMETABLE_STATUS_ON_TIME :{BLACK}Este vehículo actualmente es puntual +STR_TIMETABLE_STATUS_LATE :{BLACK}Este vehículo actualmente está retrasado {STRING} +STR_TIMETABLE_STATUS_EARLY :{BLACK}Este vehículo actualmente está adelantado {STRING} STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Este horario no ha comenzado STR_TIMETABLE_STATUS_START_AT :{BLACK}Este horario comenzará el {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Fecha de inicio -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Selecciona una fecha como punto de partida de este horario. Ctrl+clic permite fijar el punto de partida de este horario y distribuye todos los vehículos que lo compartan siempre y cuando el horario esté completo +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Selecciona la fecha de inicio del horario. Ctrl+click distribuye uniformemente todos los vehículos que compartan este horario a partir de la fecha proporcionada, basados en su orden relativo, siempre que el horario esté completamente rellenado -STR_TIMETABLE_CHANGE_TIME :{BLACK}Cambiar duración -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Cambia la duración de la orden seleccionada +STR_TIMETABLE_CHANGE_TIME :{BLACK}Modificar duración +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Modifica la duración de la orden seleccionada. Ctrl+clic establece la duración para todas las órdenes STR_TIMETABLE_CLEAR_TIME :{BLACK}Borrar duración -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Borra la duración de la orden resaltada +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Borra la duración de la orden resaltada.Ctrl+clic elimina la duración de todas las órdenes -STR_TIMETABLE_CHANGE_SPEED :{BLACK}Cambiar límite de velocidad -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Cambia el límite de velocidad de la orden resaltada +STR_TIMETABLE_CHANGE_SPEED :{BLACK}Modificar límite de velocidad +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Cambia el límite de velocidad de la orden resaltada. Ctrl+clic establece el límite para todas las órdenes STR_TIMETABLE_CLEAR_SPEED :{BLACK}Borrar límite de velocidad -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Borra el límite de velocidad de la orden resaltada +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Borra el límite de velocidad de la orden resaltada. Ctrl+clic elimina el límite de todas las órdenes -STR_TIMETABLE_RESET_LATENESS :{BLACK}Reiniciar retrasos -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Pone a cero el retraso del vehículo, así el vehículo estará en hora +STR_TIMETABLE_RESET_LATENESS :{BLACK}Reiniciar retraso +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Establece en cero el retraso acumulado del vehículo para que sea puntual STR_TIMETABLE_AUTOFILL :{BLACK}Rellenar automáticamente -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Rellena la tabla de horarios automáticamente con los valores de la siguiente jornada (Ctrl+clic para tratar de mantener los tiempos de espera) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Rellena el horario automáticamente con los valores del siguiente recorrido. Ctrl+clic para intentar mantener los tiempos de permanencia en estación -STR_TIMETABLE_EXPECTED :{BLACK}Esperado +STR_TIMETABLE_EXPECTED :{BLACK}Previsto STR_TIMETABLE_SCHEDULED :{BLACK}Programado -STR_TIMETABLE_EXPECTED_TOOLTIP :{BLACK}Alterna entre esperado y programado +STR_TIMETABLE_EXPECTED_TOOLTIP :{BLACK}Alterna entre fechas previstas y programadas STR_TIMETABLE_ARRIVAL_ABBREVIATION :Ll: STR_TIMETABLE_DEPARTURE_ABBREVIATION :S: @@ -4500,14 +4543,14 @@ STR_TIMETABLE_DEPARTURE_ABBREVIATION :S: # Date window (for timetable) STR_DATE_CAPTION :{WHITE}Seleccionar fecha STR_DATE_SET_DATE :{BLACK}Seleccionar fecha -STR_DATE_SET_DATE_TOOLTIP :{BLACK}Usar la fecha seleccionada como punto de inicio del horario +STR_DATE_SET_DATE_TOOLTIP :{BLACK}Usa la fecha seleccionada como punto de inicio del horario STR_DATE_DAY_TOOLTIP :{BLACK}Selecciona el día STR_DATE_MONTH_TOOLTIP :{BLACK}Selecciona el mes STR_DATE_YEAR_TOOLTIP :{BLACK}Selecciona el año # AI debug window -STR_AI_DEBUG :{WHITE}Depuración de Scripts de juego/IA +STR_AI_DEBUG :{WHITE}Depuración de scripts de juego/IA STR_AI_DEBUG_NAME_AND_VERSION :{BLACK}{STRING} (v{NUM}) STR_AI_DEBUG_NAME_TOOLTIP :{BLACK}Nombre del script STR_AI_DEBUG_SETTINGS :{BLACK}Configuración @@ -4523,20 +4566,22 @@ STR_AI_DEBUG_MATCH_CASE_TOOLTIP :{BLACK}Activa/d STR_AI_DEBUG_CONTINUE :{BLACK}Continuar STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}Quita la pausa y hace que la IA continúe STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}Mostrar salida de depuración de esta IA -STR_AI_GAME_SCRIPT :{BLACK}Script de juego -STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Comprobar el registro del Script de juego +STR_AI_GAME_SCRIPT :{BLACK}Script de Juego +STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Analizar el registro del script de juego STR_ERROR_AI_NO_AI_FOUND :No se encontró ninguna IA apropiada para cargar.{}Ésta es una IA por defecto que no realiza acción alguna.{}Puedes descargar nuevas IA mediante el sistema de 'Contenido Online' -STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Uno de los scripts ejecutados ha fallado. Por favor, informa del fallo al autor del script con una captura de la ventana de depuración de Script / IA -STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}La ventana de depuración de Scripts solo está disponible para el servidor +STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Uno de los scripts ejecutados ha fallado. Por favor, informa del fallo al autor del script con una captura de la ventana de depuración de script/IA +STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}La ventana de depuración de scripts solo está disponible para el servidor # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Configuración de Scripts de juego/IA +STR_AI_CONFIG_CAPTION_AI :{WHITE}Configuración de IA +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Configuración de scripts de juego STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Script de juego que será cargado en la próxima partida STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}IA que serán cargadas en la próxima partida STR_AI_CONFIG_HUMAN_PLAYER :Jugador humano STR_AI_CONFIG_RANDOM_AI :IA aleatoria STR_AI_CONFIG_NONE :(ninguno) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Núm. máximo de jugadores: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Mover hacia arriba STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Mover la IA seleccionada hacia arriba @@ -4544,13 +4589,12 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Mover ha STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Mover la IA seleccionada hacia abajo STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script de juego +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parámetros STR_AI_CONFIG_AI :{SILVER}IA -STR_AI_CONFIG_CHANGE :{BLACK}Seleccionar {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :IA -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script de juego -STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Cargar otro script +STR_AI_CONFIG_CHANGE_AI :{BLACK}Seleccionar IA +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Seleccionar script de juego +STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carga otro script STR_AI_CONFIG_CONFIGURE :{BLACK}Configurar STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configura los parámetros del script @@ -4577,10 +4621,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Mapa com STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Mapa de alturas STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minimapa -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}Parámetros {STRING} -STR_AI_SETTINGS_CAPTION_AI :IA -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script de juego +# Script Parameters +STR_AI_SETTINGS_CAPTION_AI :{WHITE}Parámetros de IA STR_AI_SETTINGS_CLOSE :{BLACK}Cerrar STR_AI_SETTINGS_RESET :{BLACK}Reiniciar STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4744,6 +4786,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... dema STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}No se pueden crear industrias... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}No puede construirse {STRING} aquí... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}No se puede construir este tipo de industria aquí... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}No se puede realizar prospección para la industria... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... demasiado cerca de otra industria STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... debe construirse un municipio primero STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... solo se permite uno por municipio @@ -4758,7 +4801,9 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... solo STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... solo puede construirse por encima de la cota de nieve STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... solo puede construirse por debajo de la cota de nieve -STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}No había sitios apropiados disponibles para industrias '{STRING}' +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}La fundación ha fallado debido a una prospeccion desafortunada; intentar de nuevo +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}No había lugares apropiados para realizar prospecciones para esta industria +STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}No había lugares apropiados para industrias '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Cambia los parámetros de generación del mapa para obtener un mapa mejor # Station construction related errors @@ -4901,7 +4946,7 @@ STR_ERROR_CAN_T_PLANT_TREE_HERE :{WHITE}No se pu STR_ERROR_CAN_T_BUILD_BRIDGE_HERE :{WHITE}No puede construirse un puente aquí... STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Primero debe demolerse el puente STR_ERROR_CAN_T_START_AND_END_ON :{WHITE}No se puede comenzar y acabar en la misma posición -STR_ERROR_BRIDGEHEADS_NOT_SAME_HEIGHT :{WHITE}Las cabeceras del puente no están al mismo nivel +STR_ERROR_BRIDGEHEADS_NOT_SAME_HEIGHT :{WHITE}Los estribos del puente no están al mismo nivel STR_ERROR_BRIDGE_TOO_LOW_FOR_TERRAIN :{WHITE}El puente es demasiado bajo para el terreno STR_ERROR_BRIDGE_TOO_HIGH_FOR_TERRAIN :{WHITE}El puente es demasiado alto para este terreno. STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Comienzo y final deben estar en línea @@ -4925,6 +4970,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objeto e STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... la sede de la empresa está en medio STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}No es posible comprar este terreno... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... ¡ya es de su propiedad! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... límite de construcción de objetos alcanzado # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}No se puede crear grupo... @@ -4997,6 +5043,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}No se pu STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... el vehículo está destruido +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... no todos los vehículos son idénticos + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Ningún vehículo estará disponible STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Es necesario modificar la configuración NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}En esta fecha no hay vehículos disponibles @@ -5023,6 +5071,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}No se pu STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... el vehículo no puede ir a todas las estaciones STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... el vehículo no puede ir a esa estación STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... un vehículo que comparte esta orden no puede ir a esa estación +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... no todos los vehículos tienen las mismas órdenes +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... no todos los vehículos comparten las órdenes STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}No se puede compartir lista de órdenes... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}No se puede dejar de compartir lista de órdenes... @@ -5030,10 +5080,12 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}No se pu STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... demasiado lejos del destino anterior STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... la aeronave no tiene suficiente alcance +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}No se puede asignar horario al vehículo... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Los vehículos sólo pueden esperar en estaciones -STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}Este vehículo no va a detenerse en esta estación +STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}Este vehículo no se detendrá en esta estación # Sign related errors STR_ERROR_TOO_MANY_SIGNS :{WHITE}... demasiados letreros diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index 321d4cba7a397..0b2061a0d1985 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}cv STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -226,9 +236,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Filtrar texto: +STR_LIST_FILTER_TITLE :{BLACK}Filtrar: STR_LIST_FILTER_OSKTITLE :{BLACK}Indicar texto a filtrar -STR_LIST_FILTER_TOOLTIP :{BLACK}Indicar un texto clave para filtrar la lista +STR_LIST_FILTER_TOOLTIP :{BLACK}Indicar palabras clave para filtrar la lista STR_TOOLTIP_GROUP_ORDER :{BLACK}Elegir orden de grupo STR_TOOLTIP_SORT_ORDER :{BLACK}Elegir orden descendiente o ascendiente @@ -305,7 +315,7 @@ STR_SORT_BY_WAITING_TOTAL :Carga total en STR_SORT_BY_WAITING_AVAILABLE :Carga disponible en espera STR_SORT_BY_RATING_MAX :Mayor índice de carga STR_SORT_BY_RATING_MIN :Menor índice de carga -STR_SORT_BY_ENGINE_ID :Id. locomotora (orden clásico) +STR_SORT_BY_ENGINE_ID :ID de vehículo (orden clásico) STR_SORT_BY_COST :Costo STR_SORT_BY_POWER :Potencia STR_SORT_BY_TRACTIVE_EFFORT :Fuerza de tracción @@ -377,9 +387,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Generaci STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Generación de industrias STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Construcción de carreteras STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Construcción de tranvía -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantar árboles. Mayús muestra un costo estimado +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantar árboles. Ctrl permite seleccionar un área diagonalmente. Mayús permite mostrar una estimación del precio STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Poner cartel -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar objeto. Mayús muestra un costo estimado +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar objeto. Ctrl para seleccionar un área en diagonal. Mayús muestra un costo estimado # Scenario editor file menu ###length 7 @@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Salir # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Opciones de juego STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Configuración -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Configuración de scripts +STR_SETTINGS_MENU_AI_SETTINGS :Configuración de IA +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Configuración de scripts de juego STR_SETTINGS_MENU_NEWGRF_SETTINGS :Configuración de NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opciones de transparencia STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Mostrar nombres de localidades @@ -645,7 +656,7 @@ STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Préstam STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total: ###length 10 -STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP :{BLACK}Cuántos vehículos tuvieron ganancias el último año, contando los de carretera, trenes, barcos y aeronaves +STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP :{BLACK}Cuántos vehículos tuvieron ganancias el último año, contando los autotransportes, trenes, barcos y aeronaves STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP :{BLACK}Número de estaciones abastecidas recientemente. Las estaciones de tren, paradas de autobuses, aeropuertos y demás se contabilizan aparte, aun si pertenecen a la misma estación STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP :{BLACK}Utilidad del vehículo con menores ingresos (de entre aquellos con más de 2 años) STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Cantidad de efectivo ganado en el trimestre con la utilidad más baja de los últimos 12 trimestres @@ -679,7 +690,7 @@ STR_MUSIC_TOOLTIP_SKIP_TO_PREVIOUS_TRACK :{BLACK}Saltar a STR_MUSIC_TOOLTIP_SKIP_TO_NEXT_TRACK_IN_SELECTION :{BLACK}Saltar a la pista siguiente de la selección STR_MUSIC_TOOLTIP_STOP_PLAYING_MUSIC :{BLACK}Detener música STR_MUSIC_TOOLTIP_START_PLAYING_MUSIC :{BLACK}Comenzar música -STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Mover los cursores para ajustar el volumen de la música y los efectos +STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC :{BLACK}Mover el deslizador para ajustar el volumen de la música y los efectos STR_MUSIC_TOOLTIP_SELECT_ALL_TRACKS_PROGRAM :{BLACK}Elegir programa 'todas las pistas' STR_MUSIC_TOOLTIP_SELECT_OLD_STYLE_MUSIC :{BLACK}Elegir programa 'antiguo' STR_MUSIC_TOOLTIP_SELECT_NEW_STYLE_MUSIC :{BLACK}Elegir programa 'moderno' @@ -779,12 +790,12 @@ STR_SMALLMAP_TOWN :{TINY_FONT}{WHI STR_SMALLMAP_DISABLE_ALL :{BLACK}Ocultar todo STR_SMALLMAP_ENABLE_ALL :{BLACK}Mostrar todo STR_SMALLMAP_SHOW_HEIGHT :{BLACK}Mostrar relieve -STR_SMALLMAP_TOOLTIP_DISABLE_ALL_INDUSTRIES :{BLACK}No mostrar industrias en el mapa +STR_SMALLMAP_TOOLTIP_DISABLE_ALL_INDUSTRIES :{BLACK}Ocultar del mapa las industrias STR_SMALLMAP_TOOLTIP_ENABLE_ALL_INDUSTRIES :{BLACK}Mostrar todas las industrias en el mapa STR_SMALLMAP_TOOLTIP_SHOW_HEIGHT :{BLACK}Alternar vista de relieve -STR_SMALLMAP_TOOLTIP_DISABLE_ALL_COMPANIES :{BLACK}No mostrar propiedades de empresas en el mapa +STR_SMALLMAP_TOOLTIP_DISABLE_ALL_COMPANIES :{BLACK}Ocultar del mapa las propiedades de las empresas STR_SMALLMAP_TOOLTIP_ENABLE_ALL_COMPANIES :{BLACK}Mostrar todas las propiedades de empresas en el mapa -STR_SMALLMAP_TOOLTIP_DISABLE_ALL_CARGOS :{BLACK}Ocultar todas las cargas del mapa +STR_SMALLMAP_TOOLTIP_DISABLE_ALL_CARGOS :{BLACK}Ocultar del mapa las cargas STR_SMALLMAP_TOOLTIP_ENABLE_ALL_CARGOS :{BLACK}Mostrar todas las cargas en el mapa # Status bar messages @@ -820,7 +831,7 @@ STR_NEWS_AIRCRAFT_CRASH :{BIG_FONT}{BLAC STR_NEWS_PLANE_CRASH_OUT_OF_FUEL :{BIG_FONT}{BLACK}¡Accidente aéreo!{}Avión se queda sin combustible, ¡{COMMA} personas mueren en explosión! STR_NEWS_DISASTER_ZEPPELIN :{BIG_FONT}{BLACK}¡Desastre de zepelín en {STATION}! -STR_NEWS_DISASTER_SMALL_UFO :{BIG_FONT}{BLACK}¡Vehículo destruido en la carretara al impactar con ovni! +STR_NEWS_DISASTER_SMALL_UFO :{BIG_FONT}{BLACK}¡Vehículo destruido en la carretera al impactar con ovni! STR_NEWS_DISASTER_AIRPLANE_OIL_REFINERY :{BIG_FONT}{BLACK}¡Explota refinería de petróleo cerca de {TOWN}! STR_NEWS_DISASTER_HELICOPTER_FACTORY :{BIG_FONT}{BLACK}¡Fábrica destruida misteriosamente cerca de {TOWN}! STR_NEWS_DISASTER_BIG_UFO :{BIG_FONT}{BLACK}¡Ovni aterriza cerca de {TOWN}! @@ -920,7 +931,7 @@ STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copiar u # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opciones de juego STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME :{BLACK}Divisa -STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Selección de divisa +STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP :{BLACK}Elegir divisa ###length 42 STR_GAME_OPTIONS_CURRENCY_GBP :Libra británica (GBP) @@ -966,36 +977,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rupia india (IN STR_GAME_OPTIONS_CURRENCY_IDR :Rupia indonesia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit malasio (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Manejar por la izquierda -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Manejar por la derecha - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nombres de localidades: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Elegir el estilo de nombres para las localidades - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Inglés -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francés -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Alemán -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Inglés (adicional) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :América Latina -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Tonterías (inglés) -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Sueco -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holandés -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandés -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polaco -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Eslovaco -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Noruego -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Húngaro -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austríaco -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumano -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Checo -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Suizo -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danés -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turco -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiano -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalán - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Guardado automático STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Elegir el intervalo de guardados automáticos @@ -1028,21 +1009,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Activar STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Controlador actual: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Tamaño de la interfaz -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Elegir el tamaño de los elementos de la interfaz +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Tamaño de la interfaz +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Mover el deslizador para cambiar el tamaño de la interfaz. Mantener pulsado Ctrl para un control fino +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Detectar automáticamente +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Detectar tamaño de la interfaz automáticamente -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(detectar) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Doble -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Cuádruple +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Ajustar biseles +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Ajustar el tamaño de los biseles respecto a la interfaz -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Tamaño de texto -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Elegir el tamaño de letra de la interfaz - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(detectar) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Doble -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Cuádruple +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Gráficos @@ -1094,8 +1073,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Vista p STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 libras (£) en la moneda STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Cambiar parámetro de moneda personalizada -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Núm. máximo de jugadores: {ORANGE}{COMMA} - STR_NONE :Ninguno STR_FUNDING_ONLY :Solo fundadas STR_MINIMAL :Mínimo @@ -1145,6 +1122,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Ambiente Templado +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Ambiente Subártico +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Ambiente Subtropical +STR_CLIMATE_TOYLAND_LANDSCAPE :Ambiente de Mundo de juguetes + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Muy plano STR_TERRAIN_TYPE_FLAT :Plano @@ -1164,7 +1147,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}No se en # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Configuración -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrar texto: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtrar: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Desplegar todo STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Compactar todo STR_CONFIG_SETTING_RESET_ALL :{BLACK}Restablecer todos los ajustes @@ -1224,6 +1207,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Derecha STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Máximo préstamo inicial: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Máxima cantidad que una empresa puede pedir prestada (sin tener en cuenta la inflación) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Sin préstamo {RED} Se necesita un script de juego para proporcionar fondos iniciales STR_CONFIG_SETTING_INTEREST_RATE :Porcentaje de interés: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Tasa de interés del préstamo; controla también la inflación, en caso de estar activada @@ -1270,16 +1256,16 @@ STR_CONFIG_SETTING_MAP_HEIGHT_LIMIT_AUTO :(automático) STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN :{WHITE}No se puede establecer el límite de elevación del mapa en el valor indicado. Al menos una montaña ya es más alta STR_CONFIG_SETTING_AUTOSLOPE :Alterar terreno debajo de edificios, vías férreas, etc.: {STRING} -STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Permitir la alteración del terreno debajo de infraestructura sin tener que retirarla +STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Permitir alteración de terreno debajo de infraestructura sin tener que retirarla -STR_CONFIG_SETTING_CATCHMENT :Permitir cambiar el tamaño del área de recolección a una forma más real: {STRING} -STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Las áreas de recolección se adecúan a diferentes tamaños, según los tipos de estaciones y aeropuertos +STR_CONFIG_SETTING_CATCHMENT :Permitir áreas de recolección más realistas: {STRING} +STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Las áreas de recolección se ajustarán a los tamaños de los tipos de estaciones y aeropuertos STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Las estaciones privadas pueden dar servicio a industrias con estaciones neutrales: {STRING} STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Al activarse, las industrias con estaciones integradas (ej. plataformas petrolíferas) podrán aceptar carga de estaciones aledañas. Al desactivarse, tales industrias solo recibirán carga en sus propias estaciones y no aceptarán de otras estaciones, ni la estación integrada brindará servicio a nada más que su industria -STR_CONFIG_SETTING_EXTRADYNAMITE :Permitir mayor eliminación de carreteras, puentes y túneles: {STRING} -STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Hacer más fácil eliminar infraestructura y edificios que sean propiedad de las localidades +STR_CONFIG_SETTING_EXTRADYNAMITE :Permitir eliminación más fácil de propiedades de localidades: {STRING} +STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Hacer más fácil la eliminación de la infraestructura y los edificios que sean propiedad de las localidades STR_CONFIG_SETTING_TRAIN_LENGTH :Longitud máxima de trenes: {STRING} STR_CONFIG_SETTING_TRAIN_LENGTH_HELPTEXT :Longitud máxima permitida para los trenes @@ -1304,8 +1290,8 @@ STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Grado de inclin STR_CONFIG_SETTING_FORBID_90_DEG :Prohibir a trenes realizar giros de 90°: {STRING} STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Los giros de 90° ocurren en vías férreas perpendiculares donde el tren gira 90° al pasar de una casilla a otra, en lugar de los 45° habituales en otras combinaciones de vías. -STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Permitir la ampliación de estaciones no adyacentes: {STRING} -STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Permitir añadir de partes a una estación sin tener que estar en contacto directo con las partes existentes. Se debe pulsar Ctrl+Clic para añadir las nuevas partes +STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Permitir ampliación de estaciones no adyacentes: {STRING} +STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Se podrán añadir partes a una estación sin que tengan que estar una al lado de la otra. Ctrl+Clic para añadir las nuevas partes STR_CONFIG_SETTING_INFLATION :Inflación: {STRING} STR_CONFIG_SETTING_INFLATION_HELPTEXT :Activar inflación en la economía, lo que hace que los costos aumenten ligeramente más rápido que los ingresos @@ -1330,7 +1316,7 @@ STR_CONFIG_SETTING_INDUSTRY_PLATFORM :Área plana alr STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :Cantidad de espacio plano alrededor de las industrias. Esto asegura que haya espacio libre alrededor de las industrias para construir vías férreas, etc. STR_CONFIG_SETTING_MULTIPINDTOWN :Permitir varias industrias similares por localidad: {STRING} -STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :En general, una localidad admite un solo tipo de industria a la vez, pero con esta opción varias industrias del mismo tipo en una localidad son posibles +STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :En general, una localidad admite un solo tipo de industria a la vez, pero con esta opción varias industrias del mismo tipo en una localidad serán posibles STR_CONFIG_SETTING_SIGNALSIDE :Mostrar señales: {STRING} STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :Elegir el lado de las vías donde se construirán las señales @@ -1340,7 +1326,7 @@ STR_CONFIG_SETTING_SIGNALSIDE_DRIVING_SIDE :En el lado de c STR_CONFIG_SETTING_SIGNALSIDE_RIGHT :A la derecha STR_CONFIG_SETTING_SHOWFINANCES :Mostrar ventana de finanzas al final del año: {STRING} -STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT :Si se activa, la ventana de finanzas aparecerá al final de cada año para permitir realizar una inspección más fácil del estado financiero de la empresa +STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT :Al activarse, la ventana de finanzas aparecerá al final de cada año para permitir la inspección más sencilla del estado financiero de la empresa STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT :Todo nuevo recorrido es 'Sin paradas' por defecto: {STRING} STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT :Cada vehículo hace parada en cada estación por la que pasa, pero al activar esta opción el vehículo seguirá de largo hasta llegar a su destino. Esta opción solo define el valor por defecto para nuevos recorridos, pero cada recorrido individual puede ajustarse independientemente @@ -1353,7 +1339,7 @@ STR_CONFIG_SETTING_STOP_LOCATION_MIDDLE :mitad STR_CONFIG_SETTING_STOP_LOCATION_FAR_END :final STR_CONFIG_SETTING_AUTOSCROLL :Recorrer vista cuando se mueva el cursor a los bordes: {STRING} -STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT :Al activarse, las vistas se desplazarán cuando el ratón se acarque a los bordes de la ventana +STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT :Al activarse, las vistas se desplazarán cuando el ratón se acerque a los bordes de la ventana ###length 4 STR_CONFIG_SETTING_AUTOSCROLL_DISABLED :Desactivado STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN :Vista principal, solo en pantalla completa @@ -1361,19 +1347,19 @@ STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT :Vista principal STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT :Todas las vistas STR_CONFIG_SETTING_BRIBE :Permitir sobornos al ayuntamiento: {STRING} -STR_CONFIG_SETTING_BRIBE_HELPTEXT :Las empresas intentan sobornar a los ayuntamientos. Si un inspector lo descubre, la empresa no podrá operar en la localidad seis meses +STR_CONFIG_SETTING_BRIBE_HELPTEXT :Las empresas podrán sobornar a los ayuntamientos, pero si un inspector lo descubre, la empresa no podrá operar en la localidad durante seis meses -STR_CONFIG_SETTING_ALLOW_EXCLUSIVE :Permitir adquirir los derechos de transporte exclusivos: {STRING} -STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Si una empresa compra los derechos de transporte exclusivos en una localidad, las estaciones de la competencia no recibirán carga nada todo un año +STR_CONFIG_SETTING_ALLOW_EXCLUSIVE :Permitir adquisición de derechos de transporte exclusivos: {STRING} +STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT :Si una empresa compra los derechos de transporte exclusivos en una localidad, las estaciones de la competencia no recibirán carga todo un año -STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS :Permitir la construcción de nuevos edificios: {STRING} +STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS :Permitir construcción de nuevos edificios: {STRING} STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT :Las empresas aportan dinero a los ayuntamientos para que construyan nuevas casas y edificios STR_CONFIG_SETTING_ALLOW_FUND_ROAD :Permitir el pago de la reconstrucción de las carreteras locales: {STRING} -STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT :Las empresas aportan dinero a los ayuntamientos para que reconstruyan sus carreteras y así sabotear a otros servicios de transporte por carretera que operen en la zona +STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT :Las empresas aportan dinero a los ayuntamientos para reconstruir sus carreteras, lo que perjudicando otros servicios de transporte en la zona -STR_CONFIG_SETTING_ALLOW_GIVE_MONEY :Permitir enviar dinero a otras empresas: {STRING} -STR_CONFIG_SETTING_ALLOW_GIVE_MONEY_HELPTEXT :Permitir la transferencia de dinero entre empresas en modo multijugador +STR_CONFIG_SETTING_ALLOW_GIVE_MONEY :Permitir envío de dinero a otras empresas: {STRING} +STR_CONFIG_SETTING_ALLOW_GIVE_MONEY_HELPTEXT :En modo multijugador, las empresas podrán transferirse dinero STR_CONFIG_SETTING_FREIGHT_TRAINS :Multiplicador de peso para simular trenes pesados: {STRING} STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :Impacto de llevar carga en los trenes. Un valor mayor exige mayor potencia a los trenes para llevar carga, sobre todo al subir colinas @@ -1383,16 +1369,16 @@ STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Establece la ve STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1/{COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Cantidad de accidentes aéreos: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Probabilidad de que ocurran accidentes aéreos.{}* Las aeronaves grandes son más propensas a accidentes en areopuertos pequeños +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Probabilidad de que ocurran accidentes aéreos.{}* Las aeronaves grandes son más propensas a accidentes en aeropuertos pequeños ###length 3 STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ninguno* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reducida STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal -STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permitir la construcción de paradas de paso en localidades: {STRING} -STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Permitir la construcción de paradas de paso en carreteras que sean propiedad de las localidades -STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permitir la construcción de paradas paradas de paso en carreteras de la competencia: {STRING} -STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :Construir paradas de autobuses de paso en carreteras que sean propiedad de otras empresas +STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permitir construcción de paradas de paso en localidades: {STRING} +STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :Se podrán construir paradas de paso en las carreteras que sean propiedad de las localidades +STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :Permitir construcción de paradas de paso en carreteras de la competencia: {STRING} +STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD_HELPTEXT :Se podrán construir paradas de paso en las carreteras que sean propiedad de otras empresas STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}No se puede cambiar esta opción si ya existen vehículos STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Mantenimiento de infraestructura: {STRING} @@ -1420,7 +1406,7 @@ STR_CONFIG_SETTING_WARN_INCOME_LESS_HELPTEXT :Mostrar un mens STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES :Vehículos siempre disponibles: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES_HELPTEXT :Todos los modelos de vehículos estarán disponibles para siempre tras haber sido introducidos -STR_CONFIG_SETTING_AUTORENEW_VEHICLE :Renovar automáticamente vehículos anicuados: {STRING} +STR_CONFIG_SETTING_AUTORENEW_VEHICLE :Renovar automáticamente vehículos viejos: {STRING} STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT :Los vehículos próximos al final de su vida útil serán renovados automáticamente, siempre y cuando se cumplan las condiciones de renovación STR_CONFIG_SETTING_AUTORENEW_MONTHS :Renovar automáticamente el vehículo cumpla {STRING} @@ -1450,6 +1436,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Grosor de las l STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Mostrar el nombre del GRF en la ventana de construcción de vehículo: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Indicar por medio de una línea adicional en la ventana de construcción de vehículo su NewGRF. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Mostrar la carga que los vehículos pueden llevar en las ventanas de listas {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Al activarse, la carga que el vehículo puede transportar aparecerá en las listas de vehículos STR_CONFIG_SETTING_LANDSCAPE :Ambiente: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Los ambientes definen mapas con diferentes tipos de carga y requisitos de crecimiento de las localidades. Pueden ajustarse con NewGRF y scripts de juego @@ -1504,6 +1492,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Mejorado STR_CONFIG_SETTING_ROAD_SIDE :Autotransportes: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Elegir el lado de la circulación +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Manejar por la izquierda +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Manejar por la derecha + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotar mapa de alturas: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :A la izquierda @@ -1559,8 +1551,8 @@ STR_CONFIG_SETTING_LIVERIES_NONE :Ninguno STR_CONFIG_SETTING_LIVERIES_OWN :Mi empresa STR_CONFIG_SETTING_LIVERIES_ALL :Todas las empresas -STR_CONFIG_SETTING_PREFER_TEAMCHAT :Activar chat de equipo con : {STRING} -STR_CONFIG_SETTING_PREFER_TEAMCHAT_HELPTEXT :Cambiar el acceso al chat interno de la empresa y al chat público entre y +STR_CONFIG_SETTING_PREFER_TEAMCHAT :Activar chat de equipo con la tecla Intro: {STRING} +STR_CONFIG_SETTING_PREFER_TEAMCHAT_HELPTEXT :Cambiar el acceso al chat interno de la empresa y al chat público entre Intro y Ctrl+Intro STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER :Velocidad de la rueda del ratón sobre el mapa: {STRING} STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER_HELPTEXT :Controlar la sensibilidad de la rueda del ratón @@ -1608,7 +1600,7 @@ STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_SHORT :corto (31-12-20 STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES_ISO :ISO (2008-12-31) STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME :Pausar la partida automáticamente al comenzar: {STRING} -STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Al activarse, el juego se detendrá automáticamente al comenzar nuevas partidas para permitir revisar el mapa +STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Al activarse, en cada inicio de partida el juego se detendrá automáticamente, para permitir la inspección del mapa STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL :Al pausar, permitir: {STRING} STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_HELPTEXT :Acciones se pueden realizar mientras el juego está en pausa. @@ -1697,7 +1689,7 @@ STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Activar esta op STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Desactivar autotransportes para la computadora: {STRING} STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Activar esta opción deshabilita la construcción de autotransportes por jugadores no humanos -STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Desactivar aeroplanos para la computadora: {STRING} +STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Desactivar aeronaves para la computadora: {STRING} STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Activar esta opción deshabilita la construcción de aeronaves por jugadores no humanos STR_CONFIG_SETTING_AI_BUILDS_SHIPS :Desactivar barcos para la computadora: {STRING} @@ -1711,7 +1703,7 @@ STR_CONFIG_SETTING_AI_PROFILE_MEDIUM :Intermedio STR_CONFIG_SETTING_AI_PROFILE_HARD :Difícil STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Permitir jugadores no humanos en modo multijugador: {STRING} -STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Permitir a los jugadores controlados por la computadora participar en partidas de varios jugadores +STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Los jugadores controlados por la computadora podrán participar en partidas de varios jugadores STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes disponibles antes de que los scripts sean suspendidos: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Número máximo de operaciones que un script puede realizar por turno @@ -1720,7 +1712,7 @@ STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Cantidad de mem STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Intervalo de mantenimiento en porcentajes: {STRING} -STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Escoger si el mantenimiento de vehículos comenzará debido al tiempo pasado desde el último mantenimiento o por una reducción de la fiabilidad menor de un porcentaje determinado +STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Elegir si el mantenimiento de vehículos se da por días o por fiabilidad menor a un porcentaje específico STR_CONFIG_SETTING_SERVINT_TRAINS :Intervalo de mantenimiento por defecto para trenes: {STRING} STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :Intervalo de mantenimiento por defecto para nuevos trenes, en caso de no definirse otro explícitamente @@ -1730,7 +1722,7 @@ STR_CONFIG_SETTING_SERVINT_AIRCRAFT :Intervalo de ma STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT :Intervalo de mantenimiento por defecto para nuevas aeronaves, en caso de no definirse otro explícitamente STR_CONFIG_SETTING_SERVINT_SHIPS :Intervalo de mantenimiento por defecto para barcos: {STRING} STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT :Intervalo de mantenimiento por defecto para nuevos barcos, en caso de no definirse otro explícitamente -STR_CONFIG_SETTING_SERVINT_VALUE :{COMMA}{NBSP}día{P 0 "" s}/% +STR_CONFIG_SETTING_SERVINT_VALUE :{COMMA}{NBSP}día{P 0 "" s} o % ###setting-zero-is-special STR_CONFIG_SETTING_SERVINT_DISABLED :Deshabilitado @@ -1796,11 +1788,11 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_SUMMARY :Resumen STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :Completo STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Noticias a color aparecen en el año: {STRING} -STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Año en el que los periódicos comenzarán a imprimirse a color. Antes de ese año, apacerán en blanco y negro +STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Año en el que los periódicos se imprimirán a color. Antes de ese año, saldrán en blanco y negro STR_CONFIG_SETTING_STARTING_YEAR :Fecha de inicio: {STRING} STR_CONFIG_SETTING_ENDING_YEAR :Año de fin de juego: {STRING} -STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Año en el que se termina el juego para registrar la puntuación de la empresa y mostrar la tabla de puntuaciones, aunque el jugador puede continuar el juego.{}Cualquier fecha anterior al año de incio hará que la tabla de puntuaciones nunca se muestre. +STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Año en el que se termina el juego para registrar la puntuación de la empresa y mostrar la tabla de puntuaciones, aunque el jugador puede continuar el juego.{}Cualquier fecha anterior al año de inicio hará que la tabla de puntuaciones nunca se muestre. STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} ###setting-zero-is-special STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Nunca @@ -1812,11 +1804,11 @@ STR_CONFIG_SETTING_ECONOMY_TYPE_ORIGINAL :Original STR_CONFIG_SETTING_ECONOMY_TYPE_SMOOTH :Estable STR_CONFIG_SETTING_ECONOMY_TYPE_FROZEN :Rígida -STR_CONFIG_SETTING_ALLOW_SHARES :Permitir comprar acciones de otras empresas: {STRING} -STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Al activarse, se pueden comprar y vender acciones de otras empresas. Las acciones de una empresa solamente estarán disponibles cuando la empresa cumpla una edad determinada +STR_CONFIG_SETTING_ALLOW_SHARES :Permitir compra de acciones de otras empresas: {STRING} +STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Al activarse, se pueden comprar y vender las acciones de otras empresas, aunque solo estarán disponibles a partir de una edad determinada de las empresas STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Edad mínima de la empresa para intercambiar acciones: {STRING} -STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Estabelcer la edad mínima que debe tener una empresa para que otros puedan comprarle y venderle acciones. +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Establecer la edad mínima que debe tener una empresa para que otros puedan comprarle y venderle acciones. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Porcentaje de la utilidad total a pagar por transferencias de carga: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Porcentaje de utilidad cedida a los transportes intermedios en sistemas de transferencia de carga, dando un mayor control sobre la utilidad de cada vehículo @@ -1828,7 +1820,7 @@ STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE :Al arrastrar, m STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE_HELPTEXT :Forma en que se colocan las señales con Ctrl+Arrastrar. Al desactivarse, se colocan señales cerca de túneles y puentes para evitar tramos largos sin señales. Al activarse, se colocan señales cada tanto de casillas, con lo que alinear señales en vías paralelas es más fácil STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE :Señales mecánicas por defecto antes de: {STRING} -STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Año a partir del cual se usarán señales eléctricas. Antes de ese año se usarán señales mecánicas, las cuales funcionan igual pero tienen distinto aspecto +STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE_HELPTEXT :Año a partir del cual se usarán señales eléctricas. Antes de ese año se usarán señales mecánicas, las cuales funcionan igual, pero tienen distinto aspecto STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Cambiar entre tipos de señales: {STRING} STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Elegir la alternación entre señales al usar Ctrl+Clic con la herramienta de señales @@ -1854,10 +1846,10 @@ STR_CONFIG_SETTING_TOWN_LAYOUT_RANDOM :Aleatorio STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :Permitir a las localidades construir carreteras: {STRING} STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Los ayuntamientos construyen carreteras para que las localidades se expandan. Desactivar para impedirlo STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Permitir a las localidades construir pasos a nivel: {STRING} -STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Activar esta opción permite a las localidades construir pasos a nivel +STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Permite a las localidades construir pasos a nivel -STR_CONFIG_SETTING_NOISE_LEVEL :Permitir el ruido de aeropuertos controlado por localidades: {STRING} -STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Al desactivarse, puede haber hasta dos aeropuertos por localidad. Al activarse, el número de aeropuertos por localidad depende de su nivel de ruido permitido, el cual depende de la población, el tamaño de cada aeropuerto y la distancia +STR_CONFIG_SETTING_NOISE_LEVEL :Permitir que localidades controlen ruido de aeropuertos: {STRING} +STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Al desactivarse, solo podrá haber dos aeropuertos por localidad. Al activarse, el número de aeropuertos por localidad se limitará por su nivel de ruido permitido, el cual dependerá de la población, el tamaño del aeropuerto y la distancia STR_CONFIG_SETTING_TOWN_FOUNDING :Fundar localidades: {STRING} STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Activar esta opción permite a los jugadores funda nuevas localidades durante la partida @@ -1875,8 +1867,8 @@ STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Lineal STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Crecimiento de árboles durante la partida: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Controlar la aparición aleatoria de árboles durante la partida. Esto puede afectar industrias que dependen del crecimiento de árboles, como los aserraderos ###length 4 -STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_SPREAD :Crecer pero no expandir {RED}(rompe el aserradero) -STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_RAINFOREST :Crecer pero solo expandir en bosques +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_SPREAD :Crecer, pero no expandir {RED}(rompe el aserradero) +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_RAINFOREST :Crecer, pero solo expandir en bosques STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_ALL :Crecer y expandir por todos lados STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_GROWTH_NO_SPREAD :No crecer ni expandir {RED}(rompe el aserradero) @@ -1937,13 +1929,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Usar {STRING}{N STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Tiempo requerido en el cálculo de cada uno de los componentes de la gráfica de distribución. Cuanto menor sea este valor, más probable es que el juego sea más lento. Cuanto mayor sea, más tiempo tardará la distribución en actualizarse cuando se produzcan cambios en las rutas STR_CONFIG_SETTING_DISTRIBUTION_PAX :Modo de distribución para pasajeros: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :En una distribución "Simétrica" se envía la misma cantidad de pasajeros entre dos estaciones. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de pasajeros en ambas direcciones. "Manual" significa que no hay distribución automática para los pasajeros. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :En una distribución "Simétrica", se envía la misma cantidad de pasajeros de la estación A a la B que de la B a la A. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de pasajeros en cualquier direccion. "Manual" significa que no se realiza una distribución automática para los pasajeros. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Modo de distribución para el correo: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :En una distribución "Simétrica" se envía la misma cantidad de correo entre dos estaciones. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de correo en ambas direcciones. "Manual" significa que no hay distribución automática para el correo +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :En una distribución "Simétrica", se envía la misma cantidad de carga de la estación A a la B que de la B a la A. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no se realiza una distribución automática para el correo. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Modo de distribución para cargamento de valores: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :El cargamento de valores contiene objetos de valor en el ambiente Templado, diamantes en el Subtropical y oro en el Subártico. Algún NewGRF puede modificar esto. En una distribución "Simétrica", se envía la misma cantidad de carga entre dos estaciones. En una distribución "Asimétrica", se envían cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no hay distribución automática para esta carga. Se recomienda la distribución "Asimétrica" o "Manual" al jugar en ambiente Subártico, ya que los bancos no regresan oro a las minas. En los ambiente Templado y Subtropical se puede escoger "Simétrica", ya que los bancos pueden regresar algunos objetos de valor a su banco de origen. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La clase carga BLINDADA contiene objetos de valor en el clima templado, diamantes en el clima subtropical y oro en el clima subártico. Nuevos escenarios puedieran modificar esto. En una distribución "Simétrica", se envía la misma cantidad de carga de la estación A a la B que de la B a la A. En una distribución "Asimétrica" se pueden enviar cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no se realiza una distribución automática para esta carga. Se recomienda fijar esta distribución en "Asimétrica" o en "Manual" al jugar en los clima subártico y subtropical, ya que los bancos sólo reciben carga en esos climas. En el clima templado es factible escoger "Simétrica" ya que los bancos pueden enviar objetos de valor de vuelta al banco de origen. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Modo de distribución para otra carga: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimétrica" significa que se pueden enviar cantidades arbitrarias de carga en ambas direcciones. "Manual" significa que no habrá distribución automática para esta clase de carga. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimétrico" significa que cantidades arbitrarias de carga pueden ser enviadas en cualquier direccion. "Manual" significa que no ocurrira distribución automática para estas cargas. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :Manual STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :Asimétrica @@ -1971,7 +1963,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_GAMEUNITS :Unidades del ju STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER :Unidades de potencia de vehículos: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_HELPTEXT :Cada vez que se muestre la potencia de un vehículo en la interfaz de usuario, se emplearán las unidades elegidas ###length 3 -STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_IMPERIAL :Imperial (cv) +STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_IMPERIAL :Imperial (hp) STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_METRIC :Métrico (cv) STR_CONFIG_SETTING_LOCALISATION_UNITS_POWER_SI :SI (kW) @@ -2003,7 +1995,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_IMPERIAL :Imperial (pies) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_METRIC :Métrico (m) STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (m) -STR_CONFIG_SETTING_LOCALISATION :{ORANGE}Localización +STR_CONFIG_SETTING_LOCALISATION :{ORANGE}Adaptación local STR_CONFIG_SETTING_GRAPHICS :{ORANGE}Gráficos STR_CONFIG_SETTING_SOUND :{ORANGE}Sonido STR_CONFIG_SETTING_INTERFACE :{ORANGE}Interfaz @@ -2016,7 +2008,7 @@ STR_CONFIG_SETTING_ACCOUNTING :{ORANGE}Contabi STR_CONFIG_SETTING_VEHICLES :{ORANGE}Vehículos STR_CONFIG_SETTING_VEHICLES_PHYSICS :{ORANGE}Leyes físicas STR_CONFIG_SETTING_VEHICLES_ROUTING :{ORANGE}Enrutamiento -STR_CONFIG_SETTING_LIMITATIONS :{ORANGE}Limitaciones +STR_CONFIG_SETTING_LIMITATIONS :{ORANGE}Restricciones STR_CONFIG_SETTING_ACCIDENTS :{ORANGE}Desastres y accidentes STR_CONFIG_SETTING_GENWORLD :{ORANGE}Generación de mapa STR_CONFIG_SETTING_ENVIRONMENT :{ORANGE}Entorno @@ -2038,7 +2030,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Cambio de senti STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Los trenes se darán la vuelta ante una señal si han estado esperado durante un tiempo largo ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(recomendado) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(recomendado) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Establecer valor @@ -2081,7 +2073,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Tabla de STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Configuración STR_INTRO_NEWGRF_SETTINGS :{BLACK}Config. NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Contenido en línea -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Configuración de scripts +STR_INTRO_AI_SETTINGS :{BLACK}Configuración de IA +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Scripts de juego STR_INTRO_QUIT :{BLACK}Salir STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Comenzar una nueva partida. Ctrl+Clic omite la configuración del mapa @@ -2101,11 +2094,12 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Mostrar STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Mostrar configuración STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Mostrar configuración de NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Revisar si hay nuevos contenidos actualizados para descargar -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Mostrar configuración de scripts +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Mostrar configuración de IA +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Mostrar configuración de scripts de juego STR_INTRO_TOOLTIP_QUIT :{BLACK}Salir de 'OpenTTD' STR_INTRO_BASESET :{BLACK}A los gráficos base elegidos les hace falta {NUM} spirte{P "" s}. Necesitan actualizarse. -STR_INTRO_TRANSLATION :{BLACK}Este idioma tiene {NUM} cadena{P "" s} de texto sin traducir todavía. Ayudar a mejorar OpenTTD siriviendo como traductor. Consulta el archivo readme.txt para más detalles. +STR_INTRO_TRANSLATION :{BLACK}Este idioma tiene {NUM} cadena{P "" s} de texto sin traducir todavía. Ayudar a mejorar OpenTTD registrándote como traductor. Consulta el archivo readme.txt para más detalles. # Quit window STR_QUIT_CAPTION :{WHITE}Salir @@ -2131,13 +2125,7 @@ STR_CHEAT_EDIT_MAX_HL :{LTBLUE}Cambiar STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}Cambiar la elevación máxima de las montañas en el mapa STR_CHEAT_CHANGE_DATE :{LTBLUE}Cambiar fecha: {ORANGE} {DATE_SHORT} STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Cambiar año actual -STR_CHEAT_SETUP_PROD :{LTBLUE}Permitir cambiar los valores de producción: {ORANGE}{STRING} - -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Ambiente Templado -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Ambiente Subártico -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Ambiente Subtropical -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Ambiente de Mundo de juguetes +STR_CHEAT_SETUP_PROD :{LTBLUE}Permitir cambio de valores de producción: {ORANGE}{STRING} # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Cromática @@ -2371,7 +2359,6 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Nueva empresa) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Crear nueva empresa y unirse a ella STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Este eres tú STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Este es el host del juego -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} cliente{P "" s}/{NUM} empresa{P "" s} # Matches ConnectionType ###length 5 @@ -2386,7 +2373,7 @@ STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Bloquear acceso STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Eliminar STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :Restablecer contraseña -STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Acción de aministrador +STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Acción de administrador STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}¿Sacar al jugador "{STRING}"? STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}¿Bloquear acceso al jugador "{STRING}"? STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}¿Eliminar la empresa "{COMPANY}"? @@ -2498,13 +2485,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :esperando actua STR_NETWORK_MESSAGE_CLIENT_LEAVING :saliendo STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} se unió a la partida -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} se unió a la partida (Cliente #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} se unió a la empresa #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} se unió a la partida (Cliente #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} se unió a la empresa #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} se unió como espectador -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} creó una nueva empresa (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} salió de la partida ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} creó una nueva empresa (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} salió de la partida ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} cambió su nombre a {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} le transfirió {2:CURRENCY_LONG} a {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} le transfirió {2:CURRENCY_LONG} a {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}El servidor ha cerrado la sesión STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Se está reiniciando el servidor...{}Espera por favor... STR_NETWORK_MESSAGE_KICKED :*** {STRING} ha sido expulsado. Razón: ({STRING}) @@ -2585,7 +2572,7 @@ STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE :{WHITE}... no s STR_CONTENT_ERROR_COULD_NOT_EXTRACT :{WHITE}No ha sido posible descomprimir el archivo descargado STR_MISSING_GRAPHICS_SET_CAPTION :{WHITE}Gráficos no encontrados -STR_MISSING_GRAPHICS_SET_MESSAGE :{BLACK}OpenTTD requiere gráficos para funcionar pero no se pudo encontrar ninguno. ¿Permitir que OpenTTD descargue e instale dichos gráficos? +STR_MISSING_GRAPHICS_SET_MESSAGE :{BLACK}OpenTTD requiere gráficos para funcionar pero no se encontró ninguno. ¿Permitir que se descarguen e instalen automáticamente? STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}Sí, descargar los gráficos STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}No, salir de OpenTTD @@ -2618,6 +2605,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}saturado STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}sobrecargado +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} a ser transportad{G 0 o a}{P 0 "" s} al mes desde {STATION} a {STATION} ({COMMA}% de la capacidad){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} a ser transportad{G 0 o a}{P 0 "" s}) de vuelta ({COMMA}% de la capacidad) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Tiempo promedio de viaje: {NUM}{NBSP}día{P "" s} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Mostrar área de recolección STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Desactivado @@ -2626,6 +2618,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}No mostr STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Mostrar área de recolección en el sitio planeado STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Acepta: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Abastece: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Costo de mantenimiento: {GOLD}{CURRENCY_SHORT}/año # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Ampliar estación @@ -2708,8 +2701,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Aumentar STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Selección de puente de ferrocarril STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Selección de puente de carretera STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Selección de puente. Clic para construir -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Colgante (acero) STR_BRIDGE_NAME_GIRDER_STEEL :Vigas (acero) STR_BRIDGE_NAME_CANTILEVER_STEEL :Voladizo (acero) @@ -2727,7 +2722,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Construi STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Construir sección de tranvía. Ctrl quita los carriles de tranvía. Mayús muestra un costo estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Construir carretera con orientación automática. Ctrl quita carreteras. Mayús muestra un costo estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Construir tranvías con orientación automática. Ctrl quita los carriles de tranvía. Mayús muestra un costo estimado -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construir depósito de carretera (para comprar y dar mantenimiento a vehículos). Mayús muestra un costo estimado +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Construir depósito de autotransportes (para comprar y dar mantenimiento a vehículos). Mayús muestra un costo estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}Construir depósito de tranvías (para comprar y dar mantenimiento a tranvías). Mayús muestra un costo estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}Construir parada de autobús. Ctrl activa la ampliación de estaciones. Mayús muestra un costo estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Construir estación de tranvía de pasajeros. Ctrl activa la ampliación de estaciones. Mayús muestra un costo estimado @@ -2813,11 +2808,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Alteraci STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Rebajar una esquina del terreno. Al arrastrar el ratón se rebaja la primera esquina elegida y el resto del terreno seleccionado se nivela a dicha altura. Ctrl para seleccionar un área en diagonal. STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Elevar una esquina del terreno. Al arrastrar el ratón se eleva la primera esquina elegida y se nivela el resto del terreno seleccionado a dicha altura. Ctrl para seleccionar un área en diagonal. Mayús muestra un costo estimado STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Nivelar un área de terreno a la altura de la primera esquina seleccionada. Ctrl para seleccionar un área en diagonal. Mayús muestra un costo estimado -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreno para usos futuros. Mayús muestra un costo estimado +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreno para usos futuros. Ctrl para seleccionar un área en diagonal. Mayús muestra un costo estimado # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Selección de objeto -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Elegir una estructura u objeto a construir. Mayús muestra un costo estimado +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Elegir una estructura u objeto a construir. Ctrl para seleccionar un área en diagonal. Mayús muestra un costo estimado STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Elegir el tipo de objeto o estructura a construir STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Vista previa del objeto STR_OBJECT_BUILD_SIZE :{BLACK}Tamaño: {GOLD}{NUM}×{NUM} casillas @@ -2829,7 +2824,7 @@ STR_OBJECT_CLASS_TRNS :Torres de trans STR_PLANT_TREE_CAPTION :{WHITE}Árboles STR_PLANT_TREE_TOOLTIP :{BLACK}Elegir el tipo de árboles a plantar. Si la casilla ya tiene un árbol, se añadirán más árboles de distintos tipos sin importar el tipo elegido STR_TREES_RANDOM_TYPE :{BLACK}Tipo aleatorio -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Colocar árboles de distinto tipo al azar. Mayús muestra un costo estimado +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Coloca árboles de tipo aleatorio. Ctrl permite seleccionar un área diagonalmente. Mayús permite mostrar una estimación del precio STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Árboles al azar STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Planta árboles al azar sobre el terreno STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2861,6 +2856,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Localida STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Fundar la localidad en un lugar aleatorio STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Muchas localidades aleatorias STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cubrir el mapa con localidades colocadas al azar +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Expandir todas las localidades +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Hacer que todos los pueblos crezcan lentamente STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nombre de la localidad: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Ingresar el nombre de la localidad @@ -2920,7 +2917,7 @@ STR_INDUSTRY_CARGOES_SELECT_INDUSTRY_TOOLTIP :{BLACK}Elegir l # Land area window STR_LAND_AREA_INFORMATION_CAPTION :{WHITE}Información sobre área de terreno -STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Centrar la vista en la casilla.Ctrl+Clic abre una vista aparte +STR_LAND_AREA_INFORMATION_LOCATION_TOOLTIP :{BLACK}Centrar la vista en la casilla. Ctrl+Clic abre una vista aparte STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A :{BLACK}Costo por despejar: {LTBLUE}N/D STR_LAND_AREA_INFORMATION_COST_TO_CLEAR :{BLACK}Costo por despejar: {RED}{CURRENCY_LONG} STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}Ingreso por despejar: {LTBLUE}{CURRENCY_LONG} @@ -3093,7 +3090,7 @@ STR_FRAMETIME_CAPTION_GL_ROADVEHS :Ticks de autotr STR_FRAMETIME_CAPTION_GL_SHIPS :Ticks de barcos STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Ticks de areonaves STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Ticks de mapa -STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Retraro en gráfica de distribución +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Retraso en gráfica de distribución STR_FRAMETIME_CAPTION_DRAWING :Presentación de gráficos STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Presentación de ventanas de vista generales STR_FRAMETIME_CAPTION_VIDEO :Salida de video @@ -3125,7 +3122,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Detalles STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}No hay información disponible STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtrar texto: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtrar: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Sobrescribir archivo STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}¿Estás seguro de sobrescribir el archivo? STR_SAVELOAD_DIRECTORY :{STRING} (Carpeta) @@ -3139,6 +3136,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Tamaño STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Elegir el tamaño del mapa en número de casillas. El número real de casillas disponibles en el mapa será ligeramente inferior STR_MAPGEN_BY :{BLACK}× STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Núm. de localidades: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nombres de localidades: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Elegir el estilo de nombres para las localidades STR_MAPGEN_DATE :{BLACK}Fecha: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Núm. de industrias: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Cima más alta: @@ -3152,13 +3151,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Extensi STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Incrementar extensión de desierto un 10% STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Disminuir extensión de desierto un 10% STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Generador de terreno: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tipo de terreno: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Nivel del mar: +STR_MAPGEN_SEA_LEVEL :{BLACK}Nivel del mar: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Ríos: STR_MAPGEN_SMOOTHNESS :{BLACK}Suavidad: STR_MAPGEN_VARIETY :{BLACK}Variedad: STR_MAPGEN_GENERATE :{WHITE}Generar +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Configuración de NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Mostrar configuración de NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Configuración de IA +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Mostrar configuración de IA +STR_MAPGEN_GS_SETTINGS :{BLACK}Configuración de scripts de juego +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Mostrar configuración de scripts de juego + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Inglés +STR_MAPGEN_TOWN_NAME_FRENCH :Francés +STR_MAPGEN_TOWN_NAME_GERMAN :Alemán +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Inglés (adicional) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :América Latina +STR_MAPGEN_TOWN_NAME_SILLY :Tonterías (inglés) +STR_MAPGEN_TOWN_NAME_SWEDISH :Sueco +STR_MAPGEN_TOWN_NAME_DUTCH :Holandés +STR_MAPGEN_TOWN_NAME_FINNISH :Finlandés +STR_MAPGEN_TOWN_NAME_POLISH :Polaco +STR_MAPGEN_TOWN_NAME_SLOVAK :Eslovaco +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Noruego +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Húngaro +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austríaco +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumano +STR_MAPGEN_TOWN_NAME_CZECH :Checo +STR_MAPGEN_TOWN_NAME_SWISS :Suizo +STR_MAPGEN_TOWN_NAME_DANISH :Danés +STR_MAPGEN_TOWN_NAME_TURKISH :Turco +STR_MAPGEN_TOWN_NAME_ITALIAN :Italiano +STR_MAPGEN_TOWN_NAME_CATALAN :Catalán # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Bordes del mapa: @@ -3217,7 +3244,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Informac STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Archivos NewGRF activos STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Archivos NewGRF inactivos STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Seleccionar perfil: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtrar texto: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtrar: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Cargar perfil STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Guardar STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Guardar lista actual como nuevo perfil @@ -3304,6 +3331,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Sprite a STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Ir al sprite anterior (ignorando pseudosprites, sprites coloreados y sprites de fuente) y pasar del primer al último sprite STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representación del sprite elegido. Se ignora la alineación al ser dibujado STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Mover el sprite cambiando los valores X y Y. Ctrl+Clic mueve el sprite ocho unidades de una sola vez + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Desfasaje reiniciado al centro +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centrado + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Punto de mira + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Restaurar coordenadas relativas STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Restaurar las coordenadas relativas STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Coordenada X: {NUM}, Coordenada Y: {NUM} (absoluta) @@ -3318,24 +3352,23 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Atención: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Error: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Error fatal: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Ocurrió un error fatal de NewGRF:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Ocurrió un error de NewGRF:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}Ha ocurrido un error en el NewGRF "{STRING}":{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} no funcionará con la con la versión de TTDPatch reportada por OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} es la para la versión {STRING} de TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} está diseñado para usarse con {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Parámetro no válido para {1:STRING}: parámetro {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} debe cargarse antes de {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} debe cargarse después de {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requiere OpenTTD versión {STRING} o superior +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} es la para la versión {2:STRING} de TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} está diseñado para usarse con {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Parámetro no válido para {1:STRING}: parámetro {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} debe cargarse antes de {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} debe cargarse después de {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requiere OpenTTD versión {2:STRING} o superior STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :El archivo GRF fue diseñado para ser traducido STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Demasiados NewGRF cargados -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Cargar {1:STRING} como NewGRF estático con {STRING} puede causar desincronizaciones +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Cargar {1:STRING} como NewGRF estático con {2:STRING} puede causar asincronías STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Sprite inesperado (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Propiedad de Acción 0 desconocida {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Intento de usar una ID no válida (sprite {3:NUM}) STR_NEWGRF_ERROR_CORRUPT_SPRITE :{YELLOW}{STRING} contiene un sprite con errores. Todos los sprites con errores se muestran como un símbolo de interrogación rojo (?) STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Contiene múltiples entradas de Acción 8 (sprite {3:NUM}) -STR_NEWGRF_ERROR_READ_BOUNDS :La lectura excedió el límite de pseudo-sprite (sprite {3:NUM}) +STR_NEWGRF_ERROR_READ_BOUNDS :La lectura excedió el límite de un pseudosprite (sprite {3:NUM}) STR_NEWGRF_ERROR_GRM_FAILED :Recursos GRF solicitados no disponibles (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} fue desactivado por {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Formato de colocación de sprites no válido o desconocido (sprite {3:NUM}) @@ -3461,14 +3494,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Comprar los der STR_LOCAL_AUTHORITY_ACTION_BRIBE :Sobornar al ayuntamiento ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Iniciar una pequeña campaña publicitaria local para atraer más pasajeros y carga a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio pequeño alrededor del centro de la localidad.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Iniciar una campaña publicitaria local mediana para atraer más pasajeros y carga a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio mediano alrededor del centro de la localidad.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Iniciar una gran campaña publicitaria local para atraer más pasajeros y carga a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio grande alrededor del centro de la localidad.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Pagar la reconstrucción de las carreteras locales.{}Provoca considerables complicaciones al tráfico hasta por 6 meses.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Construir una estatua en honor a tu empresa.{}Otorga un aumento permanente a la evaluación estaciones en esta localidad.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Pagar la construcción de nuevos edificios comerciales en la localidad.{}Otorga un aumento temporal a su crecimiento.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Comprar los derechos exclusivos de transporte en esta localidad por un año.{}El ayuntamiento solo permitirá el uso de estaciones que sean de tu empresa.{}Costo: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Sobornar al ayuntamiento para aumentar mejorar tu evaluación, con el riesgo de una severa penalización si llegas a ser descubierto.{}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniciar una pequeña campaña publicitaria local para atraer más pasajeros y carga a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio pequeño alrededor del centro de la localidad.{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniciar una campaña publicitaria local mediana para atraer más pasajeros y carga a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio mediano alrededor del centro de la localidad.{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniciar una gran campaña publicitaria local para atraer más pasajeros y carga a tus servicios de transporte.{}Otorga un aumento temporal a la evaluación de estaciones en un radio grande alrededor del centro de la localidad.{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Pagar la reconstrucción de las carreteras locales.{}Provoca considerables complicaciones al tráfico hasta por 6 meses.{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Construir una estatua en honor a tu empresa.{}Otorga un aumento permanente a la evaluación estaciones en esta localidad.{}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Pagar la construcción de nuevos edificios comerciales en la localidad.{}Otorga un aumento temporal a su crecimiento.{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Comprar los derechos exclusivos de transporte en esta localidad por un año.{}El ayuntamiento solo permitirá el uso de estaciones que sean de tu empresa.{}{POP_COLOUR}Costo: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Sobornar al ayuntamiento para aumentar mejorar tu evaluación, con el riesgo de una severa penalización si llegas a ser descubierto.{}{POP_COLOUR}Costo: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}Metas de {COMPANY} @@ -3526,11 +3559,11 @@ STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}Historia STR_STORY_BOOK_SPECTATOR :Historial global STR_STORY_BOOK_TITLE :{YELLOW}{STRING} STR_STORY_BOOK_GENERIC_PAGE_ITEM :Página {NUM} -STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}Permitir ir a una página específica al elegirla en esta lista desplegable +STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}Pasar a una página específica al elegirla de esta lista STR_STORY_BOOK_PREV_PAGE :{BLACK}Anterior STR_STORY_BOOK_PREV_PAGE_TOOLTIP :{BLACK}Ir a la página anterior STR_STORY_BOOK_NEXT_PAGE :{BLACK}Siguiente -STR_STORY_BOOK_NEXT_PAGE_TOOLTIP :{BLACK}Ir a la siguiente página +STR_STORY_BOOK_NEXT_PAGE_TOOLTIP :{BLACK}Ir a la página siguiente STR_STORY_BOOK_INVALID_GOAL_REF :{RED}Referencia a objetivos no válida # Station list window @@ -3605,7 +3638,7 @@ STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP :{BLACK}Mostrar STR_STATION_VIEW_RENAME_STATION_CAPTION :Cambiar nombre de estación STR_STATION_VIEW_CLOSE_AIRPORT :{BLACK}Cerrar aeropuerto -STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}No permitir que aterricen aviones en este aeropuerto +STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}Evita el aterrizaje de aeronaves en este aeropuerto # Waypoint/buoy view window STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT} @@ -3641,15 +3674,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Barcos STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}T. de interés del préstamo STR_FINANCES_SECTION_OTHER :{GOLD}Otros +STR_FINANCES_TOTAL_CAPTION :{WHITE}Total STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Utilidad neta +STR_FINANCES_PROFIT :{WHITE}Ganancias STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Saldo en banco STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Fondos propios STR_FINANCES_LOAN_TITLE :{WHITE}Préstamo STR_FINANCES_INTEREST_RATE :{WHITE}T. de interés del préstamo: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Préstamo máximo: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Pedir préstamo de {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Incrementar préstamo. Ctrl+Clic solicita todo el préstamo posible STR_FINANCES_REPAY_BUTTON :{BLACK}Abonar {CURRENCY_LONG} del préstamo @@ -3664,7 +3700,7 @@ STR_COMPANY_VIEW_INAUGURATED_TITLE :{GOLD}Inaugurac STR_COMPANY_VIEW_COLOUR_SCHEME_TITLE :{GOLD}Cromática: STR_COMPANY_VIEW_VEHICLES_TITLE :{GOLD}Vehículos: STR_COMPANY_VIEW_TRAINS :{WHITE}{COMMA} tren{P "" es} -STR_COMPANY_VIEW_ROAD_VEHICLES :{WHITE}{COMMA} vehículo{P "" s} de carretera +STR_COMPANY_VIEW_ROAD_VEHICLES :{WHITE}{COMMA} autotransporte{P "" s} STR_COMPANY_VIEW_AIRCRAFT :{WHITE}{COMMA} aeronave{P "" s} STR_COMPANY_VIEW_SHIPS :{WHITE}{COMMA} barco{P "" s} STR_COMPANY_VIEW_VEHICLES_NONE :{WHITE}Ninguno @@ -3733,7 +3769,7 @@ STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUST STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} y {NUM} más... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nombres de industrias. Clic para centrar la vista en la industria. Ctrl+Clic abre una vista aparte STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Carga aceptada: {SILVER}{STRING} -STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Cargemento producido: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Carga producida: {SILVER}{STRING} STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Todos los tipos STR_INDUSTRY_DIRECTORY_FILTER_NONE :Ninguno @@ -3750,7 +3786,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produce: STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Requiere: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} esperando{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Cambiar producción (múltiplo de 8, máximo 2040) @@ -3759,7 +3795,7 @@ STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Cambiar # Vehicle lists ###length VEHICLE_TYPES STR_VEHICLE_LIST_TRAIN_CAPTION :{WHITE}{STRING}: {COMMA} tren{P "" es} -STR_VEHICLE_LIST_ROAD_VEHICLE_CAPTION :{WHITE}{STRING}: {COMMA} vehículo{P "" s} de carretera +STR_VEHICLE_LIST_ROAD_VEHICLE_CAPTION :{WHITE}{STRING}: {COMMA} autotransporte{P "" s} STR_VEHICLE_LIST_SHIP_CAPTION :{WHITE}{STRING}: {COMMA} barco{P "" s} STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING}: {COMMA} aeronave{P "" s} @@ -3780,6 +3816,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Enviar i STR_VEHICLE_LIST_REPLACE_VEHICLES :Reemplazar vehículos STR_VEHICLE_LIST_SEND_FOR_SERVICING :Enviar a mantenimiento STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Ganancias este año: {CURRENCY_LONG} (último año: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Enviar a depósito STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Enviar a depósito @@ -3871,11 +3909,16 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Máx. fu STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Alcance: {GOLD}{COMMA} casillas STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipo de aeronave: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Todos los tipos +STR_CARGO_TYPE_FILTER_FREIGHT :Carga +STR_CARGO_TYPE_FILTER_NONE :Ninguno + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Lista de selección trenes. Clic en un tren para más información. Ctrl+Clic para mostrar u ocultar el tipo de tren STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Lista de selección de autotransportes. Clic en un vehículo para más información. Ctrl+Clic para mostrar u ocultar el tipo del vehículo STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}Lista de selección de barcos. Clic en un barco para más información. Ctrl+Clic para mostrar u ocultar el tipo de barco -STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Lista de selección de aeronaves. Clic en un aeronave para más información. Ctrl+Clic para mostrar u ocultar el tipo de aeronave +STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Lista de selección de aeronaves. Clic en una aeronave para más información. Ctrl+Clic para mostrar u ocultar el tipo de aeronave ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Comprar @@ -3899,7 +3942,7 @@ STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar el tren elegido. Mayús+Clic muestra un precio estimado de compra STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar el autotransporte elegido. Mayús+Clic muestra un precio estimado de compra STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar el barco elegido. Mayús+Clic muestra un precio estimado de compra -STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar la areonave seleccionada. Mayús+Clic muestra un costo estimado de compra +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar la aeronave seleccionada. Mayús+Clic muestra un costo estimado de compra ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Cambiar nombre @@ -3946,7 +3989,7 @@ STR_DEPOT_RENAME_DEPOT_CAPTION :Cambiar nombre STR_DEPOT_NO_ENGINE :{BLACK}- STR_DEPOT_VEHICLE_TOOLTIP :{BLACK}{ENGINE}{STRING} STR_DEPOT_VEHICLE_TOOLTIP_CHAIN :{BLACK}{NUM} vehículo{P "" s}{STRING} -STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} ({CARGO_SHORT}) +STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} (capacidad: {CARGO_SHORT}) ###length VEHICLE_TYPES STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Trenes: arrastrar vehículos de ferrocarril con Clic izquierdo para añadirlos o quitarlos del tren. Clic derecho para más información. Mantener pulsado Ctrl para usar estos comandos con el resto del tren @@ -4039,7 +4082,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :{G=f}aeronave STR_ENGINE_PREVIEW_SHIP :{G=m}barco STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Costo: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocidad: {VELOCITY} Potencia: {POWER}{}Costo de operación: {CURRENCY_LONG}/año{}Capacidad: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Costo: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocidad: {VELOCITY} Potencia: {POWER} Máx. F.T.: {6:FORCE}{}Costo de operación: {4:CURRENCY_LONG}/año{}Capacidad: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Costo: {0:CURRENCY_LONG} Peso: {1:WEIGHT_SHORT}{}Velocidad: {2:VELOCITY} Potencia: {3:POWER} Máx. F.T.: {6:FORCE}{}Costo de operación: {4:CURRENCY_LONG}/año{}Capacidad: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Costo: {CURRENCY_LONG} Velocidad máx.: {VELOCITY}{}Capacidad: {CARGO_LONG}{}Costo de mantenimiento: {CURRENCY_LONG}/año STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Costo: {CURRENCY_LONG} Vel. máx.: {VELOCITY}{}Tipo de aeronave: {STRING}{}Capacidad: {CARGO_LONG}, {CARGO_LONG}{}Costo de operación: {CURRENCY_LONG} al año STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Costo: {CURRENCY_LONG} Vel. máx.: {VELOCITY}{}Tipo de aeronave: {STRING}{}Capacidad: {CARGO_LONG}{}Costo de operación: {CURRENCY_LONG} al año @@ -4080,8 +4123,8 @@ STR_REPLACE_ALL_RAILTYPE :Todos los vehí STR_REPLACE_ALL_ROADTYPE :Todos los autotransportes ###length 2 -STR_REPLACE_HELP_RAILTYPE :{BLACK}Elegir el tipo de vías férreas para las que se desea reemplazar locomotoras -STR_REPLACE_HELP_ROADTYPE :{BLACK}Elegir el tipo de carretera para el que se desea reemplazar locomotoras +STR_REPLACE_HELP_RAILTYPE :{BLACK}Elegir el tipo de vías férreas según el vehículo ferroviario a reemplazar +STR_REPLACE_HELP_ROADTYPE :{BLACK}Elegir el tipo de carretera según el autotransporte a reemplazar ###next-name-looks-similar STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Mostrar el vehículo que reemplazará al otro de la izquierda @@ -4093,7 +4136,7 @@ STR_REPLACE_MAGLEV_VEHICLES :Trenes maglev STR_REPLACE_ROAD_VEHICLES :Autotransportes STR_REPLACE_TRAM_VEHICLES :Vehículos de tranvía -STR_REPLACE_REMOVE_WAGON :{BLACK}Quitar vagó ({STRING}): {ORANGE}{STRING} +STR_REPLACE_REMOVE_WAGON :{BLACK}Quitar vagones ({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 STR_REPLACE_REMOVE_WAGON_GROUP_HELP :{STRING}. Ctrl+Clic para incluir subgrupos @@ -4198,12 +4241,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {L STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potencia: {LTBLUE}{POWER}{BLACK} Velocidad máx.: {LTBLUE}{VELOCITY} {BLACK}F.T. máx.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Ganancias este año: {LTBLUE}{CURRENCY_LONG} (último año: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Ganancias este año: {LTBLUE}{CURRENCY_LONG} (último año: {CURRENCY_LONG}) {BLACK}Mín. rendimiento: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilidad: {LTBLUE}{COMMA}% {BLACK}Averías desde el último mantenimiento: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Construido: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacidad: {LTBLUE}Ninguna{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidad: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacidad: {LTBLUE}{CARGO_LONG}{3:STRING} (×{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidad: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacidad: {LTBLUE}{0:CARGO_LONG}{3:STRING} (×{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacidad: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Créditos por transferencia: {LTBLUE}{CURRENCY_LONG} @@ -4332,7 +4376,7 @@ STR_ORDER_CONDITIONAL_AGE :Edad (años) STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :Requiere mantenimiento STR_ORDER_CONDITIONAL_UNCONDITIONALLY :Siempre STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :Vida útil restante (años) -STR_ORDER_CONDITIONAL_MAX_RELIABILITY :Fabilidad máxima +STR_ORDER_CONDITIONAL_MAX_RELIABILITY :Fiabilidad máxima ###next-name-looks-similar STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}Comparación de los datos del vehículo respecto al valor dado @@ -4472,22 +4516,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Fecha de STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Elegir una fecha de inicio del itinerario. Ctrl+Clic para distribuir uniformemente todos los demás vehículos que lo compartan, siempre y cuando esté programado completamente STR_TIMETABLE_CHANGE_TIME :{BLACK}Cambiar tiempo -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Cambiar cuánto debe tardar el recorrido resaltado +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Modifica la cantidad de tiempo que la orden seleccionada debe tomar. Ctrl+clic modifica la duración para todas las órdenes STR_TIMETABLE_CLEAR_TIME :{BLACK}Borrar tiempo -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Anula el tiempo en el recorrido resaltado +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Borra la cantidad de tiempo para la orden resaltada.Ctrl+clic elimina el tiempo para todas las órdenes STR_TIMETABLE_CHANGE_SPEED :{BLACK}Cambiar límite de velocidad -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Cambiar el límite de velocidad en el recorrido resaltado +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Cambia el límite máximo de velocidad de la orden resaltada. Ctrl+clic cambia el límite para todas las órdenes STR_TIMETABLE_CLEAR_SPEED :{BLACK}Borrar límite de velocidad -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Anular el límite de velocidad en el recorrido resaltado +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Borra el límite máximo de velocidad de la orden resaltada. Ctrl+clic elimina la velocidad para todas las órdenes STR_TIMETABLE_RESET_LATENESS :{BLACK}Reiniciar retrasos STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Reiniciar el contador del retraso para que el vehículo vaya a tiempo STR_TIMETABLE_AUTOFILL :{BLACK}Llenar automáticamente -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Llenar la tabla de itinerarios automáticamente con los valores del siguiente recorrido (Ctrl+Clic para intentar mantener los tiempos de espera) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Rellena el horario automáticamente con los valores del siguiente recorrido. Ctrl+clic para intentar mantener los tiempos de espera en estación STR_TIMETABLE_EXPECTED :{BLACK}Esperado STR_TIMETABLE_SCHEDULED :{BLACK}Programado @@ -4531,12 +4575,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Uno de l STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}La ventana de depuración de scripts solo está disponible para el servidor # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Configuración de scripts +STR_AI_CONFIG_CAPTION_AI :{WHITE}Configuración de IA +STR_AI_CONFIG_CAPTION_GAMESCRIPT :Configuración de scripts de juego STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Script de juego que será cargado en la próxima partida STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Scripts de IA que serán cargados la próxima partida STR_AI_CONFIG_HUMAN_PLAYER :Jugador humano STR_AI_CONFIG_RANDOM_AI :IA aleatoria STR_AI_CONFIG_NONE :(ninguno) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Núm. máximo de jugadores: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Mover hacia arriba STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Mover la IA elegida una posición hacia arriba @@ -4544,12 +4590,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Mover ha STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Mover la IA elegida una posición hacia abajo STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script de juego +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parámetros STR_AI_CONFIG_AI :{SILVER}IA -STR_AI_CONFIG_CHANGE :{BLACK}Seleccionar {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :IA -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script de juego +STR_AI_CONFIG_CHANGE_AI :{BLACK}Elegir IA +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Elegir script de juego STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Cargar otro script STR_AI_CONFIG_CONFIGURE :{BLACK}Configurar STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configurar los parámetros del script @@ -4577,10 +4622,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Mapa com STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Mapa de alturas STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Captura de minimapa -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}Parámetros {STRING} -STR_AI_SETTINGS_CAPTION_AI :IA -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script de juego +# Script Parameters +STR_AI_SETTINGS_CAPTION_AI :{WHITE}Parámetros de IA STR_AI_SETTINGS_CLOSE :{BLACK}Cerrar STR_AI_SETTINGS_RESET :{BLACK}Reiniciar STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4685,9 +4728,9 @@ STR_ERROR_SITE_UNSUITABLE :{WHITE}... luga STR_ERROR_ALREADY_BUILT :{WHITE}... ya construido STR_ERROR_OWNED_BY :{WHITE}... propiedad de {STRING} STR_ERROR_AREA_IS_OWNED_BY_ANOTHER :{WHITE}... otra empresa es dueña de esta área -STR_ERROR_TERRAFORM_LIMIT_REACHED :{WHITE}... límite de modificación de terreno alcanzado -STR_ERROR_CLEARING_LIMIT_REACHED :{WHITE}... límite de casillas despejadas alcanzado -STR_ERROR_TREE_PLANT_LIMIT_REACHED :{WHITE}... limite de plantación de árboles alcanzado +STR_ERROR_TERRAFORM_LIMIT_REACHED :{WHITE}... no se puede modificar más terreno +STR_ERROR_CLEARING_LIMIT_REACHED :{WHITE}... no se pueden despejar más casillas +STR_ERROR_TREE_PLANT_LIMIT_REACHED :{WHITE}... no se pueden plantar más árboles STR_ERROR_NAME_MUST_BE_UNIQUE :{WHITE}El nombre debe ser único STR_ERROR_GENERIC_OBJECT_IN_THE_WAY :{WHITE}{1:STRING} estorba STR_ERROR_NOT_ALLOWED_WHILE_PAUSED :{WHITE}No permitido en pausa @@ -4744,6 +4787,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... dema STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}No se pueden crear industrias... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}No se puede construir {STRING} aquí... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}No se puede construir este tipo de industria aquí... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}No se puede hacer prospección para la industria... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... demasiado cerca de otra industria STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... primero se debe crear al menos una localidad STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... solo se permite una por localidad @@ -4758,6 +4802,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... los STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... solo se puede construir por encima del nivel de nieve STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... solo se puede construir por debajo del nivel de nieve +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Mala suerte, la financiación no fructificó; inténtentelo de nuevo +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}No se encontraron lugares aptos para hacer prospección de esta industria STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}No hubo espacio para industrias de tipo "{STRING}" STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Cambia las opciones de generación para crear un mejor mapa @@ -4901,7 +4947,7 @@ STR_ERROR_CAN_T_PLANT_TREE_HERE :{WHITE}No se pu STR_ERROR_CAN_T_BUILD_BRIDGE_HERE :{WHITE}No se puede construir puente aquí... STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Primero se debe demoler el puente STR_ERROR_CAN_T_START_AND_END_ON :{WHITE}No se puede comenzar y acabar en la misma posición -STR_ERROR_BRIDGEHEADS_NOT_SAME_HEIGHT :{WHITE}Las estribos del puente no están al mismo nivel +STR_ERROR_BRIDGEHEADS_NOT_SAME_HEIGHT :{WHITE}Los estribos del puente no están al mismo nivel STR_ERROR_BRIDGE_TOO_LOW_FOR_TERRAIN :{WHITE}El puente es demasiado bajo para este terreno STR_ERROR_BRIDGE_TOO_HIGH_FOR_TERRAIN :{WHITE}El puente es demasiado alto para este terreno STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Principio y final deben estar alineados @@ -4925,6 +4971,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Otro obj STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... la sede de la empresa estorba STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}No se puede adquirir este terreno... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... ¡ya fue adquirido por el jugador! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :... no se pueden construir más objetos # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}No se puede crear grupo... @@ -4972,7 +5019,7 @@ STR_ERROR_CAN_T_STOP_START_AIRCRAFT :{WHITE}No se pu STR_ERROR_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}No se puede enviar el tren al depósito... STR_ERROR_CAN_T_SEND_ROAD_VEHICLE_TO_DEPOT :{WHITE}No se puede enviar el vehículo al depósito... STR_ERROR_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}No se puede enviar el barco a astillero... -STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR :{WHITE}No se puede enviar el aeronave al hangar +STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR :{WHITE}No se puede enviar la aeronave al hangar ###length VEHICLE_TYPES STR_ERROR_CAN_T_BUY_TRAIN :{WHITE}No se puede comprar tren... @@ -4997,6 +5044,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}No se pu STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... el vehículo está destruido +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... no todos los vehículos son idénticos + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}No habrá vehículos disponibles STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Se debe modificar la configuración de NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Todavía no hay vehículos disponibles @@ -5023,6 +5072,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}No se pu STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... el vehículo no puede ir a todas las estaciones STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... el vehículo no puede ir a esa estación STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... un vehículo que comparte este recorrido no puede ir a esa estación +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... no todos los vehículos tienen los mismos recorridos +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... no todos los vehículos comparten los recorridos STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}No se puede compartir la lista de recorridos... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}No se puede dejar de compartir la lista de recorridos... @@ -5030,6 +5081,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}No se pu STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... demasiado lejos del destino anterior STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... la aeronave no tiene suficiente alcance +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}No se pueden asignar itinerarios al vehículo... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Los vehículos solo pueden esperar en estaciones @@ -5076,7 +5129,7 @@ STR_TOWN_BUILDING_NAME_MODERN_OFFICE_BUILDING_1 :Edificio de ofi STR_TOWN_BUILDING_NAME_WAREHOUSE_1 :Almacén STR_TOWN_BUILDING_NAME_OFFICE_BLOCK_3 :Edificio de oficinas STR_TOWN_BUILDING_NAME_STADIUM_1 :Estadio -STR_TOWN_BUILDING_NAME_OLD_HOUSES_1 :Casas antiguass +STR_TOWN_BUILDING_NAME_OLD_HOUSES_1 :Casas antiguas STR_TOWN_BUILDING_NAME_COTTAGES_1 :Casas rurales STR_TOWN_BUILDING_NAME_HOUSES_1 :Casas STR_TOWN_BUILDING_NAME_FLATS_1 :Departamentos diff --git a/src/lang/swedish.txt b/src/lang/swedish.txt index c2931264ee52d..db38cd1117c28 100644 --- a/src/lang/swedish.txt +++ b/src/lang/swedish.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hk STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hk STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hk/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hk/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hk/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hk/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hk/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hk/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -226,8 +236,8 @@ STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Sökfilter: -STR_LIST_FILTER_OSKTITLE :{BLACK}Skriv in sökfilter -STR_LIST_FILTER_TOOLTIP :{BLACK}Skriv in ett sökord att filtrera listan efter +STR_LIST_FILTER_OSKTITLE :{BLACK}Skriv in ett eller flera sökord att filtrera listan efter +STR_LIST_FILTER_TOOLTIP :{BLACK}Skriv in ett eller flera sökord att filtrera listan efter STR_TOOLTIP_GROUP_ORDER :{BLACK}Välj order att gruppera på STR_TOOLTIP_SORT_ORDER :{BLACK}Välj sorteringsordning (fallande/stigande) @@ -247,7 +257,7 @@ STR_TOOLTIP_RESIZE :{BLACK}Klicka o STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Växla stor/liten fönsterstorlek STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST :{BLACK}Rullningslist - rullar listan upp/ned STR_TOOLTIP_HSCROLL_BAR_SCROLLS_LIST :{BLACK}Rullningslist - rullar listan höger/vänster -STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Riv byggnader etc. på en markruta. Ctrl väljer yta diagonalt. Shift växlar mellan att riva/visa beräknad kostnad +STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC :{BLACK}Riv byggnader etc. på en markruta. Ctrl väljer ytan diagonalt. Shift växlar mellan att riva/visa beräknad kostnad # Show engines button ###length VEHICLE_TYPES @@ -376,9 +386,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Generera STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Generera industrier STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Bygg vägar STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Spårvägskonstruktion -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantera träd. Shift växlar mellan att bygga/visa beräknad kostnad +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantera träd. Ctrl väljer ytan diagonalt. Shift växlar mellan att bygga/visa beräknad kostnad STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Placera skylt -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Placera objekt. Shift växlar mellan att bygga/visa beräknad kostnad +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Placera objekt. Ctrl väljer ytan diagonalt. Shift växlar mellan att bygga/visa beräknad kostnad # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Avsluta # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Spelinställningar STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Inställningar -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Inställningar för datorspelare / spelskript +STR_SETTINGS_MENU_AI_SETTINGS :Inställningar för AI +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Spelskriptinställningar STR_SETTINGS_MENU_NEWGRF_SETTINGS :Inställningar för NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Inställningar för genomskinlighet STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Stadsnamn visas @@ -753,7 +764,7 @@ STR_SMALLMAP_LEGENDA_FOREST :{TINY_FONT}{BLA STR_SMALLMAP_LEGENDA_RAILROAD_STATION :{TINY_FONT}{BLACK}Järnvägsstation STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY :{TINY_FONT}{BLACK}Lastbrygga STR_SMALLMAP_LEGENDA_BUS_STATION :{TINY_FONT}{BLACK}Busshållplats -STR_SMALLMAP_LEGENDA_AIRPORT_HELIPORT :{TINY_FONT}{BLACK}Flygplats/Helikopterplats +STR_SMALLMAP_LEGENDA_AIRPORT_HELIPORT :{TINY_FONT}{BLACK}Flygplats/Helikopterflygplats STR_SMALLMAP_LEGENDA_DOCK :{TINY_FONT}{BLACK}Hamn STR_SMALLMAP_LEGENDA_ROUGH_LAND :{TINY_FONT}{BLACK}Obearbetad mark STR_SMALLMAP_LEGENDA_GRASS_LAND :{TINY_FONT}{BLACK}Gräsmark @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Indisk rupie (I STR_GAME_OPTIONS_CURRENCY_IDR :Indonesisk rupie (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malaysisk ringgit (MYR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}Välj typ av stadsnamn - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Engelska (Original) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Franska -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Tyska -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Engelska (Extra) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latinamerikanska -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Löjliga -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Svenska -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Hollänska -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finska -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polska -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovakiska -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norska -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Ungerska -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Österrikiska -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rumänska -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tjeckiska -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Schweiziska -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danska -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turkiska -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italienska -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalanska - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Spara automatiskt STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Välj intervall mellan automatiskt sparande @@ -1027,21 +1008,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Markera STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Nuvarande drivrutin: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Gränssnittstorlek -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Välj vilken gränssnittsstorlek som ska användas +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Gränssnittets storlek +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Dra i reglaget för att ställa in gränssnittets storlek. Håll in Ctrl för steglös inställning +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Känn av storleken automatiskt +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Kryssa i den här rutan för automatisk inställning av gränssnittets storlek -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(Upptäck automatiskt) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dubbel storlek -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Fyrdubbel storlek +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Skala bården +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Kryssa i den här rutan för att skala bården efter gränssnittets storlek -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Storlek på typsnitt -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Välj vilken storlek som ska användas på gränssnittets typsnitt - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(Upptäck automatiskt) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dubbel storlek -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Kvadrupel storlek +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafik @@ -1093,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Förhan 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} - STR_NONE :Ingen STR_FUNDING_ONLY :Endast finansiering STR_MINIMAL :Minimal @@ -1144,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Tempererat landskap +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arktiskt landskap +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropiskt landskap +STR_CLIMATE_TOYLAND_LANDSCAPE :Leksakslandskap + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Väldigt platt STR_TERRAIN_TYPE_FLAT :Platt @@ -1223,6 +1206,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Höger STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Maximalt startlån: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximalt belopp ett företag kan låna (där inflationen inte tas med i beräkningen) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Inget lån {RED}Kräver spelskript som sätter startkapital STR_CONFIG_SETTING_INTEREST_RATE :Räntenivå: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Räntenivå för lån; styr även inflationen om sådan är aktiverad @@ -1449,6 +1435,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Linjernas bredd STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Visa NewGRF:ens namn i fordonsbyggnadsfönstret: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Lägg till en rad i fordonsbyggnadsfönstret som visar vilken NewGRF det valda fordonet kommer ifrån. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Visa godstyper som fordonen kan transportera i listorna {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Om det är aktiverat kommer fordonets transportabla last att visas ovanför den i fordonslistor STR_CONFIG_SETTING_LANDSCAPE :Landskap: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landskapet definierar grundläggande gameplay scenarier med olika laster och krav på stadstillväxt. NewGRF och spelskript tillåter finare kontroll @@ -1503,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Förbättrad STR_CONFIG_SETTING_ROAD_SIDE :Vägfordon: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Välj körsida +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Kör på vänster sida +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Kör på höger sida + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Höjdkartans rotation: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Motsols @@ -1714,7 +1706,7 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Tillåt datorst STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes innan skript sätts i viloläge: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Maximalt antal beräkningssteg ett skript kan utföra i en omgång -STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Maximalt minnesanvändning per skript: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Maximal minnesanvändning per skript: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Hur mycket minne ett enda skript kan konsumera innan det tvingas avslutas. Det kan behöva ökas för stora kartor. STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB @@ -1936,13 +1928,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Avsätt {STRING STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Den tid varje omberäkning av en länkgrafkomponent tillåts ta. När en omberäkning startas skapas en tråd som tillåts löpa detta antal dagar. Ju kortare du sätter denna, desto mer troligt är det att tråden inte är hinner bli färdig i tid. Då kommer spelet att stanna tills den är klar (vilket gör att det laggar). Ju längre du sätter denna, desto längre tid tar det för distributionen att uppdateras när rutter ändras. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Distributionssätt för passagerare: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symmetriskt" innebär att ungefär samma antal passagerare färdas från station A till station B som från B till A. "asymmetriskt" innebär att en godtycklig mängd passagerare kan färdas i vardera riktningen. "manuellt" innebär att ingen automatisk distribution av passagerare sker. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Symmetriskt" innebär att ungefär samma antal passagerare färdas från station A till station B som från B till A. "Asymmetriskt" innebär att en godtycklig mängd passagerare kan färdas i vardera riktningen. "Manuellt" innebär att ingen automatisk distribution av passagerare sker. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Distributionssätt för post: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"symmetriskt" innebär att ungefär samma mängd post skickas från station A till station B som från B till A. "asymmetriskt" innebär att en godtycklig mängd post kan skickas i vardera riktningen. "manuellt" innebär att ingen automatisk distribution av post sker. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Symmetriskt" innebär att ungefär samma mängd post skickas från station A till station B som från B till A. "Asymmetriskt" innebär att en godtycklig mängd post kan skickas i vardera riktningen. "Manuellt" innebär att ingen automatisk distribution av post sker. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Distributionssätt för den BEPANSRADE godsklassen: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Den BEPANSRADE godsklassen innehåller värdesaker i det tempererade, diamanter i det subtropiska eller guld i det subarktiska klimatet. NewGRFer kan ändra detta. "symmetriskt" innebär att ungefär samma mängd av detta gods skickas från station A till station B som från B till A. "asymmetriskt" innebär att en godtycklig mängd av detta gods kan skickas i vardera riktningen. "manuellt" innebär att ingen automatisk distribution av denna godstyp sker. Det är rekommenderat att välja "asymmetriskt" eller "manuellt" vid subarktiskt klimat, då banker inte skickar tillbaka guld till guldgruvor. Vid tempererat och subtropiskt klimat kan även "symmetriskt" väljas, då banker kan skicka tillbaka värdesaker till den bank en viss last av värdesaker kom ifrån. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Den BEPANSRADE godsklassen innehåller värdesaker i det tempererade, diamanter i det subtropiska eller guld i det subarktiska klimatet. NewGRFer kan ändra detta. "Symmetriskt" innebär att ungefär samma mängd av detta gods skickas från station A till station B som från B till A. "Asymmetriskt" innebär att en godtycklig mängd av detta gods kan skickas i vardera riktningen. "Manuellt" innebär att ingen automatisk distribution av denna godstyp sker. Det är rekommenderat att välja "asymmetriskt" eller "manuellt" vid subarktiskt eller subtropiskt klimat, då banker endast tar emot gods i dessa klimat. Vid tempererat klimat kan även "symmetriskt" väljas, då banker kan skicka tillbaka värdesaker till den bank de kom ifrån. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Distributionssätt för övriga godsklasser: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asymmetriskt" innebär att en godtycklig mängd gods kan skickas i vardera riktningen. "manuellt" innebär att ingen automatisk distribution av dessa godstyper sker. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asymmetriskt" innebär att en godtycklig mängd gods kan skickas i vardera riktningen. "Manuellt" innebär att ingen automatisk distribution av dessa godstyper sker. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuellt STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asymmetriskt @@ -2037,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Vänd automatis STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Tillåt att tåg vänder vid en signal om de har väntat där länge ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Rekommenderad) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Rekommenderad) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Ändra inställningsvärde @@ -2080,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Bästa s STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Inställningar STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF-inställningar STR_INTRO_ONLINE_CONTENT :{BLACK}Kontrollera online-innehåll -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI / spelskript-inställningar +STR_INTRO_AI_SETTINGS :{BLACK}AI-inställningar +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Spelskriptinställningar STR_INTRO_QUIT :{BLACK}Avsluta STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Starta ett nytt spel. Ctrl+klick hoppar över landskapskonfigurationen @@ -2100,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Visar en STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Skärminställningar STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Visa inställningar för NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Kolla efter nytt och nyuppdaterat innehåll för nedladdning -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Visa inställningar för datorspelare och spelskript +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Visa inställningar för AI +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Visa inställningar för spelskript STR_INTRO_TOOLTIP_QUIT :{BLACK}Avsluta 'OpenTTD' STR_INTRO_BASESET :{BLACK}Det grafikpaket som för närvarande är valt som standard saknar {NUM} sprite{P "" s}. Vänligen kontrollera om det finns en uppdatering till paketet. @@ -2132,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Byt dat STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Ändra nuvarande år STR_CHEAT_SETUP_PROD :{LTBLUE}Aktivera modifiering av produktionsvärden: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Tempererat landskap -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arktiskt landskap -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropiskt landskap -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Leksakslandskap - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Färgschema @@ -2370,7 +2358,8 @@ 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_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" er} / {NUM} företag +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} klient{P "" er} - {NUM}{NUM} företag +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Antal för närvarande anslutna klienter, antal företag och maximalt antal företag som tillåts av serveradministratören # Matches ConnectionType ###length 5 @@ -2497,13 +2486,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :väntar på upp STR_NETWORK_MESSAGE_CLIENT_LEAVING :lämnar STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} har gått med i spelet -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} har gått med i spelet (Klient #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} har gått med i företag #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} har gått med i spelet (Klient #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} har gått med i företag #{2:NUM} 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_CLIENT_COMPANY_NEW :*** {0:STRING} har startat ett nytt företag (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} har lämnat spelet ({2: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_GIVE_MONEY :*** {0: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... STR_NETWORK_MESSAGE_KICKED :*** {STRING} kastades ut. Orsak: ({STRING}) @@ -2530,7 +2519,7 @@ STR_CONTENT_SEARCH_EXTERNAL :{BLACK}Sök på STR_CONTENT_SEARCH_EXTERNAL_TOOLTIP :{BLACK}Sök på webbplatser som är fristående från OpenTTD efter material som ej är tillgängligt på OpenTTD:s innehållstjänst STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER_CAPTION :{WHITE}Du lämnar nu OpenTTD! STR_CONTENT_SEARCH_EXTERNAL_DISCLAIMER :{WHITE}Villkoren för nedladdning av material från externa webbplatser varierar.{}Du hänvisas till de externa sidorna när det gäller instruktioner för hur materialet ska installeras i OpenTTD.{}Vill du fortsätta? -STR_CONTENT_FILTER_TITLE :{BLACK}Filter för Tagg/namn: +STR_CONTENT_FILTER_TITLE :{BLACK}Filter för tagg/namn: STR_CONTENT_OPEN_URL :{BLACK}Besök hemsida STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Besök hemsidan för det här innehållet STR_CONTENT_DOWNLOAD_CAPTION :{BLACK}Ladda ned @@ -2617,6 +2606,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}mättad STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}överbelastad +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} att transporteras per månad från {STATION} till {STATION} ({COMMA}% av kapacitet){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} att transporteras tillbaka ({COMMA}% av kapacitet) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Genomsnittlig restid: {NUM}{NBSP}dag{P "" ar} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Markera upptagningsområde STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Av @@ -2625,6 +2619,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Markera STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Markera stationens upptagningsområde STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Accepterar: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Tillhandahåller: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Underhållskostnad: {GOLD}{CURRENCY_SHORT}/år # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Slå ihop stationer @@ -2650,7 +2645,7 @@ STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Bygg jä STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Bygg järnvägssignaler. Ctrl växlar mellan semaforer/ljussignaler{}Dra för att bygga signaler utmed en rak sträcka räls. Ctrl bygger signal till nästa korsning{}Ctrl+klick aktiverar öppning av signalväljningsfönstret. Shift växlar mellan att bygga/visa beräknad kostnad STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Bygg järnvägsbro. Shift växlar mellan att bygga/visa beräknad kostnad STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Bygg järnvägstunnel. Shift växlar mellan att bygga/visa beräknad kostnad -STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Växla mellan att bygga/ta bort järnväg, signaler, riktmärken och stationer. Håll nere Ctrl för att även ta bort räls från waypoints och stationer +STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Växla mellan att bygga/ta bort järnväg, signaler, riktmärken och stationer. Håll nere Ctrl för att även ta bort räls från riktmärken och stationer STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Konvertera/Uppgradera spårtyp. Shift växlar mellan att bygga/visa beräknad kostnad STR_RAIL_NAME_RAILROAD :Järnväg @@ -2707,8 +2702,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Öka avs STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Välj järnvägsbro STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Välj vägbro STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Välj bro - klicka på önskad bro för att bygga den -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Hängbro, Stål STR_BRIDGE_NAME_GIRDER_STEEL :Balkbro, Stål STR_BRIDGE_NAME_CANTILEVER_STEEL :Konsolbro, Stål @@ -2809,14 +2806,14 @@ STR_STATION_BUILD_NOISE :{BLACK}Generera # Landscaping toolbar STR_LANDSCAPING_TOOLBAR :{WHITE}Landskapsplanering -STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Sänk ett hörn av marken. Vid dragning kommer hörnet och vald yta att sänkas ner till hörnets nya höjd. Ctrl väljer yta diagonalt. Shift växlar mellan att sänka/visa beräknad kostnad -STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Höj ett hörn av marken. Vid dragning kommer hörnet och vald yta att höjas upp till hörnets nya höjd. Ctrl väljer yta diagonalt. Shift växlar mellan att höja/visa beräknad kostnad +STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Sänk ett hörn av marken. Vid dragning kommer hörnet och vald yta att sänkas ner till hörnets nya höjd. Ctrl väljer ytan diagonalt. Shift växlar mellan att sänka/visa beräknad kostnad +STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Höj ett hörn av marken. Vid dragning kommer hörnet och vald yta att höjas upp till hörnets nya höjd. Ctrl väljer ytan diagonalt. Shift växlar mellan att höja/visa beräknad kostnad STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Utjämna land till höjden av det först valda hörnet. Ctrl väljer ytan diagonalt. Shift växlar mellan att utjämna/visa beräknad kostnad -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Köp mark för framtida användning. Shift växlar mellan att köpa mark/visa beräknad kostnad +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Köp mark för framtida användning. Ctrl väljer ytan diagonalt. Shift växlar mellan att köpa mark/visa beräknad kostnad # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Val av objekt -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Välj objekt att bygga. Shift växlar mellan att bygga/visa beräknad kostnad +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Välj objekt att bygga. Ctrl väljer ytan diagonalt. Shift växlar mellan att bygga/visa beräknad kostnad STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Välj typ av objekt att bygga STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Förhandsvisning av objektet STR_OBJECT_BUILD_SIZE :{BLACK}Storlek: {GOLD}{NUM} x {NUM} rutor @@ -2828,7 +2825,7 @@ STR_OBJECT_CLASS_TRNS :Sändare STR_PLANT_TREE_CAPTION :{WHITE}Träd STR_PLANT_TREE_TOOLTIP :{BLACK}Välj trädtyp att plantera. Om rutan redan har ett träd, kommer ytterliggare träd att vara av slumpmässig typ oberoende av vilken trädtyp som valts STR_TREES_RANDOM_TYPE :{BLACK}Träd av slumpvald typ -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Placera träd av slumpvald typ. Shift växlar mellan att placera träd/visa beräknad kostnad +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Placera träd av slumpvald typ. Ctrl väljer ytan diagonalt. Shift växlar mellan att placera träd/visa beräknad kostnad STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Slumpmässigt träd STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plantera träd slumpmässigt över landskapet STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2860,6 +2857,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Slumpmä STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Grunda stad på slumpmässig plats STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Många slumpmässiga städer STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Täck kartan med slumpmässigt placerade städer +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Utöka alla städer +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Gör så att alla städer växer en aning STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Stadsnamn: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Skriv in stadsnamn @@ -3138,6 +3137,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kartstor STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Ange kartans storlek i rutor. Antalet tillgängliga rutor kommer att bli något lägre STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Antal städer: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Stadsnamn: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Välj typ av stadsnamn STR_MAPGEN_DATE :{BLACK}Datum: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Antal industrier: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Högsta höjdpunkt: @@ -3151,13 +3152,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Ökentä STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Öka ökentäckning med tio procent STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Minska ökentäckning med tio procent STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Landgenerator: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terrängtyp: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Havsnivå +STR_MAPGEN_SEA_LEVEL :{BLACK}Havsnivå STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Flod: STR_MAPGEN_SMOOTHNESS :{BLACK}Jämnhet: STR_MAPGEN_VARIETY :{BLACK}Varierad distribution: STR_MAPGEN_GENERATE :{WHITE}Generera +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF-inställningar +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Visa inställningar för NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Inställningar för AI +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Visa inställningar för AI +STR_MAPGEN_GS_SETTINGS :{BLACK}Inställningar för spelskript +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Visa inställningar för spelskript + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Engelska (Original) +STR_MAPGEN_TOWN_NAME_FRENCH :Franska +STR_MAPGEN_TOWN_NAME_GERMAN :Tyska +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Engelska (Extra) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latinamerikanska +STR_MAPGEN_TOWN_NAME_SILLY :Löjliga +STR_MAPGEN_TOWN_NAME_SWEDISH :Svenska +STR_MAPGEN_TOWN_NAME_DUTCH :Hollänska +STR_MAPGEN_TOWN_NAME_FINNISH :Finska +STR_MAPGEN_TOWN_NAME_POLISH :Polska +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovakiska +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norska +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Ungerska +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Österrikiska +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rumänska +STR_MAPGEN_TOWN_NAME_CZECH :Tjeckiska +STR_MAPGEN_TOWN_NAME_SWISS :Schweiziska +STR_MAPGEN_TOWN_NAME_DANISH :Danska +STR_MAPGEN_TOWN_NAME_TURKISH :Turkiska +STR_MAPGEN_TOWN_NAME_ITALIAN :Italienska +STR_MAPGEN_TOWN_NAME_CATALAN :Katalanska # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Kartgränser: @@ -3274,7 +3303,7 @@ STR_SAVE_PRESET_SAVE :{BLACK}Spara STR_SAVE_PRESET_SAVE_TOOLTIP :{BLACK}Spara den inställda till den nuvarande valda namnet # NewGRF parameters window -STR_NEWGRF_PARAMETERS_CAPTION :{WHITE}Ändra NewGRF parametrar +STR_NEWGRF_PARAMETERS_CAPTION :{WHITE}Ändra NewGRF-parametrar STR_NEWGRF_PARAMETERS_CLOSE :{BLACK}Stäng STR_NEWGRF_PARAMETERS_RESET :{BLACK}Återställ STR_NEWGRF_PARAMETERS_RESET_TOOLTIP :{BLACK}Återställ alla parametrar till deras standardvärden @@ -3302,11 +3331,18 @@ STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK}Gå till STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Tidigare spriteobjekt STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Fortsätt till föregående normala spriteobjekt, ignorera eventuella pseudo/recolour/font spriteobjekt och börja om från slutet efter första spriteobjektet STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representation av det valda objektet. Justeringen ignoreras när objektet ritas. -STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Flytta runt objektet, ändrar X och Y offsets. Ctrl+klicka för att flyta runt objektet åtta steg i taget +STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Flytta runt objektet och ändra förskjutningen i X- och Y-led. Ctrl+klicka för att flytta runt objektet åtta steg i taget + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Förskjutningscentrerad +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite-centrerad + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Hårkors + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Återställ relativ -STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Återställ den nuvarande relativa offsetten -STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X offsett: {NUM}, Y offsett: {NUM} (Absolut) -STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}X offsett: {NUM}, Y offsett: {NUM} (Relativ) +STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Återställ den nuvarande relativa förskjutningen +STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Förskjutning X-led : {NUM}, Förskjutning Y-led: {NUM} (Absolut) +STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}Förskjutning X-led: {NUM}, Förskjutning Y-led: {NUM} (Relativ) STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Välj objekt STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Välj ett objekt på bildskärmen @@ -3317,18 +3353,18 @@ 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_POPUP :{WHITE}Ett NewGRF-fel har uppstått:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}NewGRF:en "{STRING}" har returnerat ett allvarligt fel:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF:en "{STRING}" har returnerat ett fel:{}{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} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Felaktig parameter för {1:STRING}: parameter {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} måste laddas innan {STRING}. -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} måste laddas efter {STRING}. -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} kräver OpenTTD version {STRING} eller bättre +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} är för {2:STRING}-versionen av TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} är designat för att användas med {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Felaktig parameter för {1:STRING}: parameter {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} måste laddas in innan {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} måste laddas in efter {2:STRING}. +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} kräver OpenTTD version {2:STRING} eller bättre STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF-filen den var designad att översätta STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :För många NewGRFer är laddade -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Att ladda {1:STRING} som statisk NewGRF med {STRING} kan orsaka desynkronisering +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Att ladda {1:STRING} som statisk NewGRF med {2:STRING} kan orsaka desynkronisering STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Oväntat spriteobjekt (spriteobjekt {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Okänd Action 0-egenskap {4:HEX} (spriteobjekt {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Försök att använda ett ogiltligt ID (spriteobjekt {3:NUM}) @@ -3460,14 +3496,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Köp exklusiva STR_LOCAL_AUTHORITY_ACTION_BRIBE :Muta de lokala myndigheterna ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Starta en liten lokal reklamkampanj, för att attrahera fler passagerare och mer gods till dina tranporttjänster.{}Ger en temporär boost till stationers betyg i en liten radie runt stadens centrum.{}Kostnad: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Starta en medelstor lokal reklamkampanj, för att attrahera fler passagerare och mer gods till dina tranporttjänster.{}Ger en temporär boost till stationers betyg i en medelstor radie runt stadens centrum.{}Kostnad: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Starta en stor lokal reklamkampanj, för att attrahera fler passagerare och mer gods till dina transporttjänster.{}Ger en temporär boost till stationers betyg i en stor radie runt stadens centrum.{}Kostnad: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Bekosta ombyggnad av stadens vägnätverk.{}Orsakar ansenliga störningar för vägtrafik i upp till 6 månader.{}Kostnad: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Bygg en staty i ditt företags ära.{}Ger en permanent boost till stationers betyg i staden.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Bekosta uppbyggnad av nya byggnader i staden.{}Ger en temporär boost till stadens tillväxt.{}Kostnad: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Köp 1 års exklusiva transport rättigheter i staden.{}Lokala myndigheterna kommer inte tillåta passagerare och gods att använda dina motståndares stationer.{}Cost: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW} Muta de lokala myndigheterna för att öka din värdering, med risk för att få höga böter om du blir upptäckt.{} Kostnad: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Starta en liten lokal reklamkampanj för att attrahera fler passagerare och mer gods till dina tranporttjänster.{}Ger en temporär boost till stationers betyg i en liten radie runt stadens centrum.{}{POP_COLOUR}Kostnad: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Starta en medelstor lokal reklamkampanj, för att attrahera fler passagerare och mer gods till dina tranporttjänster.{}Ger en temporär boost till stationers betyg i en medelstor radie runt stadens centrum.{}{POP_COLOUR}Kostnad: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Starta en stor lokal reklamkampanj, för att attrahera fler passagerare och mer gods till dina transporttjänster.{}Ger en temporär boost till stationers betyg i en stor radie runt stadens centrum.{}{POP_COLOUR}Kostnad: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Bekosta ombyggnad av stadens vägnätverk.{}Orsakar ansenliga störningar för vägtrafik i upp till 6 månader.{}{POP_COLOUR}Kostnad: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Bygg en staty till ditt företags ära.{}Ger en permanent boost till stationers betyg i staden.{}{POP_COLOUR}Cost: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Bekosta konstruktion av nya byggnader i staden.{}Ger en temporär boost till stadens tillväxt.{}{POP_COLOUR}Kostnad: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Köp 1 års exklusiva transporträttigheter i staden.{}De lokala myndigheterna kommer inte tillåta passagerare och gods att använda dina motståndares stationer.{}{POP_COLOUR}Kostnad: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW} Muta de lokala myndigheterna för att öka din värdering, med risk för att få höga böter om du blir upptäckt.{}{POP_COLOUR}Kostnad: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Mål @@ -3640,15 +3676,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Skepp STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Ränta på lån STR_FINANCES_SECTION_OTHER :{GOLD}Övrigt +STR_FINANCES_TOTAL_CAPTION :{WHITE}Totalt STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Nettoförtjänst +STR_FINANCES_PROFIT :{WHITE}Vinst STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Banksaldo STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Egna medel STR_FINANCES_LOAN_TITLE :{WHITE}Lån STR_FINANCES_INTEREST_RATE :{WHITE}Ränta på lån: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maxlån: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{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_REPAY_BUTTON :{BLACK}Återbetala {CURRENCY_LONG} @@ -3749,7 +3788,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Producer STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Kräver: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} väntar{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Ändra produktion (produkt av 8, upp till 2040) @@ -3779,6 +3818,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Skicka i STR_VEHICLE_LIST_REPLACE_VEHICLES :Byt ut fordon STR_VEHICLE_LIST_SEND_FOR_SERVICING :Skicka på service STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Vinst detta år: {CURRENCY_LONG} (förra året: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Skicka till depå STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Skicka till depå @@ -3870,6 +3911,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Maximal STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Räckvidd: {GOLD}{COMMA} rutor STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Flygplanstyp: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Alla typer av last +STR_CARGO_TYPE_FILTER_FREIGHT :Gods +STR_CARGO_TYPE_FILTER_NONE :Ingen + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Lista av tågvagnar. Klicka på tågvagn för information. Ctrl+klick visar eller döljer vagnstypen STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Vägfordonslista. Klicka på fordon för information. Ctrl+klick visar eller döljer fordonstypen @@ -4038,7 +4084,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :flygplan STR_ENGINE_PREVIEW_SHIP :skepp STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Kostnad: {CURRENCY_LONG} Vikt: {WEIGHT_SHORT}{}Hastighet: {VELOCITY} Kraft {POWER}{}Driftkostnad: {CURRENCY_LONG}/år{}Kapacitet: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Kostnad: {CURRENCY_LONG} Vikt: {WEIGHT_SHORT}{}Hastighet: {VELOCITY} Effekt: {POWER} Max. T.E.: {6:FORCE}{}Driftkostnad: {4:CURRENCY_LONG}/år{}Kapacitet: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Kostnad: {0:CURRENCY_LONG} Vikt: {1:WEIGHT_SHORT}{}Hastighet: {2:VELOCITY} Effekt: {3:POWER} Max. T.E.: {6:FORCE}{}Driftkostnad: {4:CURRENCY_LONG}/år{}Kapacitet: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Kostnad: {CURRENCY_LONG} Maxhastiget: {VELOCITY}{}Kapacitet: {CARGO_LONG}{}Driftkostnad: {CURRENCY_LONG}/år STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Kostnad: {CURRENCY_LONG} Maxhastighet: {VELOCITY}{}Flygplanstyp: {STRING}{}Kapacitet: {CARGO_LONG}, {CARGO_LONG}{}Driftkostnad: {CURRENCY_LONG}/år STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Kostnad: {CURRENCY_LONG} Maxhastighet: {VELOCITY}{}Flygplanstyp: {STRING}{}Kapacitet: {CARGO_LONG}{}Driftkostnad: {CURRENCY_LONG}/år @@ -4197,12 +4243,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Vikt: {L STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Vikt: {LTBLUE}{WEIGHT_SHORT} {BLACK}Kraft: {LTBLUE}{POWER}{BLACK} Maxhastiget: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Vinst detta år: {LTBLUE}{CURRENCY_LONG} (förra året: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Vinst detta år: {LTBLUE}{CURRENCY_LONG} (förra året: {CURRENCY_LONG}) {BLACK}Min. prestationsvärdering: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Tillförlitlighet: {LTBLUE}{COMMA}% {BLACK}Motorstopp sedan senaste servicen: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Byggt: {LTBLUE}{NUM}{BLACK} Värde: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Kapacitet: {LTBLUE}Ingen{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapacitet: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapacitet: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Kapacitet: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK} Överför kredit: {LTBLUE}{CURRENCY_LONG} @@ -4468,25 +4515,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Den här STR_TIMETABLE_STATUS_START_AT :{BLACK}Den här tidtabellen kommer starta {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Startdatum -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Välj ett datum som startpunkt för den här tidtabellen. Om tidtabellen är fullt tidssatt så innebär Ctrl+klick att startpunkten sätts för denna tidtabell och att startpunkten för övriga fordon som delar dessa order fördelas ut jämt baserat på deras relativa ordning +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Välj ett datum som startpunkt för den här tidtabellen. Om tidtabellen är fullt tidssatt så gör ett Ctrl+klick alla fordon som delar dessa order fördelas jämt från det givna datumet, baserat på deras relativa ordning STR_TIMETABLE_CHANGE_TIME :{BLACK}Ändra tid -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Ändra hur lång tid den markerade ordern bör ta +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Ändra hur lång tid den markerade ordern bör ta. Ctrl+klick ställer in tiden för alla ordrar STR_TIMETABLE_CLEAR_TIME :{BLACK}Rensa tid -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Rensa tiden för markerad order +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Ta bort tiden för markerad order. Ctrl+klick tar bort tiden för alla ordrar STR_TIMETABLE_CHANGE_SPEED :{BLACK}Ändra hastighetsgräns -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Ändra hastighetsgräns för markerad order +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Ändra hastighetsgräns för markerad order. Ctrl+klick ställer in hastighetsgränsen för alla ordrar STR_TIMETABLE_CLEAR_SPEED :{BLACK}Rensa hastighetsgräns -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Rensa hastighetsgräns för markerad order +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Ta bort hastighetsgräns för markerad order. Ctrl+klick tar bort hastighetsgränsen för alla ordrar STR_TIMETABLE_RESET_LATENESS :{BLACK}Rensa räknaren för sen ankomst -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Nollställ räknaren för sen ankomst så att fordonet kommer i tid +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Nollställ räknaren för sen ankomst så att fordonet kommer i tid. Ctrl+klick nollställer för hela gruppen så att det senaste fordonet kommer att vara i tid och alla andra tidiga STR_TIMETABLE_AUTOFILL :{BLACK}Fyll i automatiskt -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fyll i tidtabellen automatiskt med värden från nästa resa (Ctrl+klick för att försöka behålla väntetiderna) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fyll i tidtabellen automatiskt med värden från nästa resa. Ctrl+klicka för att försöka behålla väntetiderna STR_TIMETABLE_EXPECTED :{BLACK}Förväntat STR_TIMETABLE_SCHEDULED :{BLACK}Schemalagt @@ -4530,12 +4577,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Ett av s STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Felsökning av datorspelare / spelskript är bara tillgänglig för servern # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Konfiguration av datorspelare/spelskript +STR_AI_CONFIG_CAPTION_AI :{WHITE}Inställningar för AI +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Inställningar för spelskript STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Spelskriptet som kommer att läsas in i nästa spel STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Datorspelare som kommer att läsas in i nästa spel STR_AI_CONFIG_HUMAN_PLAYER :Mänsklig spelare STR_AI_CONFIG_RANDOM_AI :Slumpa datorspelare STR_AI_CONFIG_NONE :(inget) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Max antal motståndare: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Flytta upp STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Flytta upp vald datorspelare i listan @@ -4543,12 +4592,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Flytta n STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Flytta ner vald datorspelare i listan STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spelskript +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametrar STR_AI_CONFIG_AI :{SILVER}Datorspelare -STR_AI_CONFIG_CHANGE :{BLACK}Välj {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :Datorspelare -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Spelskript +STR_AI_CONFIG_CHANGE_AI :{BLACK}Välj datorspelare +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Välj spelskript STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Läs in ett annat skript STR_AI_CONFIG_CONFIGURE :{BLACK}Konfigurera STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Konfigurera datorspelarens parametrar @@ -4576,10 +4624,10 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Skärmdu STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Skärmdump av höjdkarta STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Skärmdump av miniatyrkartan -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} parametrar -STR_AI_SETTINGS_CAPTION_AI :Datorspelarens -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spelskriptets +# Script Parameters +STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametrar +STR_AI_SETTINGS_CAPTION_AI :Datorspelare +STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Spelskript STR_AI_SETTINGS_CLOSE :{BLACK}Stäng STR_AI_SETTINGS_RESET :{BLACK}Återställ STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4635,7 +4683,7 @@ STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Sparfilen är g STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE :Filen är inte läsbar STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE :Filen är inte skrivbar STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED :Integritetskontrollen på datan misslyckades -STR_GAME_SAVELOAD_ERROR_PATCHPACK :Sparat spel är från en modifierat version +STR_GAME_SAVELOAD_ERROR_PATCHPACK :Sparat spel är från en modifierad version STR_GAME_SAVELOAD_NOT_AVAILABLE : STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}Spelet sparades i en version som ej stöder spårvagn. Alla spårvagnar har tagits bort @@ -4657,7 +4705,7 @@ STR_WARNING_HEIGHTMAP_SCALE_CAPTION :{WHITE}Skala-va STR_WARNING_HEIGHTMAP_SCALE_MESSAGE :{YELLOW}För stora storleksändringar av källkarta är inte rekomenderat. Fortsätt med generering? # Soundset messages -STR_WARNING_FALLBACK_SOUNDSET :{WHITE}Endast ett reservdata-ljudsett hittades. Om du vill ha ljud, installera ett ljudsett via nerladdnings-systemet +STR_WARNING_FALLBACK_SOUNDSET :{WHITE}Endast ett reservdata-ljudsett hittades. Om du vill ha ljud, installera ett ljudsett via nedladdningssystemet # Screenshot related messages STR_WARNING_SCREENSHOT_SIZE_CAPTION :{WHITE}Gigantisk skärmdump @@ -4743,6 +4791,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... för STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Kan inte generera industrier... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Kan inte bygga {STRING} här... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Kan inte bygga denna typ av industri här... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Kan inte prospektera för industrin... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... för nära en annan industri STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... måste grunda stad först STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... endast en per stad @@ -4757,6 +4806,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... skog STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... kan endast byggas ovanför snögränsen STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... kan endast byggas nedanför snögränsen +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Finansieringen misslyckades att prospektera på grund av otur; försök igen +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Det fanns inga lämpliga platser för att prospektera för denna industri STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Det fanns inga lämpliga platser för '{STRING}'-industrier STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Ändra parametrarna för kartgenereringen för att skapa en bättre karta @@ -4924,6 +4975,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objekt i STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... huvudkontor i vägen STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Kan inte köpa denna mark... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... du äger den redan! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... gränsen för konstruktion av objekt är nådd # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Kan inte skapa grupp... @@ -4996,6 +5048,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Kan inte STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... fordonet är förstört +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... alla fordon är inte identiska + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Inga fordon alls kommer att vara tillgängliga STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Ändra din konfiguration av NewGRF:er STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Inga fordon är tillgängliga än @@ -5022,6 +5076,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Kan inte STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... fordonet kan inte nå alla stationer STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... fordonet kan inte komma fram till denna station STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... ett fordon som delar denna order kan inte komma till denna station +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... alla fordon har inte samma order +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... alla fordon delar inte order STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Kan inte dela orderlistan... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Kan inte sluta dela orderlistan... @@ -5029,6 +5085,20 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Kan inte STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... för långt från föregående destination STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... flygplanet har inte tillräcklig räckvidd +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_NO_RAIL_STATION :{WHITE}Det finns ingen järnvägsstation +STR_ERROR_NO_BUS_STATION :{WHITE}Det finns ingen busstation +STR_ERROR_NO_TRUCK_STATION :{WHITE}Det finns ingen lastbrygga +STR_ERROR_NO_DOCK :{WHITE}Det finns ingen hamn +STR_ERROR_NO_AIRPORT :{WHITE}Det finns ingen flygplats/helikopterflygplats +STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE :{WHITE}Det finns inga hållplatser med en kompatibel vägtyp +STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE :{WHITE}Det finns inga hållplatser med en kompatibel spårvagnstyp +STR_ERROR_NO_STOP_ARTICULATED_VEHICLE :{WHITE}Det finns inga hållplatser som passar för ledade vägfordon.{}Ledade vägfordon kräver genomfartshållplatser, inte lastbryggor +STR_ERROR_AIRPORT_NO_PLANES :{WHITE}Det här flygplanet kan inte landa på den här helikopterflygplatsen +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Den här helikoptern kan inte landa på den här flygplatsen +STR_ERROR_NO_RAIL_WAYPOINT :{WHITE}Det finns inget riktmärke +STR_ERROR_NO_BUOY :{WHITE}Det finns ingen boj + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Kan inte lägga till fordonet i en tidtabell... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Fordon kan enbart vänta vid stationer diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index 107c45efedf09..9c9e2ebcff146 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -200,6 +200,8 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}டன் STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}டன் STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}கி.கி. @@ -383,10 +385,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :வெளியேறு # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :விளையாட்டு விருப்ப பேரம் STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :அமைப்புகள் -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI / ஆட்ட அமைப்புகள் STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF அமைப்புகள் STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :ஒளி அமைப்புகள் STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :நகரத்தின் பெயர்களை காட்டு @@ -935,36 +936,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :இந்தி STR_GAME_OPTIONS_CURRENCY_IDR :இந்தோனேசிய ரூபியா (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :மலேசிய ரிங்கிட்டு (MYR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}நகர பெயர்கள் பாணியினைத் தேர்ந்தெடுக்கவும் - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :ஆங்கிலம் (இயற்கையான) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :பிரெஞ்சு -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :ஜெர்மன் -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :ஆங்கிலம் (கூடுதலான) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :இலத்தின்-அமெரிக்க -STR_GAME_OPTIONS_TOWN_NAME_SILLY :முட்டாள்தனமான -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :சுவீடிஷ் -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :டச்சு -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :பின்னிஷ் -STR_GAME_OPTIONS_TOWN_NAME_POLISH :போலிஷ் -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :சுலோவக் -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :நார்வேஜியன் -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :ஹங்கேரியன் -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :ஆஸ்திரியன் -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :ரோமேனியன் -STR_GAME_OPTIONS_TOWN_NAME_CZECH :செக் -STR_GAME_OPTIONS_TOWN_NAME_SWISS :சுவிஸ் -STR_GAME_OPTIONS_TOWN_NAME_DANISH :டேனிஷ் -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :துர்கிஷ் -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :இத்தாலியன் -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :கடலன் - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}தானாக சேமி STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}தானியங்கி விளையாட்டு சேமிப்பு இடைவெளியைத் தேர்ந்தெடுக்கவும் @@ -988,25 +959,19 @@ STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}தி STR_GAME_OPTIONS_RESOLUTION_OTHER :மற்றவை STR_GAME_OPTIONS_RESOLUTION_ITEM :{NUM}x{NUM} +STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}விளையாட்டு மறுதொடக்கம் செய்யப்பட்ட பிறகு மட்டுமே இந்த அமைப்பு நடைமுறைக்கு வரும் STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync -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_2X_ZOOM :இரண்டு மடங்கு -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :நான்கு மடங்கு -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}எழுத்துரு அளவு - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :இயல்பான -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :இரண்டு மடங்கு -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :நான்கு மடங்கு +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GRAPHICS :{BLACK}அசைவூட்டங்கள் +STR_GAME_OPTIONS_REFRESH_RATE_ITEM :{NUM}Hz STR_GAME_OPTIONS_BASE_GRF :{BLACK}அடிப்படை அசைவூட்டம் STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}பயன்படுத்தப்போகும் அடிப்படை அசைவூட்டத்தினை தேர்ந்தெடுக்கவும் @@ -1022,6 +987,7 @@ STR_GAME_OPTIONS_BASE_MUSIC_TOOLTIP :{BLACK}பய STR_GAME_OPTIONS_BASE_MUSIC_STATUS :{RED}{NUM} பிழையான கோப்பு{P "" கள்} STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP :{BLACK}அடிப்படை இசைத் தொகுப்பு பற்றிய கூடுதல் தகவல்கள் +STR_ERROR_RESOLUTION_LIST_FAILED :{WHITE}ஆதரிக்கப்பட்ட திரைத் தெளிவுத்திரங்களின் வரிசை பெற முடியவில்லை STR_ERROR_FULLSCREEN_FAILED :{WHITE}முழுத்திரை நிலை தோல்வியடைந்தது # Custom currency window @@ -1050,8 +1016,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}மு STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 பவுண்டு (£) உங்க்ள் நாணயத்தில் STR_CURRENCY_CHANGE_PARAMETER :{BLACK}பயனரால் மாற்றப்பட்ட பண குணாதிசயங்களை மாற்று -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}அதிகபட்ச போட்டியாளர்கள்: {ORANGE}{COMMA} - STR_NONE :ஒன்றுமில்லை STR_FUNDING_ONLY :நிதியளிப்பு மட்டும் STR_MINIMAL :குறைந்தபட்சம் @@ -1101,6 +1065,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :மிதமான நிலவெளி +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :வட துருவ நிலவெளி +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :மிதவெப்பமண்டல நிலவெளி +STR_CLIMATE_TOYLAND_LANDSCAPE :பொம்மை நிலவெளி + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :மிகவும் சமமான STR_TERRAIN_TYPE_FLAT :சமமான @@ -1172,6 +1142,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :வலது STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :அதிகபட்ச ஆரம்ப கடன்: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :ஒரு நிறுவனத்தால் பெறமுடியும் கடன் (பணவீக்கத்தினைக் கணக்கில் எடுத்துக் கொள்ளாமல்) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :வட்டி: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :கடன் வட்டி;செயற்படுத்தினால் பணவீக்கத்தினையும் கட்டுப்படுத்தும் @@ -1204,9 +1175,10 @@ STR_CONFIG_SETTING_TRAIN_REVERSING_HELPTEXT :இயக்க STR_CONFIG_SETTING_DISASTERS :பேரழிவுகள்: {STRING} -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} ###setting-zero-is-special STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN :{WHITE} அதிகபட்ச வரைபட உயரமாக இந்த மதிப்பை நீங்கள் தர இயலாது. வரைபடத்தில் குறைந்தது ஒரு மலையாவது இந்த மதிப்பை விட உயரமாக உள்ளது @@ -1249,10 +1221,11 @@ STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH :அதிகப STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT :கட்டப்படும் சுரங்கங்களின் அதிகபட்ச நீளம் STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD :மனித அடிப்படை தொழிற்சாலை கட்டுமான வழி: {STRING} +STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :முதன்மைத் தொழிற்சாலை நிதியம் வழி. 'ஒன்றுமில்லை' என்றால் அவற்றை நிதியளிக்க முடியாது, 'கனிமத்தேட்டம்' என்றால் நிதியளிக்க முடியும், ஆனால் நிலப்படத்தில் ஒரு சீரற்ற இடத்தில் கட்டுமானம் ஏற்படும் மற்றும் சமமாக தோல்வியடையலாம், 'மற்ற தொழிற்சாலைகளைப் போல' என்றால் நிறுவனங்களால் துணைத் தொழிற்சாலைகளை போல வேண்டிய இடத்தில் முதன்மை தொழிற்சாலைகள் கட்டமைக்கலாம் ###length 3 STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NONE :ஒன்றுமில்லை STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NORMAL :மற்ற தொழிற்சாலைகளைப் போல -STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_PROSPECTING :எங்கேயாவது +STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_PROSPECTING :கனிமத்தேட்டம் STR_CONFIG_SETTING_INDUSTRY_PLATFORM :தொழிற்சாலைகள் அருகே உள்ள சம நிலங்கள்: {STRING} STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :ஒரு தொழிலைச் சுற்றியுள்ள தட்டையான இடத்தின் அளவு. தடங்கள் மற்றும் பலவற்றைக் கட்டுவதற்கு ஒரு தொழிற்துறையைச் சுற்றி வெற்று இடம் இருப்பதை இது உறுதி செய்கிறது @@ -1299,6 +1272,7 @@ STR_CONFIG_SETTING_FREIGHT_TRAINS :பெரிய STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :ரயில்களில் சரக்குகளை கொண்டு செல்வதன் தாக்கத்தை அமைக்கவும். அதிக மதிப்பு ரயில்களுக்கு, குறிப்பாக மலைகளில் தேவைப்படும் அளவுக்கு சரக்குகளை எடுத்துச் செல்கிறது STR_CONFIG_SETTING_PLANE_SPEED :விமான வேக பெருக்கி: {STRING} +STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :விமானங்களின் போக்குவரத்து வருமானத்தின் அளவைக் குறைக்க, மற்ற வாகன வகைகளுடன் ஒப்பிடும்போது விமானங்களின் ஒப்பீட்டு வேகத்தை அமைக்கவும் STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :விமான விபத்துகளின் எண்ணிக்கை: {STRING} @@ -1315,6 +1289,7 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}வா STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :கட்டட பராமரிப்பு: {STRING} STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :துவங்கும் நிறுவனத்தின் வண்ணம்: {STRING} +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :துவங்கும் நிறுவனத்தின் வண்ணம் STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :விமான நிலையங்கள் என்றும் காலாவதியாகாது: {STRING} @@ -1396,6 +1371,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :சீரமை STR_CONFIG_SETTING_ROAD_SIDE :சாலை வாகனங்கள்: {STRING} +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :இடப்பக்கம் ஒட்டு +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :வலப்பக்கம் ஒட்டு + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :உயர்பட சுழற்ச்சி: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :வலமிருந்து இடமாக செல் @@ -1422,6 +1401,7 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :ஊதா ###length 4 STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :சாம்பல் நிறமான காட்சி +STR_CONFIG_SETTING_SCROLLMODE :பார்படத்தின் பக்கமுருட்டல் நடத்தை: {STRING} ###length 4 STR_CONFIG_SETTING_SCROLLMODE_RMB :வலது சுட்டி பொத்தானைக் கொண்டு வரைபடத்தை நகர்த்தவும் STR_CONFIG_SETTING_SCROLLMODE_LMB :இடது சுட்டி பொத்தானைக் கொண்டு வரைபடத்தை நகர்த்தவும் @@ -1456,6 +1436,7 @@ STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK :ஒரு அ ###length 3 STR_CONFIG_SETTING_USE_RELAY_SERVICE_NEVER :என்றுமில்லை STR_CONFIG_SETTING_USE_RELAY_SERVICE_ASK :கேள் +STR_CONFIG_SETTING_USE_RELAY_SERVICE_ALLOW :அனுமதி ###length 3 STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_COMMAND :Command+Click @@ -1508,6 +1489,7 @@ STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS :பயன்ப STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT :முன்னோக்கியின் வேக வரம்பு: {STRING} +STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_VAL :{NUM}% இயல்பான விலையாட்டு வேகம் ###setting-zero-is-special STR_CONFIG_SETTING_FAST_FORWARD_SPEED_LIMIT_ZERO :வரம்பு இல்லை (உங்கள் கணினி அனுமதிக்கும் அளவுக்கு வேகமாக) @@ -1571,6 +1553,7 @@ STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :பழுதுபார்த்தல்கள் இடையே உள்ள காலத்தினை சதவிகிதத்தில் காட்டவும்: {STRING} STR_CONFIG_SETTING_SERVINT_TRAINS :இரயிகளின் பழுதுபார்த்தல் இடைவேளி: {STRING} +STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT :புதிய இரயில் வாகனங்களுக்கான இயல்புநிலை சேவை இடைவெளியை அமைக்கவும், வாகனத்திற்கு வெளிப்படையான சேவை இடைவெளி எதுவும் அமைக்கப்படவில்லை என்றால் STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES :சாலை வாகனங்களின் பழுதுபார்த்தல் இடைவேளி: {STRING} STR_CONFIG_SETTING_SERVINT_AIRCRAFT :விமாங்களின் பழுதுபார்த்தல் இடைவேளி: {STRING} STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT :புதிய விமானங்களுக்கான இயல்புநிலை சேவை இடைவெளியை அமைக்கவும், வாகனத்திற்கு வெளிப்படையான சேவை இடைவெளி எதுவும் அமைக்கப்படவில்லை என்றால் @@ -1610,6 +1593,7 @@ STR_CONFIG_SETTING_NEWS_INDUSTRY_CLOSE_HELPTEXT :தொழிற STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES :பொருளாதார மாற்றங்கள்: {STRING} STR_CONFIG_SETTING_NEWS_ECONOMY_CHANGES_HELPTEXT :உலக பொருளாதார மாற்றங்களைப் பற்றி செய்தித்தாளினைக் காட்டு +STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_COMPANY_HELPTEXT :நிறுவனத்தால் வழங்கப்படும் தொழில்களின் உற்பத்தி நிலை மாறும்போது செய்தித்தாளைக் காட்டவும் STR_CONFIG_SETTING_NEWS_INDUSTRY_CHANGES_UNSERVED :மற்ற தொழிற்சாலைகளின் உற்பத்தி மாற்றங்கள்: {STRING} @@ -1666,6 +1650,7 @@ STR_CONFIG_SETTING_SIGNAL_GUI_MODE_HELPTEXT :சிக்ன ###length 2 STR_CONFIG_SETTING_TOWN_LAYOUT :புதிய நகரங்களுக்கான சாலை கட்டங்கள்: {STRING} +STR_CONFIG_SETTING_TOWN_LAYOUT_HELPTEXT :நகரங்களுக்கான சாலை தளவமைப்பு ###length 5 STR_CONFIG_SETTING_TOWN_LAYOUT_DEFAULT :அசலான STR_CONFIG_SETTING_TOWN_LAYOUT_BETTER_ROADS :நல்ல சாலைகள் @@ -1731,6 +1716,7 @@ 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 :நகரமாக மாறும் நகரங்களின் எண்ணிக்கை, இதனால் பெரியதாகத் தொடங்கி வேகமாக வளரும் நகரம் STR_CONFIG_SETTING_LARGER_TOWNS_VALUE :1 இல் {COMMA} ###setting-zero-is-special STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :ஒன்றுமில்லை @@ -1778,6 +1764,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_IMPERIAL :இம்பீ STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_METRIC :மெட்ரிக் (I) STR_CONFIG_SETTING_LOCALISATION_UNITS_VOLUME_SI :SI (மீ³) +STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE :இழு திறன் அலகுகள்: {STRING} ###length 3 STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_IMPERIAL :இம்பீரியல் (lbf) STR_CONFIG_SETTING_LOCALISATION_UNITS_FORCE_METRIC :மெட்ரிக் (kgf) @@ -1823,7 +1810,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :சிக்ன STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :இரயில்கள் நீண்ட நேரம் காத்திருந்தால், சிக்னலில் திரும்புவதற்கு அனுமதிக்கவும் ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(பரிந்துரைக்கப்பட்டது) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(பரிந்துரைக்கப்பட்டது) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}அமைப்பின் மதிப்பினை மாற்று @@ -1844,6 +1831,7 @@ STR_CONFIG_ERROR_OUT_OF_MEMORY :{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} @@ -1860,7 +1848,6 @@ STR_INTRO_HIGHSCORE :{BLACK}பு STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}அமைப்புகள் STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF அமைப்புகள் STR_INTRO_ONLINE_CONTENT :{BLACK}கோப்புகளை இணையதளத்தில் தேடு -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI / ஆட்டம் அமைப்புகள் STR_INTRO_QUIT :{BLACK}வெளியேறு STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}புதிய ஆட்டத்தினைத் தொடங்கும். Ctrl+Click அழுத்தினால் வரைபட அமைப்புவடிவாக்கம் தவிர்க்கப்படும் @@ -1878,7 +1865,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}பு STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}திரை அமைப்புகள் STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF அமைப்புகளைக் காட்டு STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}பதிவிறக்கம் செய்ய புதிய மற்றும் புதுப்பிக்கப்பட்ட உள்ளடக்கத்தை பார்க்கவும் -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}AI/வரிவடிவங்கள் அமைப்புகளைக் காட்டு STR_INTRO_TOOLTIP_QUIT :{BLACK} 'OpenTTD'ஐ விட்டு வெளியேறு STR_INTRO_TRANSLATION :{BLACK}இந்த மொழிபெயர்ப்பில் {NUM} இல்லை {P "" s}.மொழிபெயர்பாளராக பதிவு செய்து OpenTTDவிற்கு உதவவும். மேலும் விவரங்கள் அறிய readme.txt ஐ பார்க்கவும்.. @@ -1908,12 +1894,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}தே STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}நடப்பு வருடத்தை மாற்று STR_CHEAT_SETUP_PROD :{LTBLUE}தயாரிப்பு மதிப்புகளை மாற்ற முடியும்: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :மிதமான நிலவெளி -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :வட துருவ நிலவெளி -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :மிதவெப்பமண்டல நிலவெளி -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :பொம்மை நிலவெளி - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - நிற கோட்பாடு @@ -2102,18 +2082,22 @@ STR_NETWORK_COMPANY_LIST_CLIENT_LIST :இணைய STR_NETWORK_COMPANY_LIST_SPECTATE :பார்வையாளனாக பார் # Network client list +STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}இணைய வீரர்கள் 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_CONNECTION_TYPE :{BLACK}தொடர்பு வகை STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_TOOLTIP :{BLACK}உங்கள் சேவையகத்தை மற்றவர்கள் எப்படி அணுகலாம் STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}உங்கள் வீரரின் பெயர் +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}உங்கள் வீரரின் பெயரைத் திருத்தவும் STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}இந்த நிறுவனத்திற்கான நிர்வாக நடவடிக்கைகள் +STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :இந்த நிறுவனத்தில் சேரு STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}இந்த விளையாட்டாளருக்கு ஒரு செய்தியை அனுப்பவும் STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}அனைத்து பார்வையாளர்களுக்கும் ஒரு செய்தியை அனுப்பவும் STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(புதிய நிறுவனம்) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}புதிய நிறுவனத்தினை நிறுவி விளையாடு -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} வாடிக்கையாளர்{P "" கள்} / {NUM} நிறுவன{P ம் ங்கள்} +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :இது நீன்கள் +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}இது விலையாட்டின் வழங்குபவர் # Matches ConnectionType ###length 5 @@ -2222,6 +2206,7 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_NOT_ENOUGH_PLAYERS :விளைய STR_NETWORK_SERVER_MESSAGE_GAME_REASON_CONNECTING_CLIENTS :வீரர்கள் இணைக்கப்படுகின்றனர் STR_NETWORK_SERVER_MESSAGE_GAME_REASON_MANUAL :எனது STR_NETWORK_SERVER_MESSAGE_GAME_REASON_GAME_SCRIPT :விளையாட்டின் ஸ்கிரிப்ட் +STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :இணைப்பு வரைப்பட மேம்படுத்தற்காக காத்திருக்கிறது STR_NETWORK_MESSAGE_CLIENT_LEAVING :விட்டுச்செல்கிறார் STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} விளையாட்டில் சேர்ந்து உள்ளார் @@ -2329,6 +2314,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}நிரம்பிய STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}அளவிற்கு அதிகமாக ஏற்றப்பட்டுள்ளது +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}செயல்படும் பகுதியினை குறிக்கவும் STR_STATION_BUILD_COVERAGE_OFF :{BLACK}நிறுத்து @@ -2401,8 +2388,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}சி STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}இரயில்வே பாலத்தினை தேர்ந்தெடு STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}சாலைப் பாலத்தினை தேர்ந்தெடு STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}பாலம் தேர்ந்தெடுத்தல் - தேவையான பாலத்தினைக் கட்ட அதனினை சொடுக்கவும் -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :தொங்குபாலம், எஃகு STR_BRIDGE_NAME_GIRDER_STEEL :உத்திரம்பாலம் , எஃகு STR_BRIDGE_NAME_CANTILEVER_STEEL :நெடுங்கைபாலம், எஃகு @@ -2538,6 +2523,7 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}ஏத STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}ஏதொவொறு இடத்தில் நகரத்தினை நிறுவு STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}பல வெவ்வேறு நகரங்கள் STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}வரைபடத்தினை நகரங்களினால் நிறப்பு +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}எல்லா ஊர்களையும் விரிவுபடுத்து STR_FOUND_TOWN_NAME_TITLE :{YELLOW}நகரத்தின் பெயர்: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}நகரத்தின் பெயரினை இடு @@ -2728,6 +2714,7 @@ STR_FRAMERATE_MEMORYUSE :{WHITE}நி STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} நுண்ணொடி STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} மில்லி விநாடி(கள்) +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} பிரேம்கள்/வினாடி STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} வினாடிக்கு பிரேம்கள் STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} விநாடி(கள்) @@ -2750,6 +2737,7 @@ STR_FRAMETIME_CAPTION_GL_TRAINS :இரயில STR_FRAMETIME_CAPTION_GL_ROADVEHS :சாலை வாகனத்தின் பயண நேரம் STR_FRAMETIME_CAPTION_GL_AIRCRAFT :விமான டிக்குகள் STR_FRAMETIME_CAPTION_GL_LANDSCAPE :உலக சொடுக்குகள் +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :இணைப்பு வரைபட தாமதம் STR_FRAMETIME_CAPTION_DRAWING :கிராபிக்ஸ் ரெண்டரிங் STR_FRAMETIME_CAPTION_VIDEO :வீடியோ வெளியீடு STR_FRAMETIME_CAPTION_SOUND :ஒலி கலவை @@ -2778,6 +2766,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}ஆட 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_PARENT_DIRECTORY :{STRING} (தாய் கோப்புறை) @@ -2789,6 +2778,8 @@ STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}உல STR_MAPGEN_MAPSIZE :{BLACK}வரைபடத்தின் அளவு: STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}நகரங்களின் எண்ணிக்கை: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}நகரங்களின் பெயர்கள்: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}நகர பெயர்கள் பாணியினைத் தேர்ந்தெடுக்கவும் STR_MAPGEN_DATE :{BLACK}தேதி: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}தொழிற்சாலைகளின் எண்ணிக்கை: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}மிக உயர்ந்த சிகரம்: @@ -2799,14 +2790,36 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}பா STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}பாலைவன முழுத் தழுவு அளவினை பத்து சதவிகிதம் அதிகப்படுத்து STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}பாலைவன முழுத் தழுவு அளவினை பத்து சதவிகிதம் குறைக்கவும் STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}பூமி உருவாக்குனர்: STR_MAPGEN_TERRAIN_TYPE :{BLACK}நிலவகை: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}கடல் மட்டம்: +STR_MAPGEN_SEA_LEVEL :{BLACK}கடல் மட்டம்: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}ஆறுகள்: STR_MAPGEN_SMOOTHNESS :{BLACK}சமநிலை: STR_MAPGEN_VARIETY :{BLACK}பலவகை பரவல்: STR_MAPGEN_GENERATE :{WHITE}உருவாக்கு +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :ஆங்கிலம் (இயற்கையான) +STR_MAPGEN_TOWN_NAME_FRENCH :பிரெஞ்சு +STR_MAPGEN_TOWN_NAME_GERMAN :ஜெர்மன் +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :ஆங்கிலம் (கூடுதலான) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :இலத்தின்-அமெரிக்க +STR_MAPGEN_TOWN_NAME_SILLY :முட்டாள்தனமான +STR_MAPGEN_TOWN_NAME_SWEDISH :சுவீடிஷ் +STR_MAPGEN_TOWN_NAME_DUTCH :டச்சு +STR_MAPGEN_TOWN_NAME_FINNISH :பின்னிஷ் +STR_MAPGEN_TOWN_NAME_POLISH :போலிஷ் +STR_MAPGEN_TOWN_NAME_SLOVAK :சுலோவக் +STR_MAPGEN_TOWN_NAME_NORWEGIAN :நார்வேஜியன் +STR_MAPGEN_TOWN_NAME_HUNGARIAN :ஹங்கேரியன் +STR_MAPGEN_TOWN_NAME_AUSTRIAN :ஆஸ்திரியன் +STR_MAPGEN_TOWN_NAME_ROMANIAN :ரோமேனியன் +STR_MAPGEN_TOWN_NAME_CZECH :செக் +STR_MAPGEN_TOWN_NAME_SWISS :சுவிஸ் +STR_MAPGEN_TOWN_NAME_DANISH :டேனிஷ் +STR_MAPGEN_TOWN_NAME_TURKISH :துர்கிஷ் +STR_MAPGEN_TOWN_NAME_ITALIAN :இத்தாலியன் +STR_MAPGEN_TOWN_NAME_CATALAN :கடலன் + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}வரைபடத்தின் முனைகள்: STR_MAPGEN_NORTHWEST :{BLACK}வடமேற்கு @@ -2893,6 +2906,7 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}பத STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}குறைந்த். பயன்படுத்தக்கூடிய பதிப்பு: {SILVER}{NUM} STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE :{BLACK}தட்டு: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :இயல்பிருப்பு (D) STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :முதன்மை / 32 bpp STR_NEWGRF_SETTINGS_PALETTE_LEGACY :மரபுரிமை (W) STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}குணாதிசயங்கள்: {SILVER}{STRING} @@ -2933,8 +2947,13 @@ STR_SPRITE_ALIGNER_CAPTION :{WHITE}ஸ் STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}அடுத்த ஸ்பிரைட்டு STR_SPRITE_ALIGNER_GOTO_BUTTON :{BLACK}ஸ்பிரைட்டுயிற்கு செல்லவும் STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}முந்தைய ஸ்பிரைட்டு + +###length 2 + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}முன்னிருந்தமாதிரி மாற்று STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}தற்போதைய ஆஃப்செட்களை மீட்டமைக்கவும் +STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X ஒதுக்கம்: {NUM}, Y ஒதுக்கம்: {NUM} (அறுதி) STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}X ஒதுக்கம்: {NUM}, Y ஒதுக்கம்: {NUM} (சார்பு) STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}ஸ்பிரைட்டினைத் தேர்ந்தெடுக்கவும் @@ -2945,7 +2964,7 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}எச்சரிக்கை: {SILVER}{STRING} 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_VERSION_NUMBER :OpenTTDஆல் தெரிவித்த TTDPatch விருத்துடன் {1:STRING} செயல்படாது STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} ஆனது {STRING} TTD பதிப்பிற்காகவே STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} ஆனது {STRING} உடன் இணைந்து பயன்படுத்த வடிவமைக்கப்பட்டுள்ளது STR_NEWGRF_ERROR_INVALID_PARAMETER :செல்லாத குணாதிசயம் {1:STRING} இன்: குணாதிசயம் {STRING} ({NUM}) @@ -2954,6 +2973,7 @@ STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} ஆ STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} இற்கு OpenTTD பதிப்பு {STRING} இற்கு அதிகமான பதிப்பு தேவைப்படுகிறது STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF கோப்பு மொழிபெயர்க்க வடிமைக்கப்பட்டது STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :அளவிற்கு அதிகமான NewGRF கள் ஏற்றப்பட்டுள்ளன +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :{2:STRING}உடன் {1:STRING}ஐ நிலையான NewGRFஆக ஏற்றுவதால் இணைப்பு பீழை ஏற்படலாம் STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :எதிர்பார்க்கப்படாத ஸ்பிரைட்டு(ஸ்பிரைட்டு {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :தெரியாத செயல் 0 பொருள் {4:HEX} (ஸ்பிரிட் {3:NUM}) STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :பல அதிரடி 8 உள்ளீடுகளைக் கொண்டுள்ளது (ஸ்பிரிட் {3:NUM}) @@ -3230,6 +3250,7 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}கப் STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}கடன் வட்டி STR_FINANCES_SECTION_OTHER :{GOLD}மற்றவை +STR_FINANCES_TOTAL_CAPTION :{WHITE}மொத்தம் STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}வங்கி கையிருப்பு @@ -3368,6 +3389,7 @@ STR_VEHICLE_LIST_SEND_AIRCRAFT_TO_HANGAR :பணிமன STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP :{BLACK}பட்டியலில் உள்ள அனைத்து வாகனங்களையும் நிறுத்த இங்கே சொடுக்கவும் STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP :{BLACK}பட்டியலில் உள்ள அனைத்து வாகனங்களையும் இயக்க இங்கே சொடுக்கவும் +STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP :{BLACK}இந்த வகை வாகனத்திற்கான எஞ்சின் வடிவமைப்புகளின் பட்டியலைப் பார்க்கவும் STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION :{WHITE}{COMMA} வாகன{P "த்தின்" ங்களின்} பகிர்ந்த கட்டளைகள் @@ -3423,6 +3445,7 @@ STR_BUY_VEHICLE_SHIP_CAPTION :புது STR_BUY_VEHICLE_AIRCRAFT_CAPTION :புது விமானம் STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}செலவு: {GOLD}{CURRENCY_LONG}{BLACK} எடை: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK} செலவு: {GOLD}{CURRENCY_LONG}{BLACK} (சரக்கு திருத்தல் விலை: {GOLD}{CURRENCY_LONG}{BLACK}) கனம்: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}வேகம்: {GOLD}{VELOCITY}{BLACK} திறன்: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}வேகம்: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}கடலில் வேகம்: {GOLD}{VELOCITY} @@ -3445,6 +3468,9 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}அத STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}தூரம்: {GOLD}{COMMA} கட்டங்கள் STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}விமான வகை: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_FREIGHT :சரக்கு + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}இரயில் வாகனங்கள் பட்டியல் - மேலும் விவரங்களுக்கு வாகனத்தை சொடுக்கவும் STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}சாலை வாகனங்கள் பட்டியல் - மேலும் விவரங்களுக்கு வாகனத்தை சொடுக்கவும் @@ -3458,6 +3484,8 @@ STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}கப STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}விமானத்தை வாங்கு ###length VEHICLE_TYPES +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}விமானத்தை வாங்கி மாற்றியமை @@ -4040,6 +4068,7 @@ STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}AI இ STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}AI பதிவு செய்தி இடைவெளி சரத்துடன் பொருந்தும்போது உடைப்பதை இயக்கவும் / முடக்கவும் STR_AI_DEBUG_BREAK_ON_LABEL :{BLACK}உடைத்து ஆம்: STR_AI_DEBUG_BREAK_STR_OSKTITLE :{BLACK}உடைத்து ஆம் +STR_AI_DEBUG_BREAK_STR_TOOLTIP :ஒரு AI பதிவு குறிப்பும் இந்த சரமும் (உரையும்) ஒண்றாக இருக்கும் போது, ஆட்டம் இடை நிருத்தப்படும். STR_AI_DEBUG_MATCH_CASE :{BLACK}case இனை சரிபடுத்தவும் STR_AI_DEBUG_CONTINUE :{BLACK}தொடரு STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}AI இனை தொடரு @@ -4050,12 +4079,12 @@ STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}வர STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/ஆட்ட வரிவடிவம் சரிபார்த்தல் கட்டம் சர்வர்களுக்கு மட்டுமே உள்ளது # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI/வரிவடிவம் ஏற்றபடி அமை STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}வரிவடிவம் அடுத்த ஆட்டங்களிலிருந்து பதிவேற்றப்படும் STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}அடுத்த ஆட்டங்களில் பதிவேற்றப்படும் AI-கள் STR_AI_CONFIG_HUMAN_PLAYER :மனித வீரர் STR_AI_CONFIG_RANDOM_AI :ஏதொவொரு AI STR_AI_CONFIG_NONE :(none) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}அதிகபட்ச போட்டியாளர்கள்: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}மேல் நகர்த்து STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}தேரந்தெடுக்கப்பட்ட AI-இனை பட்டியலில் மேல் நகர்த்து @@ -4065,8 +4094,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}தே STR_AI_CONFIG_GAMESCRIPT :{SILVER}விளையாட்டின் ஸ்கிரிப்ட் STR_AI_CONFIG_AI :{SILVER}AIகள் -STR_AI_CONFIG_CHANGE :{BLACK}தேர்ந்தெடு {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :AI STR_AI_CONFIG_CHANGE_GAMESCRIPT :விளையாட்டின் ஸ்கிரிப்ட் STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}மற்றொறு வரிவடிவத்தினை பதிவேற்று @@ -4096,10 +4123,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}மு STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}உயர்படத்தின் திரைப்பிடிப்பு STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}சிறிய வரைபட திரைபிடிப்பு -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} குணாதிசயங்கள் +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :விளையாட்டின் ஸ்கிரிப்ட் STR_AI_SETTINGS_CLOSE :{BLACK}மூடு STR_AI_SETTINGS_RESET :{BLACK}முன்னிருந்தமாதிரி மாற்று STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4507,6 +4532,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}சர STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... வாகனம் அழிக்கப்பட்டுள்ளது + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}எந்த வாகனங்களும் தற்போது கிடையாது STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}தங்களது NewGRF அமைப்பினை மாற்றவும் STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}தற்போது எந்த வாகனங்களும் கிடையாது @@ -4540,6 +4566,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}கட STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... முந்தைய இடத்திலிருந்து நெடுந்தூரம் உள்ளது STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... விமானத்தால் அதிக தூரம் பறக்க இயலாது +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}வாகனத்தை கால அட்டவணை செய்ய இயலாது... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}வாகனங்கள் நிலையங்களில் மட்டுமே காத்திருக்க முடியும் diff --git a/src/lang/thai.txt b/src/lang/thai.txt index f050aa48c5490..bb7a3de4853f9 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -198,6 +198,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA} แร STR_UNITS_POWER_METRIC :{COMMA} แรงม้า STR_UNITS_POWER_SI :{COMMA} กิโลวัตต์ + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}ตัน STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA} ตัน STR_UNITS_WEIGHT_SHORT_SI :{COMMA} กิโลกรัม @@ -379,10 +380,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :ออก # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :ตัวเลือกเกม STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :การตั้งค่า -STR_SETTINGS_MENU_SCRIPT_SETTINGS :กำหนดค่าสคริปต์ AI/Game STR_SETTINGS_MENU_NEWGRF_SETTINGS :กำหนดค่า NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :แถบเมนูตั้งค่าวัตถุโปร่งใส STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :แสดงชื่อเมือง @@ -941,36 +941,6 @@ STR_GAME_OPTIONS_CURRENCY_IRR :Iranian Rial (I STR_GAME_OPTIONS_CURRENCY_HKD :ดอลลาร์ฮ่องกง (HKD) STR_GAME_OPTIONS_CURRENCY_MYR :ริงกิตมาเลเซีย (MYR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}เลือกรูปแบบของชื่อเมือง - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :อังกฤษ (ดั้งเดิม) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :ฝรั่งเศส -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :เยอรมัน -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :อังกฤษ (ตัวเสริม) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :ลาติน-อเมริกัน -STR_GAME_OPTIONS_TOWN_NAME_SILLY :อังกฤษอย่างง่าย -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :สวีดิช -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :ดัชต์ -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :ฟินน์ -STR_GAME_OPTIONS_TOWN_NAME_POLISH :โปลิช -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :สโลวากิช -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :นอร์วิเจียน -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :ฮังกาเรียน -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :ออสเตรียน -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :โรมาเนียน -STR_GAME_OPTIONS_TOWN_NAME_CZECH :เช็ค -STR_GAME_OPTIONS_TOWN_NAME_SWISS :สวิส -STR_GAME_OPTIONS_TOWN_NAME_DANISH :เดนมาร์ค -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :ตุรกี -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :อิตาเลียน -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :คาตาลัน - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}บันทึกเกมอัตโนมัติ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}เลือกระยะห่างระหว่างการบันทึกเกมอัตโนมัติแต่ละครั้ง @@ -995,15 +965,8 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :อื่นๆ -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}ขนาดของแผงควบคุม -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :ปกติ -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :คูณสี่ -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}ขนาดตัวอักษร - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :ปกติ -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :ขนาดใหญ่คูณสอง STR_GAME_OPTIONS_REFRESH_RATE :{BLACK}รีเฟรชเรทของหน้าจอ @@ -1051,8 +1014,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}แส STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 ปอนด์สเตอร์ลิง (£) ในสกุลเงินของคุณ STR_CURRENCY_CHANGE_PARAMETER :{BLACK}เปลี่ยนการกำหนดค่าตัวแปรสกุลเงิน -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}จำนวนผู้ร่วมแข่งขันสูงสุด: {ORANGE}{COMMA} - STR_NONE :ไม่มี STR_FUNDING_ONLY :ระดมทุนเท่านั้น STR_MINIMAL :ขั้นต่ำ @@ -1102,6 +1063,12 @@ STR_SUBSIDY_X2 :2 เท่า STR_SUBSIDY_X3 :3 เท่า STR_SUBSIDY_X4 :4 เท่า +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :ภูมิประเทศเขตอบอุ่น +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :ภูมิประเทศเขตกึ่งขั้วโลก +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :ภูมิประเทศเขตกึ่งมรสุม +STR_CLIMATE_TOYLAND_LANDSCAPE :ภูมิประเทศเมืองของเล่น + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :แบนราบมาก STR_TERRAIN_TYPE_FLAT :แบนราบ @@ -1174,6 +1141,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :ขวา STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :เงินกู้เริ่มต้นสูงสุด: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :บริษัท สามารถกู้ยืมเงินจำนวนสูงสุด (โดยไม่คำนึงถึงอัตราเงินเฟ้อเข้าบัญชี) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :ดอกเบี้ย: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :อัตราดอกเบี้ยเงินกู้; มีผลกับอัตราเงินเฟ้อถ้าเปิดใช้งาน @@ -1428,6 +1396,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :ปรังป STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :เลือกฝั่งในการขับขี่ +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :ขับชิดซ้าย +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :ขับชิดขวา + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :ทิศการหมุน Heightmap: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :ทวนเข็มนาฬิกา @@ -1916,7 +1888,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :หมุนก STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :อนุญาตให้ขบวนรถไฟกลับขบวนที่เสาอาณัติสัญญาณเมื่อมีการรอสัญญาณอนุญาตเป็นเวลานาน ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(แนะนำ) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(แนะนำ) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}เปลี่ยนค่าการตั้งค่า @@ -1958,7 +1930,6 @@ STR_INTRO_HIGHSCORE :{BLACK}ตา STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}ตั้งค่า STR_INTRO_NEWGRF_SETTINGS :{BLACK}การตั้งค่า NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}ตรวจสอบเนื้อหาออนไลน์ -STR_INTRO_SCRIPT_SETTINGS :{BLACK}ตั้งค่า AI/Game Script STR_INTRO_QUIT :{BLACK}ออก STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}เริ่มเกมใหม่, Ctrl+Click เพื่อข้ามการตั้งค่าแผนที่ @@ -1978,7 +1949,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}แส STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}การตั้งค่า หน้าจอ STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}แสดงการกำหนดค่า NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}ตรวจสอบเนื้อหาใหม่และการปรับปรุงสำหรับดาวโหลด -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}แสดงการตั้งค่า AI/Game script STR_INTRO_TOOLTIP_QUIT :{BLACK}ออกจากเกม OpenTTD STR_INTRO_TRANSLATION :{BLACK} การแปลภาษาส่วนนี้หายไป {NUM} string{P ""}. โปรดช่วยทำให้ OpenTTD ดีขึ้นโดยการสมัครเป็นผู้แปล. ดูใน readme.txt สำหรับรายละเอียด. @@ -2007,12 +1977,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}เป STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}เปลี่ยนปีปัจจุบัน STR_CHEAT_SETUP_PROD :{LTBLUE}เปิดใช้งานการแก้ไขปริมาณผลผลิต: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :ภูมิประเทศเขตอบอุ่น -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :ภูมิประเทศเขตกึ่งขั้วโลก -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :ภูมิประเทศเขตกึ่งมรสุม -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :ภูมิประเทศเมืองของเล่น - # Livery window STR_LIVERY_GENERAL_TOOLTIP :{BLACK}แสดงแบบสีทั่วไป @@ -2447,6 +2411,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}สมดุล STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}หนาแน่น +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}แสดงพื้นที่ให้บริการ STR_STATION_BUILD_COVERAGE_OFF :{BLACK}ปิด @@ -2536,8 +2502,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}เพ STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}เลือกสะพานรถไฟ STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}เลือกสะพานสำหรับรถยนต์ STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}เลือกสะพาน - คลิกสะพานที่ท่านชื่นชอบเพื่อก่อสร้าง -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :สะพานแขวนแบบคอนกรีต STR_BRIDGE_NAME_GIRDER_STEEL :สะพานนั่งร้านแบบเหล็กกล้า STR_BRIDGE_NAME_CANTILEVER_STEEL :สะพานคานแบบเหล็กกล้า @@ -2929,6 +2893,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}ขน STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}เลือกขนาดของแผนที่(ตาราง) จำนวนของตารางที่สามารถมองเห็นจะมีจำนวนน้อยกว่าเล็กน้อย STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}จำนวนเมือง +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}ชื่อเมือง: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}เลือกรูปแบบของชื่อเมือง STR_MAPGEN_DATE :{BLACK}วันที่: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}จำนวนอุตสาหกรรม: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}จุดที่พีคมากที่สุด: @@ -2936,14 +2902,36 @@ STR_MAPGEN_HEIGHTMAP_HEIGHT_UP :{BLACK}เพ STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN :{BLACK}ลดขนาดความสูงที่สุดของยอดเขาบนแผนที่ STR_MAPGEN_SNOW_COVERAGE_UP :{BLACK}เพิ่มการครอบคลุมหิมะไปถึงสิบเปอร์เซ็นต์ STR_MAPGEN_DESERT_COVERAGE :{BLACK}การปกคลุมของทะเลทราย: -STR_MAPGEN_LAND_GENERATOR :{BLACK}เครื่องมือสร้างสภาพพื้นดิน: STR_MAPGEN_TERRAIN_TYPE :{BLACK}ประเภทภูมิประเทศ: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}ระดับทะเล: +STR_MAPGEN_SEA_LEVEL :{BLACK}ระดับทะเล: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}แม่น้ำ: STR_MAPGEN_SMOOTHNESS :{BLACK}ความเรียบ: STR_MAPGEN_VARIETY :{BLACK}การกระจายความแตกต่าง: STR_MAPGEN_GENERATE :{WHITE}สร้างสภาพภูมิประเทศ +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :อังกฤษ (ดั้งเดิม) +STR_MAPGEN_TOWN_NAME_FRENCH :ฝรั่งเศส +STR_MAPGEN_TOWN_NAME_GERMAN :เยอรมัน +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :อังกฤษ (ตัวเสริม) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :ลาติน-อเมริกัน +STR_MAPGEN_TOWN_NAME_SILLY :อังกฤษอย่างง่าย +STR_MAPGEN_TOWN_NAME_SWEDISH :สวีดิช +STR_MAPGEN_TOWN_NAME_DUTCH :ดัชต์ +STR_MAPGEN_TOWN_NAME_FINNISH :ฟินน์ +STR_MAPGEN_TOWN_NAME_POLISH :โปลิช +STR_MAPGEN_TOWN_NAME_SLOVAK :สโลวากิช +STR_MAPGEN_TOWN_NAME_NORWEGIAN :นอร์วิเจียน +STR_MAPGEN_TOWN_NAME_HUNGARIAN :ฮังกาเรียน +STR_MAPGEN_TOWN_NAME_AUSTRIAN :ออสเตรียน +STR_MAPGEN_TOWN_NAME_ROMANIAN :โรมาเนียน +STR_MAPGEN_TOWN_NAME_CZECH :เช็ค +STR_MAPGEN_TOWN_NAME_SWISS :สวิส +STR_MAPGEN_TOWN_NAME_DANISH :เดนมาร์ค +STR_MAPGEN_TOWN_NAME_TURKISH :ตุรกี +STR_MAPGEN_TOWN_NAME_ITALIAN :อิตาเลียน +STR_MAPGEN_TOWN_NAME_CATALAN :คาตาลัน + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}ขอบแผนที่: STR_MAPGEN_NORTHWEST :{BLACK}ตะวันตกเฉียงเหนือ @@ -3078,6 +3066,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}sprite STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}เคลื่อนไปยัง sprite ปกติอันก่อนหน้า โดยข้าม pseudo/recolour/font และวกกลับเมื่อถึงจุดเริ่มต้น STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}แสดง sprite ที่เลือกใหม่อีกครั้ง STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}ย้าย sprite wxiv[q, แก้ไขแกน X และ Y สำหรับความคลาดเคลื่อน + +###length 2 + + STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}รีเซ็ตการตั้งค่าปัจจุบัน STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}ตำแน่ง X: {NUM}, ตำแหน่ง Y: {NUM} (แบบแน่นอน) STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}หยิบ sprite @@ -3090,8 +3082,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}อันตราย: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Error: {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}ไม่สามารถทำงานได้บน TTDPatchเวอร์ชั่นนี่ รายงานโดย OpenTTD STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} สำหรับ {STRING} version of TTD STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} ออกแบบมาสำหรับใช้งานกับ {STRING} @@ -3602,6 +3592,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}กำ STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}พิสัยทำการ: {GOLD}{COMMA} ช่อง STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}ชนิดของเครื่องบิน: {GOLD}{STRING} +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}รายการรถไฟ - คลิกที่รถไฟเพื่อดูรายละเอียด STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}รายการรถ - คลิกที่รถเพื่อดูรายละเอียด @@ -4238,12 +4230,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}ถ้ STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/Game Script Debug window จะใช้งานได้เฉพาะที่เป็น Server # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}ปรับแต่ง AI/Game Script STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Game Script จะเปิดใช้งานในเกมถัดไป STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}AI จะทำการเปิดใช้งานในเกมถัดไป STR_AI_CONFIG_HUMAN_PLAYER :ผู้เล่น STR_AI_CONFIG_RANDOM_AI :คอมพิวเตอร์ STR_AI_CONFIG_NONE :(ไม่มี) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}จำนวนผู้ร่วมแข่งขันสูงสุด: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}เลื่อนขึ้น STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}ย้าย AI ที่เลือกขึ้นด้านบนของรายชื่อ @@ -4253,8 +4245,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}ย้ STR_AI_CONFIG_GAMESCRIPT :{SILVER}Game Script STR_AI_CONFIG_AI :{SILVER}AI -STR_AI_CONFIG_CHANGE :{BLACK}เลือก {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :AI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Game Script STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}โหลดscriptอื่น @@ -4279,10 +4269,8 @@ STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}ไม STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}บันทึกหน้าจอของ Heightmap STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}จับภาพหน้าจอ มินิแมพ -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Game Script STR_AI_SETTINGS_CLOSE :{BLACK}ปิด STR_AI_SETTINGS_RESET :{BLACK}เริ่มใหม่ STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4687,6 +4675,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}ไม STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... ยานพาหนะถูกทำลาย + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}ไม่มียานพาหานะให้เลือก STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}เปลี่ยนการกำหนดค่าสำหรับ NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}ยังไม่มียานพาหานะให้เลือก @@ -4720,6 +4709,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}ไม STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... ไกลจากจุดก่อนหน้านี้มากเกินไป STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... อากาศยานมีพิสัยการบินไม่พอ +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}ไม่สามารถจัดตารางเวลาให้ยานพาหนะนี้ได้... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}พาหนะสามารถหยุดรอได้เฉพาะที่สถานี diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index c952d66141762..b50cd51c0a1df 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP} STR_UNITS_POWER_METRIC :{COMMA}{NBSP}匹 STR_UNITS_POWER_SI :{COMMA}{NBSP}千瓦 +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}匹/短噸 +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}匹/公噸 +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}匹/千公斤 +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}匹/短噸 +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}匹/公噸 +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}匹/千公斤 +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}千瓦/短噸 +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}千瓦/公噸 +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}瓦/公斤 + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}短噸 STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}噸 STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}公斤 @@ -225,9 +235,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP} STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}公尺 # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}篩選字串: -STR_LIST_FILTER_OSKTITLE :{BLACK}輸入篩選字串 -STR_LIST_FILTER_TOOLTIP :{BLACK}輸入關鍵字以篩選您想查閱或更改的選項 +STR_LIST_FILTER_TITLE :{BLACK}篩選: +STR_LIST_FILTER_OSKTITLE :{BLACK}輸入一個或多個關鍵字詞以篩選此列表 +STR_LIST_FILTER_TOOLTIP :{BLACK}輸入一個或多個關鍵字詞以篩選您想查閱或更改的選項 STR_TOOLTIP_GROUP_ORDER :{BLACK}選擇群組次序 STR_TOOLTIP_SORT_ORDER :{BLACK}選擇排序 (逆序/順序) @@ -247,7 +257,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 ###length VEHICLE_TYPES @@ -376,9 +386,9 @@ 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_PLANT_TREES :{BLACK}植樹。按 Shift 可切換種植/顯示預估的種植費用 +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}植樹。按 Ctrl 以對角線選擇區域。按 Shift 可切換種植/顯示預估的種植費用 STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}放置標誌 -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}放置物件。按 Shift 可切換興建/顯示預估的興建費用 +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}放置物件。按 Ctrl 以對角線選擇區域。按 Shift 可切換興建/顯示預估的興建費用。 # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :離開 # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :遊戲選項 STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :設定 -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI / 遊戲腳本設定 +STR_SETTINGS_MENU_AI_SETTINGS :AI 設定 +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :遊戲腳本設定 STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF 設定 STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :透明度選項 STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :顯示市鎮名稱 @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :印度盧比(IN STR_GAME_OPTIONS_CURRENCY_IDR :印尼盾 (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :馬來西亞令吉 (MYR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}選擇市鎮命名風格 - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :英國 (原版) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :法國 -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :德國 -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :英國 (增訂版) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :拉丁美洲 -STR_GAME_OPTIONS_TOWN_NAME_SILLY :荒唐名稱 -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :瑞典 -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :荷蘭 -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :芬蘭 -STR_GAME_OPTIONS_TOWN_NAME_POLISH :波蘭 -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :斯洛伐克 -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :挪威 -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :匈牙利 -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :奧地利 -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :羅馬尼亞 -STR_GAME_OPTIONS_TOWN_NAME_CZECH :捷克 -STR_GAME_OPTIONS_TOWN_NAME_SWISS :瑞士 -STR_GAME_OPTIONS_TOWN_NAME_DANISH :丹麥 -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :土耳其 -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :義大利 -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :加泰隆尼亞 - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}自動存檔 STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}選擇自動存檔頻率 @@ -1027,21 +1008,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}勾選 STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}使用中的驅動程式: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}介面大小 -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}選擇使用的介面元素大小 +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}界面大小 +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}滑動以設定界面大小。 按住 Ctrl 以調整至非整數之倍數。 +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}自動選取大小 +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}勾選此方框以自動選取界面大小 -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(自動偵測) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :正常大小 -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :兩倍大小 -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :四倍大小 +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}縮放邊框 +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}勾選此方框以令邊框隨界面大小而縮放 -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}字體大小 -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}選擇此字體大小 - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(自動偵測) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :正常 -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :兩倍大小 -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :四倍大小 +STR_GAME_OPTIONS_GUI_SCALE_1X :1倍 +STR_GAME_OPTIONS_GUI_SCALE_2X :2倍 +STR_GAME_OPTIONS_GUI_SCALE_3X :3倍 +STR_GAME_OPTIONS_GUI_SCALE_4X :4倍 +STR_GAME_OPTIONS_GUI_SCALE_5X :5倍 STR_GAME_OPTIONS_GRAPHICS :{BLACK}圖形 @@ -1093,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}預覽 STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}將10000 Pound (£)換算成你的幣值 STR_CURRENCY_CHANGE_PARAMETER :{BLACK}修改自訂幣值參數 -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}競爭對手數目上限:{ORANGE}{COMMA} - STR_NONE :無 STR_FUNDING_ONLY :只挹注資金 STR_MINIMAL :最小 @@ -1144,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :溫帶 +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :寒帶 +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :亞熱帶 +STR_CLIMATE_TOYLAND_LANDSCAPE :玩具世界 + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :非常平坦 STR_TERRAIN_TYPE_FLAT :平坦 @@ -1163,7 +1146,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}無適 # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}顯示設定 -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}篩選字串: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}篩選: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}展開所有選項 STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}折疊所有選項 STR_CONFIG_SETTING_RESET_ALL :{BLACK}重設所有數值 @@ -1223,6 +1206,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :靠右 STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :最大貸款額:{STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :公司最多可借多少錢(此設定的值排除了通貨膨脹因素)。 +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :無貸款 {RED} 需要有遊戲腳本以提供初始資金 STR_CONFIG_SETTING_INTEREST_RATE :息率:{STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :設定貸款息率。如啟用了通貨膨脹的設定,則此設定同時決定通脹率。 @@ -1449,6 +1435,8 @@ 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_SHOW_CARGO_IN_LISTS :在車輛列表中顯示車輛可運載之貨物種類 {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :如啟用此選項,車輛可運輸的負載量會於車輛列表上方顯示。 STR_CONFIG_SETTING_LANDSCAPE :場景:{STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :此設定決定基本的遊戲場景、可供運輸的貨物種類,以及城鎮發展的條件。然而,NewGRF 及遊戲腳本可提供更加細緻的設定。 @@ -1503,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :改進版 STR_CONFIG_SETTING_ROAD_SIDE :公路車輛:{STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :選擇行車方向。 +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :靠左行駛 +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :靠右行駛 + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :旋轉高度圖:{STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :逆時針 @@ -1940,7 +1932,7 @@ STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :設使有交通 STR_CONFIG_SETTING_DISTRIBUTION_MAIL :郵件分配方式:{STRING} STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :設使有交通路線連接甲、乙兩站。「對稱」指甲站往乙站的郵件數量與乙站往甲站的郵件數量大致相同。「不對稱」指任何一站往另一站的郵件數量皆由系統隨意決定。「手動」指系統不會自動分配郵件的目的地。 STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :裝甲貨物分配方式:{STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :「裝甲貨物」包括溫帶場景的「貴重物品」、寒帶場景的「金塊」及亞熱帶場景的「鑽石」。使用 NewGRF 可能會改變以上設定。{} 設使有交通路線連接甲、乙兩站。「對稱」指甲站往乙站的郵件數量與乙站往甲站的裝甲貨物數量大致相同。「不對稱」指任何一站往另一站的裝甲貨物數量皆由系統隨意決定。「手動」指系統不會自動分配裝甲貨物的目的地。{} 建議在溫帶及亞熱帶場景應使用「對稱」,因為銀行會互相發送貴重物品或鑽石;而在寒帶場景應使用「不對稱」,因為銀行不會把金塊送回礦場。 +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :「裝甲貨物」包括溫帶場景的「貴重物品」、寒帶場景的「金塊」及亞熱帶場景的「鑽石」。使用 NewGRF 可能會改變以上設定。設使有交通路線連接甲、乙兩站,則「對稱」指甲站往乙站的郵件數量與乙站往甲站的裝甲貨物數量大致相同;「不對稱」指任何一站往另一站的裝甲貨物數量皆由系統隨意決定;「手動」指系統不會自動分配裝甲貨物的目的地。建議在亞熱帶及寒帶場景中應使用「不對稱」或「手動」,因為銀行只會接收貨物。在溫帶場景中建議使用「對稱」,因為銀行之間會互相傳送貴重物品。 STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :其他貨物分配方式:{STRING} STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :如設定此值為「不對稱」,則任何一站往另一站的貨物數量皆由系統隨意決定。如設定此值為「手動」,則系統不會自動分配貨物的目的地。 ###length 3 @@ -2005,7 +1997,7 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :國際單位( STR_CONFIG_SETTING_LOCALISATION :{ORANGE}本地化 STR_CONFIG_SETTING_GRAPHICS :{ORANGE}圖形 STR_CONFIG_SETTING_SOUND :{ORANGE}音效 -STR_CONFIG_SETTING_INTERFACE :{ORANGE}介面 +STR_CONFIG_SETTING_INTERFACE :{ORANGE}界面 STR_CONFIG_SETTING_INTERFACE_GENERAL :{ORANGE}基本顯示 STR_CONFIG_SETTING_INTERFACE_VIEWPORTS :{ORANGE}顯示設定 STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION :{ORANGE}建造 @@ -2037,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :在號誌自動 STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :設定是否容許列車在號誌前等候超過一段時間後調頭。 ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(建議) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(建議) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}修改設定值 @@ -2080,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK}積分 STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}設定 STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF 設定 STR_INTRO_ONLINE_CONTENT :{BLACK}檢查線上內容 -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI / 遊戲腳本設定 +STR_INTRO_AI_SETTINGS :{BLACK}AI 設定 +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}遊戲腳本設定 STR_INTRO_QUIT :{BLACK}離開 STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}開始新遊戲。按住 Ctrl 點選可跳過地圖設定畫面 @@ -2100,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}顯示 STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}顯示設定 STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}顯示 NewGRF 設定 STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}檢查有無最新或可更新的內容可下載 -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}顯示AI和遊戲腳本設定 +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}顯示 AI 設定 +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}顯示遊戲腳本設定 STR_INTRO_TOOLTIP_QUIT :{BLACK}離開「OpenTTD」 STR_INTRO_BASESET :{BLACK}目前圖形設定缺少 {NUM}個貼圖。 請確認基礎貼圖組是否有更新。 @@ -2132,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}修改 STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}變更目前年份 STR_CHEAT_SETUP_PROD :{LTBLUE}允許修改產量:{ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :溫帶 -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :寒帶 -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :亞熱帶 -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :玩具世界 - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} 的配色 @@ -2370,7 +2358,6 @@ 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_CLIENT_COMPANY_COUNT :{BLACK}{NUM}個用戶端 / {NUM}所公司 # Matches ConnectionType ###length 5 @@ -2497,13 +2484,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :等待連結圖 STR_NETWORK_MESSAGE_CLIENT_LEAVING :離開中 STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} 已加入遊戲 -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} 已加入此遊戲 (用戶端 #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} 已加入公司 #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} 已加入此遊戲 (用戶端 #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} 已加入公司 #{2:NUM} 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_CLIENT_COMPANY_NEW :*** {0:STRING} 已建立新公司 (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} 已離開遊戲 ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} 已修改其名稱為 {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} 付給{1:STRING} {2:CURRENCY_LONG} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} 付給{1:STRING} {2:CURRENCY_LONG} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}伺服器關閉連線 STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}伺服器重新啟動中...{}請稍候... STR_NETWORK_MESSAGE_KICKED :*** {STRING} 已被踢出。原因:({STRING}) @@ -2617,6 +2604,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}飽和 STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}超載 +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}每月有 {CARGO_LONG} 正等待 從 {STATION} 運送至 {STATION} (可載量之{COMMA}%){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}回程則有{CARGO_LONG}(可載量之{COMMA}%) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}平均運輸時間:{NUM}{NBSP}日 + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}顯示運輸涵蓋範圍 STR_STATION_BUILD_COVERAGE_OFF :{BLACK}關 @@ -2625,6 +2617,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}不顯 STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}顯示設置地點的運輸涵蓋範圍 STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}接受:{GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}供應:{GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}維護成本: {GOLD}{CURRENCY_SHORT}/年 # Join station window STR_JOIN_STATION_CAPTION :{WHITE}合併車站 @@ -2707,8 +2700,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}增加 ( STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}選擇鐵路橋樑 STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}選擇道路橋樑 STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}選擇橋樑 - 點選想建的橋樑即可建造 -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :吊橋,鋼製 STR_BRIDGE_NAME_GIRDER_STEEL :桁橋,鋼製 STR_BRIDGE_NAME_CANTILEVER_STEEL :懸臂橋,鋼製 @@ -2809,14 +2804,14 @@ 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_PURCHASE_LAND :{BLACK}購買土地供將來使用。按 Shift 可切換購買/顯示預估的購買費用 +STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}下降土地上的一角。以拖曳來下降第一個選定的角落並平面化選定的區域到新角落的高度。按 Ctrl 以對角線選定區域。按 Shift 可切換建造/顯示成本估算。 +STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}上昇土地上的一角。以拖曳來上昇第一個選定的角落並平面化選定的區域到新角落的高度。按 Ctrl 以對角線選定區域。按 Shift 以切換建造/顯示成本估算。 +STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}將一片區域正平到首選高度。按 Ctrl 以對角線選擇區域。按 Shift 查看造價預算 +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}購買土地供將來使用。按 Ctrl 以對角線選擇區域。按 Shift 可切換購買/顯示預估的購買費用 # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}選擇物件 -STR_OBJECT_BUILD_TOOLTIP :{BLACK}選擇要建立的物件。按 Shift 可切換建立/顯示預估的建立費用 +STR_OBJECT_BUILD_TOOLTIP :{BLACK}選擇要建立的物件。按 Ctrl 以對角線選擇區域。按 Shift 可切換建立/顯示預估的建立費用。 STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}選擇物件的類別以進行建造 STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}預覽此物件 STR_OBJECT_BUILD_SIZE :{BLACK}大小:{GOLD}{NUM} x {NUM} 格 @@ -2828,7 +2823,7 @@ STR_OBJECT_CLASS_TRNS :天線塔 STR_PLANT_TREE_CAPTION :{WHITE}樹木 STR_PLANT_TREE_TOOLTIP :{BLACK}選擇要種植的樹種。無論您選擇了甚麼樹種,如所點擊的方格本身已經有樹,遊戲會在該方格加上一棵隨機樹種的樹 STR_TREES_RANDOM_TYPE :{BLACK}隨機種類樹木 -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}種植隨機種類樹木。按 Shift 可切換種植/顯示預估的種植費用 +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}種植隨機種類樹木。按 Ctrl 以對角線選擇區域。按 Shift 可切換種植/顯示預估的種植費用。 STR_TREES_RANDOM_TREES_BUTTON :{BLACK}隨機樹種 STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}在場景中隨機植樹 STR_TREES_MODE_NORMAL_BUTTON :{BLACK}正常 @@ -2860,6 +2855,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}隨機 STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}隨機選址建立市鎮 STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}許多隨機市鎮 STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}以隨機分佈的市鎮佈滿地圖 +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}擴展所有市鎮 +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}讓所有市鎮略為成長 STR_FOUND_TOWN_NAME_TITLE :{YELLOW}市鎮名稱: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}輸入市鎮名稱 @@ -3124,7 +3121,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}遊戲 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_FILTER_TITLE :{BLACK}篩選字串: +STR_SAVELOAD_FILTER_TITLE :{BLACK}篩選: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}覆蓋檔案 STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}你確定要覆蓋現有存檔嗎? STR_SAVELOAD_DIRECTORY :{STRING} (路徑) @@ -3138,6 +3135,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}地圖 STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}選擇地圖大小(單位為方格)。實際可供使用的方格數量會比所設定的值略低 STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}市鎮數量: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}市鎮名稱: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}選擇市鎮命名風格 STR_MAPGEN_DATE :{BLACK}日期: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}工業數量: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}最高峰: @@ -3151,13 +3150,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}沙漠 STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}將沙漠覆蓋率提高10% STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}將沙漠覆蓋率降低10% STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}地形產生器: STR_MAPGEN_TERRAIN_TYPE :{BLACK}地形種類: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}海平面: +STR_MAPGEN_SEA_LEVEL :{BLACK}海平面: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}河流: STR_MAPGEN_SMOOTHNESS :{BLACK}平滑度: STR_MAPGEN_VARIETY :{BLACK}地形起伏分佈: STR_MAPGEN_GENERATE :{WHITE}產生 +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF 設定 +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}顯示 NewGRF 設定 +STR_MAPGEN_AI_SETTINGS :{BLACK}AI 設定 +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}顯示 AI 設定 +STR_MAPGEN_GS_SETTINGS :{BLACK}遊戲腳本設定 +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}顯示遊戲腳本設定 + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :英國 (原版) +STR_MAPGEN_TOWN_NAME_FRENCH :法國 +STR_MAPGEN_TOWN_NAME_GERMAN :德國 +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :英國 (增訂版) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :拉丁美洲 +STR_MAPGEN_TOWN_NAME_SILLY :荒唐名稱 +STR_MAPGEN_TOWN_NAME_SWEDISH :瑞典 +STR_MAPGEN_TOWN_NAME_DUTCH :荷蘭 +STR_MAPGEN_TOWN_NAME_FINNISH :芬蘭 +STR_MAPGEN_TOWN_NAME_POLISH :波蘭 +STR_MAPGEN_TOWN_NAME_SLOVAK :斯洛伐克 +STR_MAPGEN_TOWN_NAME_NORWEGIAN :挪威 +STR_MAPGEN_TOWN_NAME_HUNGARIAN :匈牙利 +STR_MAPGEN_TOWN_NAME_AUSTRIAN :奧地利 +STR_MAPGEN_TOWN_NAME_ROMANIAN :羅馬尼亞 +STR_MAPGEN_TOWN_NAME_CZECH :捷克 +STR_MAPGEN_TOWN_NAME_SWISS :瑞士 +STR_MAPGEN_TOWN_NAME_DANISH :丹麥 +STR_MAPGEN_TOWN_NAME_TURKISH :土耳其 +STR_MAPGEN_TOWN_NAME_ITALIAN :義大利 +STR_MAPGEN_TOWN_NAME_CATALAN :加泰隆尼亞 # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}地圖邊緣: @@ -3216,7 +3243,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}NewGRF STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}啟用 NewGRF 檔案 STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}停用 NewGRF 檔案 STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}選擇預置值: -STR_NEWGRF_FILTER_TITLE :{ORANGE}篩選字串: +STR_NEWGRF_FILTER_TITLE :{ORANGE}篩選: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}載入所選的設定值 STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}儲存設定值 STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}儲存目前清單為設定值 @@ -3303,6 +3330,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}上一 STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}繼續處理上一個正常的子畫面,略過任何虛位/重新著色/文字字型相關的子畫面,並在到達第一個子畫面後,返回最後的子畫面繼續進行處理。 STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}顯示目前選取的 sprite。當 sprite 正在描繪時會忽略其定位 STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}移動 sprite 到指定的 X 及 Y 座標位移。Ctrl+點擊可以一次移動8個單元格。 + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}置中位移值 +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}置中貼圖 + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}十字瞄準線 + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}重設相對值 STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}重設目前的相對位移值 STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X 位移:{NUM},Y 位移:{NUM}(絕對值) @@ -3317,15 +3351,15 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}警告:{SILVER}{STRING} 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_FATAL_POPUP :{WHITE}發生嚴重 NewGRF "{STRING}" 錯誤的處理方式:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}發生NewGRF "{STRING}" 錯誤:{}{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} 一起使用 -STR_NEWGRF_ERROR_INVALID_PARAMETER :{1:STRING} 的參數無效:參數 {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} 必須在 {STRING} 之前載入 -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} 必須要在 {STRING} 之後載入 -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} 需要 OpenTTD 版本 {STRING} 或更新的版本 +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} 只適合用於 TTD 版本 {2:STRING}。 +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} 必須跟 {2:STRING} 一起使用 +STR_NEWGRF_ERROR_INVALID_PARAMETER :{1:STRING} 的參數無效:參數 {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} 必須於 {2:STRING} 之前載入。 +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} 必須於 {2:STRING} 之後載入。 +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} 需要 OpenTTD 版本 {2:STRING} 或更新的版本 STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF 檔案翻譯後出現錯誤 STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :已載入太多 NewGRF STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :在已載入 {2:STRING} 的情況下將 {1:STRING} 載入為靜態 NewGRF,可能會造成同步失敗 @@ -3460,14 +3494,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :購買專屬運 STR_LOCAL_AUTHORITY_ACTION_BRIBE :向地方政府行賄 ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}開始進行小型地方廣告活動,為您的運輸服務吸引更多乘客與貨物。{}使城鎮小範圍內的車站獲得暫時的評分增益。{}費用:{CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}開始進行中型地方廣告活動,為您的運輸服務吸引更多乘客與貨物。{}使城鎮中等範圍內的車站獲得暫時的評分增益。{}費用:{CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}開始進行大型地方廣告活動,為您的運輸服務吸引更多乘客與貨物。{}使城鎮較大範圍內的車站獲得暫時的評分增益。{}費用:{CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}出資重建市鎮內道路網。{}將對往後六個月的道路運輸造成可觀的衝擊。{}費用:{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} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}開始進行小型地方廣告活動,為您的運輸服務吸引更多乘客與貨物。{}使城鎮小範圍內的車站獲得暫時的評分增益。{} {POP_COLOUR}費用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}開始進行中型地方廣告活動,為您的運輸服務吸引更多乘客與貨物。{}使城鎮中等範圍內的車站獲得暫時的評分增益。{}{POP_COLOUR}費用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}開始進行大型地方廣告活動,為您的運輸服務吸引更多乘客與貨物。{}使城鎮較大範圍內的車站獲得暫時的評分增益。{}{POP_COLOUR}費用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}出資重建市鎮內道路網。{}將對往後六個月的道路運輸造成可觀的衝擊。{}{POP_COLOUR}費用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}建造雕像紀念您的公司。{}使城鎮範圍內的車站獲得永久的評分增益。{}{POP_COLOUR}費用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}出資協助市鎮建造新的商業建築。{}使城鎮獲得暫時性的成長速度增益。{}{POP_COLOUR}費用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}購買此市鎮一年的專屬運輸權。{}地方政府將不會讓其他公司的車站服務該市鎮的乘客和貨物。{}{POP_COLOUR}費用:{CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}冒著被抓到嚴懲的風險,向地方政府行賄以提高評價{}{POP_COLOUR}費用:{CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} 遊戲目標 @@ -3640,15 +3674,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}船舶 STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}貸款利息 STR_FINANCES_SECTION_OTHER :{GOLD}其他 +STR_FINANCES_TOTAL_CAPTION :{WHITE}總計 STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}淨收益 +STR_FINANCES_PROFIT :{WHITE}盈利 STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}銀行餘額 STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}自有資金 STR_FINANCES_LOAN_TITLE :{WHITE}貸款 STR_FINANCES_INTEREST_RATE :{WHITE}貸款利息: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}貸款上限:{BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}貸款 {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}增加貸款。 按住 Ctrl 點選可貸款最大額度 STR_FINANCES_REPAY_BUTTON :{BLACK}償還 {CURRENCY_LONG} @@ -3749,7 +3786,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}產出: 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 :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} 等待中{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}修改產量 (以 8 為倍數增減,最大為 2040) @@ -3779,6 +3816,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}向清 STR_VEHICLE_LIST_REPLACE_VEHICLES :替換車輛 STR_VEHICLE_LIST_SEND_FOR_SERVICING :送去維護 STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}今年盈利:{CURRENCY_LONG} (去年盈利:{CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :送到機廠 STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :送到車廠 @@ -3822,7 +3861,7 @@ STR_GROUP_REMOVE_ALL_VEHICLES :移去所有車 STR_GROUP_RENAME_CAPTION :{BLACK}重新命名群組 STR_GROUP_PROFIT_THIS_YEAR :今年盈利: -STR_GROUP_PROFIT_LAST_YEAR :去年盈利: +STR_GROUP_PROFIT_LAST_YEAR :去年盈利: STR_GROUP_OCCUPANCY :目前使用率: STR_GROUP_OCCUPANCY_VALUE :{NUM}% @@ -3870,6 +3909,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}最大 STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}範圍:{GOLD}{COMMA} 方格 STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}飛機類型:{GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :所有貨物種類 +STR_CARGO_TYPE_FILTER_FREIGHT :貨運 +STR_CARGO_TYPE_FILTER_NONE :無 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}列車選單。點選機車或車卡檢視詳細資訊,或者按住 Ctrl 鍵再點選機車或車卡以切換是否顯示機車或車卡的種類 STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}車輛選單。點選車輛檢視詳細資訊,或者按住 Ctrl 鍵再點選車輛以切換是否顯示車輛的種類 @@ -4038,7 +4082,7 @@ 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_MAX_TE :{BLACK}費用:{CURRENCY_LONG} 載重:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER} 最大牽引力:{6:FORCE}{}營運成本:{4:CURRENCY_LONG}/年{}容量:{5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}費用:{0:CURRENCY_LONG} 載重:{1:WEIGHT_SHORT}{}速度:{2:VELOCITY} 功率:{3: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_CAP_CAP_RUNCOST :{BLACK}費用: {CURRENCY_LONG} 最高速度: {VELOCITY}{}飛機型號: {STRING}{}容量: {CARGO_LONG}, {CARGO_LONG}{}營運成本:每年: {CURRENCY_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}費用:{CURRENCY_LONG} 最高速度:{VELOCITY}{}飛機型號:{STRING}{}容量:{CARGO_LONG}{}營運成本:每年{CURRENCY_LONG} @@ -4197,12 +4241,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}載重 STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}載重:{LTBLUE}{WEIGHT_SHORT} {BLACK}功率:{LTBLUE}{POWER}{BLACK} 最高速度:{LTBLUE}{VELOCITY} {BLACK}最大牽引力:{LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}今年盈利:{LTBLUE}{CURRENCY_LONG} (去年盈利:{CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}今年盈利:{LTBLUE}{CURRENCY_LONG} (去年盈利:{CURRENCY_LONG}) {BLACK}最差表現:{LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}可靠度:{LTBLUE}{COMMA}% {BLACK}上次維護後的故障次數:{LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}興建於:{LTBLUE}{NUM}{BLACK} 價值:{LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}容量:{LTBLUE}無{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}容量:{LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}容量:{LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}容量:{LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}容量:{LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}容量:{LTBLUE}{CARGO_LONG},{CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}轉運潛在收入:{LTBLUE}{CURRENCY_LONG} @@ -4468,25 +4513,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}此時 STR_TIMETABLE_STATUS_START_AT :{BLACK}此時刻表實施日期為 {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}實施日期 -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}選擇此時刻表開始實施的日期。如按住Ctrl鍵點選此掣,而時刻表每一項指令皆已指定持續時間,則系統會為每個共用此時刻表的車輛賦予一個開始實施時刻表的日期,使它們之間的間隔一致。 +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}選擇此時刻表開始實施的日期。如按住Ctrl鍵點選此掣,而時刻表每一項指令皆已指定持續時間,則系統會使所有共用此時刻表的車輛之間的間隔平均。 STR_TIMETABLE_CHANGE_TIME :{BLACK}修改時刻 -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}修改選取指令所需的時間 +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}修改選取指令所需的時間。按住 Ctrl 點選可設定所有指令的時間。 STR_TIMETABLE_CLEAR_TIME :{BLACK}清除時刻表 -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}清除目前選定指令所設定的時間 +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}清除目前選定指令所設定的時間。按住 Ctrl 點選可清除所有指令的時間。 STR_TIMETABLE_CHANGE_SPEED :{BLACK}修改速度限制 -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}修改選取指令所設定的最高速度 +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}修改選取指令所設定的最高速度。按住 Ctrl 點選可設定所有指令的速度。 STR_TIMETABLE_CLEAR_SPEED :{BLACK}清除速度限制 -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}清除選取指令所設定的最高速度 +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}清除選取指令所設定的最高速度。按住 Ctrl 點選可清除所有指令的速度。 STR_TIMETABLE_RESET_LATENESS :{BLACK}歸零誤點/慢分 STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}將記錄上的誤點值歸零,使該車輛被視為準點 STR_TIMETABLE_AUTOFILL :{BLACK}自動製表 -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}自動以下次運轉的時間排定時刻表 (按住 CTRL 可保持等待時間) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}自動以下次運轉的時間排定時刻表。按住 Ctrl 點選可保留等候時間。 STR_TIMETABLE_EXPECTED :{BLACK}實際時間 STR_TIMETABLE_SCHEDULED :{BLACK}表定時間 @@ -4530,12 +4575,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}正在 STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}AI/只可於伺服器打開遊戲腳本除錯視窗 # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}AI /遊戲腳本的組態 +STR_AI_CONFIG_CAPTION_AI :{WHITE}AI設定 +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}遊戲腳本設定 STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}將於下一次遊戲中載入的腳本 STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}下局開始時將啟用AI STR_AI_CONFIG_HUMAN_PLAYER :人類玩家 STR_AI_CONFIG_RANDOM_AI :隨機 AI STR_AI_CONFIG_NONE :(無) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}競爭對手數目上限:{ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}向上移 STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}向上移動所選的 AI @@ -4543,12 +4590,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}向下 STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}向下移動所選的 AI STR_AI_CONFIG_GAMESCRIPT :{SILVER}遊戲腳本 +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}參數 STR_AI_CONFIG_AI :{SILVER}AI -STR_AI_CONFIG_CHANGE :{BLACK}選擇 {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :遊戲腳本 +STR_AI_CONFIG_CHANGE_AI :{BLACK}選擇 AI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}選擇遊戲腳本 STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}載入另一腳本 STR_AI_CONFIG_CONFIGURE :{BLACK}組態設定 STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}設定腳本的參數 @@ -4576,9 +4622,9 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}截圖 STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}高度圖截圖 STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}小地圖截圖 -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} 參數 -STR_AI_SETTINGS_CAPTION_AI :AI +STR_AI_SETTINGS_CAPTION_AI :AI 參數 STR_AI_SETTINGS_CAPTION_GAMESCRIPT :遊戲腳本 STR_AI_SETTINGS_CLOSE :{BLACK}關閉 STR_AI_SETTINGS_RESET :{BLACK}重設 @@ -4743,6 +4789,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... 已 STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}無法產生工業... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}無法在此建造 {STRING} ... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}無法在此新建這種工業... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}無法勘探工業... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... 太接近另一個工業 STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... 應先建造市鎮 STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... 每個市鎮僅允許一個 @@ -4757,6 +4804,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... 森 STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... 只能在雪線以上建造 STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... 只能在雪線以下建造 +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}由於運氣差,勘探失敗,請重試 +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}無適當地點勘探此類工業。 STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}無適當地點興建「{STRING}」工業 STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}請更改參數以產生較佳的地圖 @@ -4924,6 +4973,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}被東 STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... 被公司總部擋住 STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}不能購買這塊土地... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... 您已經擁有了! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}...已達物件建造之上限 # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}無法建立群組... @@ -4996,6 +5046,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}不能 STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... 車輛已被摧毀 +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}...車輛並非全部相同 + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}沒有可用的車輛 STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}請修改您的 NewGRF 設定 STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}未有可用的車輛 @@ -5022,6 +5074,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}無法 STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}車輛無法前往所有車站 STR_ERROR_CAN_T_ADD_ORDER :{WHITE}車輛無法前往該站 STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}一部共用這個指令清單的車輛無法前往該站 +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}...車輛之指令並非全部相同 +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}...車輛並非全部使用同一共享指令 STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}無法共享指令清單... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}無法停止共享指令清單... @@ -5029,6 +5083,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}無法 STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... 與上個目的地相距太遠 STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... 飛機的飛行範圍不足 +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}無法為車輛加入時刻表... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}車輛只能在車站停靠等候 diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index b63eed6a5226f..72db25c4a6258 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -160,8 +160,8 @@ STR_ABBREV_TOFFEE :{TINY_FONT}ŞL STR_ABBREV_BATTERIES :{TINY_FONT}Pİ STR_ABBREV_PLASTIC :{TINY_FONT}PL STR_ABBREV_FIZZY_DRINKS :{TINY_FONT}İÇ -STR_ABBREV_NONE :{TINY_FONT}YOK -STR_ABBREV_ALL :{TINY_FONT}HEPSİ +STR_ABBREV_NONE :{TINY_FONT}YO +STR_ABBREV_ALL :{TINY_FONT}TÜMÜ # 'Mode' of transport for cargoes STR_PASSENGERS :{COMMA}{NBSP}yolcu @@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}bg STR_UNITS_POWER_METRIC :{COMMA}{NBSP}bg STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}bg/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}bg/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}bg/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}bg/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}bg/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -226,9 +236,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Süzgeç metni: -STR_LIST_FILTER_OSKTITLE :{BLACK}Süzgeç metnini girin -STR_LIST_FILTER_TOOLTIP :{BLACK}Listeyi filtrelemek için bir anahtar sözcük girin +STR_LIST_FILTER_TITLE :{BLACK}Filtre: +STR_LIST_FILTER_OSKTITLE :{BLACK}Listeyi filtrelemek için anahtar sözcük girin +STR_LIST_FILTER_TOOLTIP :{BLACK}Listeyi filtrelemek için anahtar sözcük girin STR_TOOLTIP_GROUP_ORDER :{BLACK}Gruplama sırasını seç STR_TOOLTIP_SORT_ORDER :{BLACK}Sıralama türünü seçin (azalan/artan) @@ -377,9 +387,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Şehir y STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Fabrika yapımı STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Yol yapımı STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK} Tramvay yapımı -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Ağaç dik. Shift ile tıklama maliyet tahminini gösterir +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Ağaç dik. Ctrl ile tıklama alanı çapraz olarak seçer. Shift ile tıklama maliyet tahminini gösterir STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Tabela koy -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Nesneyi yerleştirin. Shift ile tıklama maliyet tahminini gösterir +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Nesneyi yerleştirin. Ctrl alanı çapraz olarak seçer. Shift inşa etme/değerini gösterme arasında geçiş yapar # Scenario editor file menu ###length 7 @@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Oyundan Çık # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Seçenekler STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Ayarlar -STR_SETTINGS_MENU_SCRIPT_SETTINGS :YZ/Oyun betik ayarları +STR_SETTINGS_MENU_AI_SETTINGS :YZ ayarları +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Oyun betiği ayarları STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF ayarları STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Şeffaflık seçenekleri STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Şehir isimlerini göster @@ -966,36 +977,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Hindistan Rupis STR_GAME_OPTIONS_CURRENCY_IDR :Endonezya Rupiahı (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Malezya Ringgiti (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Soldan trafik -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Sağdan trafik - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Şehir isimleri: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Şehir isimleri için bir tür seçin - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :İngiliz (Özgün) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Fransız -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Alman -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :İngiliz (İlave) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latin-Amerikan -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Saçmasapan (İngilizce) -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :İsveç -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Hollanda -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Fin -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Leh -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovak -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norveç -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Macar -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Avusturya -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romen -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Çek -STR_GAME_OPTIONS_TOWN_NAME_SWISS :İsviçre -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danimarka -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Türk -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italyan -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalan - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Otomatik Kaydet STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Otomatik kaydetme sıklığını seçin @@ -1028,21 +1009,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Dikey se STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Geçerli sürücü: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Arayüz boyutu -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Kullanmak üzere arayüz bileşen boyutunu seçin +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Arayüz büyüklüğü +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Arayüz büyüklüğünü ayarlamak için kaydırın. Sürekli ayarlama için Ctrl tuşunu basılı tutun +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Büyüklüğü otomatik algıla +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Arayüz boyutunu otomatik ayarlamak için bu kutucuğu işaretleyin -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(otomatik-tespit) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :İki kat büyük -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Dört kat büyük +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Eğimi ayarla +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Eğimi arayüz boyutuna göre ayarlamak için bu kutucuğu işaretleyin -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Yazı boyutu -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :Arayüz boyutunu seç - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(otomatik-tespit) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Yazı iki kat büyük -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Dört kat büyük +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafikler @@ -1094,8 +1073,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Önizle STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Sterlin'in (£) para biriminizdeki karşılığı STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Özel para birimini değiştir -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}En fazla rakip: {ORANGE}{COMMA} - STR_NONE :Hiç STR_FUNDING_ONLY :Yalnızca yatırım STR_MINIMAL :En düşük @@ -1145,6 +1122,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Ilıman iklim +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Soğuk iklim +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Tropik iklim +STR_CLIMATE_TOYLAND_LANDSCAPE :Oyun bahçesi + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Dümdüz STR_TERRAIN_TYPE_FLAT :Düz @@ -1164,7 +1147,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}Uygun YZ # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Ayarlar -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Süzgeç metni: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Filtre: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Tümünü genişlet STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Tümünü kısalt STR_CONFIG_SETTING_RESET_ALL :{BLACK}Tüm değerleri sıfırla @@ -1224,6 +1207,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Sağ STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :En yüsek açılış borcu: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Bir şirketin alabileceği en fazla borç (enflasyon hesaba katılmadan) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Borç yok seçeneği, başlangıç fonunu sağlamak için oyun betiği {RED}gerektirir. STR_CONFIG_SETTING_INTEREST_RATE :Faiz oranı: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Borç faiz oranı; eğer aktifse aynı zamanda enflasyonu da belirler @@ -1450,6 +1436,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Grafiklerdeki STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :NewGRF'nin adını araç inşa penceresinde göster: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Araç inşa penceresine, seçilen aracın hangi NewGRF'den geldiğini gösteren bir satır ekleyin. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Liste menüsünde araçların taşıyabildiği kargoları göster {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Etkinleştirildiğinde, araç listesinin üstünde aracın nakliye edilebilir yükü gözükür STR_CONFIG_SETTING_LANDSCAPE :İklim: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :İklimler farklı kargo ve şehir gelişme gereksinimlerini belirleyen temel oynanış senaryolarını tanımlar. NewGRF ve Oyun Betikleri daha ince ayarlar yapmanızı sağlar @@ -1504,6 +1492,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Gelişmiş STR_CONFIG_SETTING_ROAD_SIDE :Yol araçları: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Sürüş yönünü seçin +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Soldan trafik +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Sağdan trafik + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Yükseklik haritasını döndür: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Saat yönünün tersi @@ -1937,13 +1929,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Dağıtım graf STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Bağlantı grafiğini oluşturan parçaların her tekrar hesaplaması için kullanılan zaman. Tekrar hesaplama başlatıldığında bu kadar gün sürecek bir işlem başlatılmış olur. Buraya daha kısa süreler girdikçe işlemin bitmesi gerekirken bitmemiş olma ihtimali artar. Ardından oyun ("lag") olana dek durur. Daha uzun süreler girdiğinizde güzergahlar değiştikçe dağıtımın güncellenmesi daha uzun sürer. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Yolcular için dağıtım kipi: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"simetrik" seçildiğinde A durağından B durağına taşınan ile B'den A'ya taşınan yolcu miktarı kabaca eşit olur. "asimetrik" seçildiğinde iki yönde de rastgele miktarda yolcu gönderilebilir. "el ile" seçildiğinde yolcular için otomatik dağıtım yapılmaz. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Simetrik" seçildiğinde A durağından B durağına taşınan ile B'den A'ya taşınan yolcu miktarı kabaca eşit olur. "Asimetrik" seçildiğinde iki yönde de rastgele miktarda yolcu gönderilebilir. "el ile" seçildiğinde yolcular için otomatik dağıtım yapılmaz. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Posta için dağıtım kipi: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"simetrik" seçildiğinde A durağından B durağına gönderilen ile B'den A'ya gönderilen posta miktarı kabaca eşit olur. "asimetrik" seçildiğinde iki yönde de rastgele miktarda posta gönderilebilir. "el ile" seçildiğinde posta için otomatik dağıtım yapılmaz. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Simetrik" seçildiğinde A durağından B durağına gönderilen ile B'den A'ya gönderilen posta miktarı kabaca eşit olur. "Asimetrik" seçildiğinde iki yönde de rastgele miktarda posta gönderilebilir. "El ile" seçildiğinde posta için otomatik dağıtım yapılmaz. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :ZIRHLI kargo sınıfı için dağıtım kipi: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :ZIRHLI kargo sınıfı ılıman iklimde değerli mallar, yarı-tropik iklimde elmaslar, veya yarı-soğuk iklimde altın içerir. NewGRF dosyaları bunu değiştirebilir. "Simetrik" olarak ayarlandığında A durağından B durağına gönderilen kargo miktarı, B'den A'ya gönderilene kabaca eşit olur. "Asimetrik" ise herhangi bir yönde rastgele miktarda kargo gönderilebileceğini gösterir. "El ile" seçildiğinde o kargo için otomatik dağıtım yapılmaz. Yarı-soğuk iklimde oynarken bu değeri "asimetrik" veya "el ile" olarak ayarlamanız tavsiye edilir, çünkü bankalar altınları altın madenine geri göndermez. Ilıman ve yarı-tropik iklim için aynı zamanda "simetrik" seçebilirsiniz, zira bankalar değerli malların bir kısmını malların geldiği kaynak bankaya geri gönderir. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Diğer kargo sınıfları için dağılım kipi: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"asimetrik", kargonun iki yönde de rastgele miktarda gönderileceğini gösterir. "el ile" seçildiği takdirde o kargolar için otomatik dağılım yapılmaz. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimetrik", kargonun iki yönde de rastgele miktarda gönderileceğini gösterir. "El ile" seçildiği takdirde o kargolar için otomatik dağılım yapılmaz. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :el ile (manual) STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimetrik @@ -2038,7 +2030,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :İşaretlerde o STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Tren sinyalde uzun süre beklediği takdirde ters yöne gitmesine izin ver ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Önerilen) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Önerilen) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Ayar değerini değiştir @@ -2081,7 +2073,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Puan Tab STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Ayarlar STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Ayarları STR_INTRO_ONLINE_CONTENT :{BLACK}Çevrimiçi İçeriği Kontrol Et -STR_INTRO_SCRIPT_SETTINGS :{BLACK}YZ/Oyun Betik Ayarları +STR_INTRO_AI_SETTINGS :{BLACK}YZ Ayarları +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Oyun Betiği Ayarları STR_INTRO_QUIT :{BLACK}Çıkış STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Yeni oyuna başla. Ctrl+Tıklama harita ayarlamasını atlar. @@ -2101,7 +2094,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Puan tab STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Görüntü ayarları STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF ayarlarını göster STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}İndirilecek yeni ve güncellenmiş içeriği kontrol et -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}YZ ve Oyun betik ayarlarını göster +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}YZ ayarlarını göster +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Oyun betiği ayarlarını göster STR_INTRO_TOOLTIP_QUIT :{BLACK}'OpenTTD' den çık STR_INTRO_BASESET :{BLACK}Geçerli seçimdeki temel grafik setinin {NUM} örneği eksik. Lütfen temel setin güncellemelerini kontrol edin. @@ -2114,9 +2108,9 @@ STR_QUIT_YES :{BLACK}Evet STR_QUIT_NO :{BLACK}Hayır # Abandon game -STR_ABANDON_GAME_CAPTION :{WHITE}Ana Menüye Dön -STR_ABANDON_GAME_QUERY :{YELLOW}Oyunu bitirmek istediğinize emin misiniz? -STR_ABANDON_SCENARIO_QUERY :{YELLOW}Bu senaryodan çıkmak istediğinize emin misiniz? +STR_ABANDON_GAME_CAPTION :{WHITE}Oyunu Terk Et +STR_ABANDON_GAME_QUERY :{YELLOW}Bu oyunu terk etmek istediğinize emin misiniz? +STR_ABANDON_SCENARIO_QUERY :{YELLOW}Bu senaryoyu terk etmek istediğinize emin misiniz? # Cheat window STR_CHEATS :{WHITE}Hileler @@ -2133,12 +2127,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Tarihi STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Yılı değiştir STR_CHEAT_SETUP_PROD :{LTBLUE}Üretim değerlerini değiştir: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Ilıman iklim -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Soğuk iklim -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Tropik iklim -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Oyun bahçesi - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Renk Düzeni @@ -2371,7 +2359,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Yeni şirket) STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Yeni bir şirket oluştur ve ona katıl STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Bu sensin STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Bu, oyunun ev sahibi -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} oyuncu / {NUM} şirket +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} oyuncu - {NUM}/{NUM} şirket +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Şu anda bağlı olan istemci sayısı, şirket sayısı ve sunucu sahibi tarafından izin verilen maksimum şirket sayısı # Matches ConnectionType ###length 5 @@ -2498,13 +2487,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :bağlantı graf STR_NETWORK_MESSAGE_CLIENT_LEAVING :ayrılıyor STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} oyuna katıldı -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} oyuna katıldı (İstemci #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} #{2:NUM} numaralı şirkete katıldı +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} oyuna katıldı (İstemci #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} #{2:NUM} numaralı şirkete katıldı STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} gözlemcilere katıldı -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} yeni bir şirket kurdu (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} oyunu terketti ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} yeni bir şirket kurdu (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} oyunu terketti ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} adını {STRING} olarak değiştirdi -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} {1:STRING} adlı şirkete {2:CURRENCY_LONG} verdi +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} {1:STRING} adlı şirkete {2:CURRENCY_LONG} verdi STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Sunucu kapandı STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Sunucu baştan başlatılıyor...{}Lütfen bekleyin... STR_NETWORK_MESSAGE_KICKED :*** {STRING} atıldı. Sebep: ({STRING}) @@ -2618,6 +2607,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}doygun STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}aşırı dolu +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} aylık nakledilecek {STATION} istasyonundan {STATION} istasyonuna ({COMMA}% kapasite ile){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} geri nakledilecek ({COMMA}% kapasite ile) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Ortalama seyahat süresi: {NUM}{NBSP}gün + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Kapsama alanı STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Kapalı @@ -2626,6 +2620,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Kapsama STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Kapsama alanını göster STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}İstenen: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Sağladıkları: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Bakım maliyeti: {GOLD}{CURRENCY_SHORT}/yıl # Join station window STR_JOIN_STATION_CAPTION :{WHITE}İstasyonu birleştir @@ -2708,8 +2703,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Sinyal s STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Tren Köprüsü Seç STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Köprü Seç STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Köprü seçimi - tercih ettiğiniz köprüyü yapmak için tıklayın -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Çelik, Asma STR_BRIDGE_NAME_GIRDER_STEEL :Çelik, Kirişli STR_BRIDGE_NAME_CANTILEVER_STEEL :Çelik, Ağ @@ -2792,14 +2789,14 @@ STR_STATION_BUILD_AIRPORT_CLASS_LABEL :{BLACK}Havalima STR_STATION_BUILD_AIRPORT_LAYOUT_NAME :{BLACK}Yerleşim {NUM} STR_AIRPORT_SMALL :Küçük -STR_AIRPORT_CITY :Şehirlerarası +STR_AIRPORT_CITY :Şehir STR_AIRPORT_METRO :Büyükşehir STR_AIRPORT_INTERNATIONAL :Uluslararası STR_AIRPORT_COMMUTER :Abonman STR_AIRPORT_INTERCONTINENTAL :Kıtalararası -STR_AIRPORT_HELIPORT :Heliport +STR_AIRPORT_HELIPORT :Heli pisti STR_AIRPORT_HELIDEPOT :Heligaraj -STR_AIRPORT_HELISTATION :Helistasyon +STR_AIRPORT_HELISTATION :Heli istasyonu STR_AIRPORT_CLASS_SMALL :Küçük havalimanları STR_AIRPORT_CLASS_LARGE :Büyük Havalimanları @@ -2813,11 +2810,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Arazi d STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Arazinin bir köşesini alçalt. Sürükleme ilk seçilen köşeyi alçaltır ve seçilen araziyi yeni yüksekliğe indirir. Ctrl bir alanı köşeden köşeye seçer. Shift ile tıklama maliyet tahminini gösterir STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Arazinin bir köşesini yükselt. Sürükleme ilk seçilen köşeyi yükseltir ve seçilen araziyi yeni yüksekliğe çıkarır. Ctrl bir alanı köşeden köşeye seçer. Shift ile tıklama maliyet tahminini gösterir STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Bir alanı ilk seçilen köşenin yüksekliğine düzle. Ctrl ile alanı köşeden köşeye seçer. Shift ile tıklama maliyet tahminini gösterir -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Gelecekte kullanım için arazi satın al. Shift ile tıklama maliyet tahminini gösterir +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Gelecekte kullanım için arazi satın al. Ctrl alanı çapraz olarak seçer. Shift ile tıklama maliyet tahminini gösterir # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Nesne Seçimi -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Yapılacak nesneyi seçin. Shift ile tıklama maliyet tahminini gösterir +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Yapılacak nesneyi seçin. Ctrl alanı çapraz olarak seçer. Shift ile tıklama maliyet tahminini gösterir STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}İnşa edilecek nesnenin sınıfını seçin STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Nesnenin önizlemesi STR_OBJECT_BUILD_SIZE :{BLACK}Boyut: {GOLD}{NUM} x {NUM} kare @@ -2829,7 +2826,7 @@ STR_OBJECT_CLASS_TRNS :Vericiler STR_PLANT_TREE_CAPTION :{WHITE}Ağaçlar STR_PLANT_TREE_TOOLTIP :{BLACK}Dikilecek ağaç türünü seçin. Eğer alan zaten ağaç içeriyorsa, bu seçimden bağımsız olarak karışık ağaç türleri ekleyecek. STR_TREES_RANDOM_TYPE :{BLACK}Rastgele türde ağaçlar -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Rastgele türde ağaçlar koy. Shift ile ağaç koyma/maliyet gösterme tercihi yapılır +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Rastgele türde ağaçlar koy. Ctrl ile tıklama alanı çapraz olarak seçer. Shift ile tıklama maliyet tahminini gösterir STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Rastgele Ağaç STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Haritaya rastgele ağaç dik STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal @@ -2861,6 +2858,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Rastgele STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Rastgele bir yerde şehir kur STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Birçok rastgele şehir STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Haritayı rastgele şehirlerle doldur +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Tüm şehirleri genişlet +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Tüm şehirleri birazcık büyüt STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Kasaba adı: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Kasaba adı girin @@ -3125,7 +3124,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Oyun Ayr STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Mevcut bilgi yok STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Süzgeç dizgesi: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtre: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Dosya Üzerine Yaz STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Mevcut dosyanın üzerine yazmak istediğinizden emin misiniz? STR_SAVELOAD_DIRECTORY :{STRING} (Dizin) @@ -3139,6 +3138,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Harita b STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Haritanın büyüklüğünü kare sayısına göre seçin. Kullanılabilir karelerin sayısı bir miktar az olacaktır. STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Şehir sayısı: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Şehir isimleri: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Şehir isimleri için bir tür seçin STR_MAPGEN_DATE :{BLACK}Tarih: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Fabrika sayısı: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}En yüksek tepe: @@ -3152,13 +3153,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Çöl ö STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Çöl örtüsünü yüzde on arttır STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Çöl örtüsünü yüzde on azalt STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}%{NUM} -STR_MAPGEN_LAND_GENERATOR :{BLACK}Harita üretici: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Arazi türü: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Deniz seviyesi: +STR_MAPGEN_SEA_LEVEL :{BLACK}Deniz seviyesi: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Nehirler: STR_MAPGEN_SMOOTHNESS :{BLACK}Düzlük seviyesi: STR_MAPGEN_VARIETY :{BLACK}Çeşitlilik dağılımı: STR_MAPGEN_GENERATE :{WHITE}Oluştur +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}NewGRF Ayarları +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}NewGRF ayarlarını göster +STR_MAPGEN_AI_SETTINGS :{BLACK}YZ Ayarları +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}YZ ayarlarını göster +STR_MAPGEN_GS_SETTINGS :{BLACK}Oyun Betiği Ayarları +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Oyun betiği ayarlarını göster + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :İngiliz (Özgün) +STR_MAPGEN_TOWN_NAME_FRENCH :Fransız +STR_MAPGEN_TOWN_NAME_GERMAN :Alman +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :İngiliz (İlave) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latin-Amerikan +STR_MAPGEN_TOWN_NAME_SILLY :Saçmasapan (İngilizce) +STR_MAPGEN_TOWN_NAME_SWEDISH :İsveç +STR_MAPGEN_TOWN_NAME_DUTCH :Hollanda +STR_MAPGEN_TOWN_NAME_FINNISH :Fin +STR_MAPGEN_TOWN_NAME_POLISH :Leh +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovak +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norveç +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Macar +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Avusturya +STR_MAPGEN_TOWN_NAME_ROMANIAN :Romen +STR_MAPGEN_TOWN_NAME_CZECH :Çek +STR_MAPGEN_TOWN_NAME_SWISS :İsviçre +STR_MAPGEN_TOWN_NAME_DANISH :Danimarka +STR_MAPGEN_TOWN_NAME_TURKISH :Türk +STR_MAPGEN_TOWN_NAME_ITALIAN :Italyan +STR_MAPGEN_TOWN_NAME_CATALAN :Katalan # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Harita kenarları: @@ -3217,7 +3246,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Ayrınt STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Aktif NewGRF dosyaları STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Aktif olmayan NewGRF dosyaları STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Önceden belirlenmiş ayar seçin: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Süzgeç metni: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Filtre: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Seçili önayarı yükle STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Önayarı kaydet STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Şimdiki listeyi önayar olarak kaydet @@ -3304,6 +3333,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Önceki STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Tüm sahte/yeniden renklendirme/yazı tipi nesnelerini ve baştaki sargıyı atlayarak bir önceki normal nesneye geç STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Seçili nesnenin mevcut gösterimi. Bu nesneyi çizerken hizalama ihmal edilir STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Nesneyi X ve Y ofsetlerini değiştirerek gezdir. Ctrl+Tıklama ile nesneleri bir kerede sekiz birim kaydır + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Ofset ortalandı +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Nesne ortalandı + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Artı imleci + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Bağılı sıfırla STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Geçerli bağıl ofsetleri sıfırla STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X ofseti: {NUM}, Y ofseti: {NUM} (Gerçek) @@ -3318,18 +3354,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Uyarı: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Hata: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Ölümcül hata: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Ölümcül bir NewGRF hatası oluştu:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF hatası oluştu:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}NewGRF "{STRING}" bir ölümcül hata bildirdi:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF "{STRING}" bir ölümcül hata bildirdi:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} OpenTTD tarafından belirtilen TTDPatch sürümüyle çalışmayacaktır -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING}, TTD'nin {STRING} sürümü içindir -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING}, {STRING} ile kullanılmak için tasarlanmıştır -STR_NEWGRF_ERROR_INVALID_PARAMETER :{1:STRING} için geçersiz parametre: {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} önce, {STRING} ondan sonra yüklenmeli -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} sonra, {STRING} ondan önce yüklenmeli -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} OpenTTD {STRING} veya daha yüksek bir sürüm gerektirir +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING}, TTD'nin {2:STRING} sürümü içindir +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING}, {2:STRING} ile kullanılmak için tasarlanmıştır +STR_NEWGRF_ERROR_INVALID_PARAMETER :{1:STRING} için geçersiz parametre: {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} önce, {2:STRING} ondan sonra yüklenmeli +STR_NEWGRF_ERROR_LOAD_AFTER :Önce {1:STRING}, sonra {2:STRING} yüklenmeli. +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} OpenTTD {2:STRING} veya daha yüksek bir sürüm gerektirir STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF dosyası çeviri için yapılmış STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Çok fazla NewGRF yüklendi -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :{1:STRING} adlı NewGRF'yi {STRING} ile birlikte kullanmak senkronizasyon sorunu oluşturabilir +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :{1:STRING} adlı NewGRF'yi {2:STRING} ile birlikte kullanmak senkronizasyon sorunu oluşturabilir STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Beklenmedik nesne (nesne {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Bilinmeyen Action 0 özelliği {4:HEX} (nesne {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Geçersiz ID kullanım girişimi (nesne {3:NUM}) @@ -3461,14 +3497,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Ayrıcalıklı STR_LOCAL_AUTHORITY_ACTION_BRIBE :Belediyeye rüşvet ver ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW} Müsteri çekmek için duvarlara poster yapıştır.{}Şehir merkezinin etrafında küçük bir çapta istasyon derecelendirmesinde geçici bir yükseltme sağlar.{}Fiyat: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW} Müsteri çekmek için radyoya reklam ver.{}Şehir merkezinin etrafında orta bir çapta istasyon derecelendirmesinde geçici bir yükseltme sağlar.{}Fiyat: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW} Müsteri çekmek için televizyona reklam ver.{}Şehir merkezinin etrafında büyük bir çapta istasyon derecelendirmesinde geçici bir yükseltme sağlar.{}Fiyat: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW} Yol tamirleri için belediyeye bağış yap.{}6 ay boyunca şehrin yolları kullanılamaz.{}Fiyat: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Şirket sahibinin heykelini dik.{}Şehirdeki istasyon derecelendirmesinde kalıcı bir yükseltme sağlar.{}Fiyatı: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Şehirde ticari binaların yapımı için bağış yap.{}Bu kasabanın büyümesine geçici bir yükseltme sağlar.{}Fiyatı: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW} Bir yıllık ayrıcalıklı nakliyat haklarını satın al.{} Belediye, rakip istasyonların yolcu ve kargo taşımasına izin vermez.{} Fiyat: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Yakalanma riskini göze alarak belediyeye rüşvet ver.{}Fiyat: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW} Müsteri çekmek için küçük reklam kampanyası düzenle.{}Şehir merkezinin etrafında küçük bir alanda istasyon derecelendirmesinde geçici bir yükseltme sağlar.{}{POP_COLOUR}Fiyat: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW} Müsteri çekmek için radyoya reklam ver.{}Şehir merkezinin etrafında orta bir çapta istasyon derecelendirmesinde geçici bir yükseltme sağlar.{}{POP_COLOUR}Fiyat: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW} Müsteri çekmek için televizyona reklam ver.{}Şehir merkezinin etrafında büyük bir çapta istasyon derecelendirmesinde geçici bir yükseltme sağlar.{}{POP_COLOUR}Fiyat: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW} Yol tamirleri için belediyeye bağış yap.{}6 ay boyunca şehrin yollarında önemli aksamalara sebep olur.{}{POP_COLOUR}Fiyat: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Şirket sahibinin heykelini dik.{}Şehirdeki istasyon derecelendirmesinde kalıcı bir yükseltme sağlar.{}{POP_COLOUR}Fiyatı: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Şehirde ticari binaların yapımı için bağış yap.{}Bu kasabanın büyümesine geçici bir yükseltme sağlar.{}{POP_COLOUR}Fiyatı: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW} Bir yıllık ayrıcalıklı nakliyat haklarını satın al.{} Belediye, rakip istasyonların yolcu ve kargo taşımasına izin vermez.{}{POP_COLOUR} Fiyat: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Yakalanırsan şiddetli bir ceza alma riskini göze alarak yerel yönetime bölge derecelendirmesini arttırmak için rüşvet ver.{}{POP_COLOUR}Fiyat: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Hedefler @@ -3641,15 +3677,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Gemiler STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Kredi Faizi STR_FINANCES_SECTION_OTHER :{GOLD}Diğer +STR_FINANCES_TOTAL_CAPTION :{WHITE}Toplam STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Net Kâr +STR_FINANCES_PROFIT :{WHITE}Kâr STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Banka Hesabı STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Kendi Sermayem STR_FINANCES_LOAN_TITLE :{WHITE}Kredi STR_FINANCES_INTEREST_RATE :{WHITE}Kredi Faizi: {BLACK}%{NUM} STR_FINANCES_MAX_LOAN :{WHITE}Azami Kredi: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}{CURRENCY_LONG} Kredi Al STR_FINANCES_BORROW_TOOLTIP :{BLACK}Borcu arttır. Ctrl+Tıklama alınabilen en yüksek borcu alır STR_FINANCES_REPAY_BUTTON :{BLACK}{CURRENCY_LONG} Geri Öde @@ -3750,7 +3789,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Üretile STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Gereken: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} bekliyor{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Üretimi değiştir (8'in katı, 2040'a kadar) @@ -3780,6 +3819,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Listedek STR_VEHICLE_LIST_REPLACE_VEHICLES :Araçları Değiştir STR_VEHICLE_LIST_SEND_FOR_SERVICING :Bakıma Gönder STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Bu seneki kar: {CURRENCY_LONG} (geçen sene: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Garaja Gönder STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Garaja Gönder @@ -3871,6 +3912,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Aza. Çe STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Menzil: {GOLD}{COMMA} kare STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Uçak türü: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Tüm kargo tipleri +STR_CARGO_TYPE_FILTER_FREIGHT :Nakliye +STR_CARGO_TYPE_FILTER_NONE :Hiçbiri + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Tren seçim listesi. Bilgi için araç tıklayın. Ctrl+Tıklama araç türünün gizlenmesini açar/kapatır STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Karayolu araçları seçim listesi. Bilgi için araca tıklayın. Ctrl+Tıklama araç türünün gizlenmesini açar/kapatır @@ -4039,7 +4085,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :uçak STR_ENGINE_PREVIEW_SHIP :gemi STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Fiyat: {CURRENCY_LONG} Ağırlık: {WEIGHT_SHORT}{}Hız: {VELOCITY} Güç: {POWER}{}İşletme Gideri: {CURRENCY_LONG}/yıl{}Kapasite: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Maliyet: {CURRENCY_LONG} Ağırlık: {WEIGHT_SHORT}{}Hız: {VELOCITY} Güç: {POWER} Azami Tork: {6:FORCE}{}İşletme Gideri: {4:CURRENCY_LONG}/yıl{}Kapasite: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Maliyet: {0:CURRENCY_LONG} Ağırlık: {1:WEIGHT_SHORT}{}Hız: {2:VELOCITY} Güç: {3:POWER} Azami Tork: {6:FORCE}{}İşletme Gideri: {4:CURRENCY_LONG}/yıl{}Kapasite: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Maliyet: {CURRENCY_LONG} Azami Hız: {VELOCITY}{}Kapasite: {CARGO_LONG}{}İşletme Gideri: {CURRENCY_LONG}/yıl STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Maliyet: {CURRENCY_LONG} Azami Hız: {VELOCITY}{}Uçak türü: {STRING}{}Kapasite: {CARGO_LONG}, {CARGO_LONG}{}İşletme Gideri: {CURRENCY_LONG}/yıl STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Maliyet: {CURRENCY_LONG} Azami Hız: {VELOCITY}{}Uçak türü: {STRING}{}Kapasite: {CARGO_LONG}{}İşletme Gideri: {CURRENCY_LONG}//yıl @@ -4198,12 +4244,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Ağırl STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Ağırlık: {LTBLUE}{WEIGHT_SHORT} {BLACK}Güç: {LTBLUE}{POWER}{BLACK} Azami Hız: {LTBLUE}{VELOCITY} {BLACK}Azami Tork: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Bu yılki kar: {LTBLUE}{CURRENCY_LONG} (geçen yıl: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Bu yıl kâr: {LTBLUE}{CURRENCY_LONG} (geçen sene: {CURRENCY_LONG}) {BLACK}Min. performans: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Güvenilirlik: {LTBLUE}{COMMA}% {BLACK}Son bakımdan beri bozulma sayısı: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Üretim: {LTBLUE}{NUM}{BLACK} Değer: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Kapasite: {LTBLUE}Yok{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapasite: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapasite: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Kapasite: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Kapasite: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Kapasite: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Aktarma Maliyeti: {LTBLUE}{CURRENCY_LONG} @@ -4472,22 +4519,22 @@ STR_TIMETABLE_STARTING_DATE :{BLACK}Başlang STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Bu zaman çizelgesinin başlangıcı olarak bir tarih seçin. Ctrl+Tıklama eğer komuta zaman çizelgesi uygulanmışsa bu komutu paylaşan tüm araçlara göreli komutlarını baz alarak belirtilen tarihten itibaren eşit dağıtır. STR_TIMETABLE_CHANGE_TIME :{BLACK}Zamanı değiştir -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Seçili talimatın harcaması gereken süreyi değiştir +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Seçili talimatın harcaması gereken süreyi değiştir. Ctrl+Tıklama bütün talimatların süresini değiştirir STR_TIMETABLE_CLEAR_TIME :{BLACK}Zamanı Temizle -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Seçili talimatın harcaması gereken süreyi sil +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Seçili talimatın harcaması gereken süreyi sil. Ctrl+Tıklama bütün talimatların sürelerini siler STR_TIMETABLE_CHANGE_SPEED :{BLACK}Hız Sınırını Değiştir -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Seçili emrin azami hızını değiştir +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Seçili emrin azami seyahat hızını değiştir. Ctrl+Tıklama bütün emirlerin azami hızlarını değiştirir STR_TIMETABLE_CLEAR_SPEED :{BLACK}Hız Sınırını Kaldır -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Seçili emrin azami hızını kaldır +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Seçili emrin azami seyahat hızını sil. Ctrl+Tıklama bütün emirlerin azami hızlarını siler STR_TIMETABLE_RESET_LATENESS :{BLACK}Gecikme sayacını sıfırla -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Geç kalma sayacını sıfırla, böylece araç zamanında gitmiş sayılacak +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Geç kalma sayacını sıfırla, böylece araç zamanında gitmiş sayılacak. Ctrl ile tıklamak bütün grubu sıfırlar böylece en son araç zamanında ve diğer tüm araçlar erken gelmiş sayılacak. STR_TIMETABLE_AUTOFILL :{BLACK}Otomatik doldur -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Zaman tablosunu bir sonraki yolculuktaki değerlerle otomatik doldur (Bekleme sürelerini tutmak için Ctrl ile tıklanır) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Zaman tablosunu bir sonraki yolculuktaki değerlerle otomatik doldur Bekleme sürelerini tutmak için Ctrl ile tıklanır STR_TIMETABLE_EXPECTED :{BLACK}Beklenen STR_TIMETABLE_SCHEDULED :{BLACK}Programlanan @@ -4507,14 +4554,14 @@ STR_DATE_YEAR_TOOLTIP :{BLACK}Yılı s # AI debug window -STR_AI_DEBUG :{WHITE}YZ Hata Ayıklama +STR_AI_DEBUG :{WHITE}YZ/Oyun Betiği Hata Ayıklama STR_AI_DEBUG_NAME_AND_VERSION :{BLACK}{STRING} (v{NUM}) STR_AI_DEBUG_NAME_TOOLTIP :{BLACK}Betik adı STR_AI_DEBUG_SETTINGS :{BLACK}YZ Ayarları STR_AI_DEBUG_SETTINGS_TOOLTIP :{BLACK}Betik ayarlarını değiştir STR_AI_DEBUG_RELOAD :{BLACK}YZ'yı baştan yükle STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}YZ'yı öldür, kodu tekrar yükle ve YZ'yı tekrar başlat -STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}YZ log iletisi durma metni ile eşleştiğinde duraklatmayı aç/kapa +STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}YZ kayıt iletisi durma metni ile eşleştiğinde duraklatmayı aç/kapa STR_AI_DEBUG_BREAK_ON_LABEL :{BLACK}Geldiğinde duraklatılacak metin: STR_AI_DEBUG_BREAK_STR_OSKTITLE :{BLACK}Geldiğinde duraklatılacak metin STR_AI_DEBUG_BREAK_STR_TOOLTIP :{BLACK}Bir YZ log mesajı metin ile eşleşirse, oyun duraklatılır @@ -4531,12 +4578,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Çalış STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}YZ Hata Ayıklama penceresi sadece sunucu içindir # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}YZ Yapılandırması +STR_AI_CONFIG_CAPTION_AI :{WHITE}YZ Yapılandırması +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Oyun Betiği Yapılandırması STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Bir sonraki oyunda yüklenecek Oyun Betiği STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Bir sonraki oyunda yüklenecek YZ'ler STR_AI_CONFIG_HUMAN_PLAYER :İnsan oyuncu STR_AI_CONFIG_RANDOM_AI :Rastgele YZ STR_AI_CONFIG_NONE :(hiçbiri) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}En fazla yarışmacı sayısı: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Yukarı taşı STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Seçilen YZ'yi listede yukarı taşı @@ -4544,12 +4593,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Aşağı STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Seçilen YZ'yi listede aşağı taşı STR_AI_CONFIG_GAMESCRIPT :{SILVER}Oyun Betiği +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametreler STR_AI_CONFIG_AI :{SILVER}YZ'ler -STR_AI_CONFIG_CHANGE :{BLACK}{STRING} Seç -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :YZ -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Oyun Betiği +STR_AI_CONFIG_CHANGE_AI :{BLACK}YZ Seç +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Oyun Betiği Seç STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Başka bir betik yükle STR_AI_CONFIG_CONFIGURE :{BLACK}Yapılandır STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Betik parametrelerini yapılandır @@ -4577,7 +4625,7 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Tüm har STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Yükseklik haritası ekran görüntüsü STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Küçük harita ekran görüntüsü -# AI Parameters +# Script Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametreler STR_AI_SETTINGS_CAPTION_AI :YZ STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Oyun Betiği @@ -4744,6 +4792,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... çok STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Fabrika yapılamıyor... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Buraya {STRING} yapılamaz... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Buraya bu fabrikadan yapılamaz... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Endüstri araştırılamaz... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... başka bir fabrikaya çok yakın STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... önce şehir yapılmalı STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... her şehirde yalnızca bir tane olabilir @@ -4758,6 +4807,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... orma STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... yalnız kar çizgisinin üzerinde yapılabilir STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... yalnız kar çizgisinin altında yapılabilir +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Maalesef finansman sağlanamadı, tekrar deneyin. +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Bu endüstri için uygun bir konum bulunamadı STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}'{STRING}' fabrikaları için uygun bir alan yoktu STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Daha iyi bir harita için harita oluşturma parametrelerini değiştirin @@ -4925,6 +4976,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Yolda ne STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... yolda şirket binası var STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Burası satın alınamaz... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... zaten senin! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... Nesne oluşturma sınırına ulaştınız # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Grup oluşturulamıyor... @@ -4997,6 +5049,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Servis a STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... araç imha edilmiş +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... tüm araçlar birebir aynı değil + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Hiçbir araç kullanılabilir olmayacak STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Yeni NewGRF yapılandırmanızı değiştirin STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Henüz hiçbir araç kullanılabilir değil @@ -5023,6 +5077,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Seçili STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... araç istasyonların tümüne gidemiyor STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... araç bu istasyona gidemiyor STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... bu emri paylaşan bir araç bu istasyona gidemiyor +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... tüm araçlar aynı talimatlara sahip değil +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... tüm araçlar aynı talimatları paylaşmıyor STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Talimat listesi paylasilamiyor... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Paylaşılan talimat listesini durduramazsınız... @@ -5030,6 +5086,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Talimat STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... önceki hedeften çok uzak STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... uçağın menzili yeterli değil +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Aracın zaman çizelgesi oluşturulamıyor... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Araçlar sadece istasyonlarda bekleyebilir diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index 11e3e43e41fda..06c01ba668d2d 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -325,6 +325,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}к STR_UNITS_POWER_METRIC :{COMMA}{NBSP}к.с. STR_UNITS_POWER_SI :{COMMA}{NBSP}кВт +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}к.с/т +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}к.с./т +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}к.с./Мг +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}к.с./т +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}к.с./т +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}к.с./Мг +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}кВт/т +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}кВт/т +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}Вт/кг + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}т STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}т STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}кг @@ -351,8 +361,8 @@ STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}м # Common window strings STR_LIST_FILTER_TITLE :{BLACK}Фільтр: -STR_LIST_FILTER_OSKTITLE :{BLACK}Введіть рядок фільтру -STR_LIST_FILTER_TOOLTIP :{BLACK}Введіть ключове слово для фільтраціі списку +STR_LIST_FILTER_OSKTITLE :{BLACK}Введіть одне чи більше слів для фільтрування списку +STR_LIST_FILTER_TOOLTIP :{BLACK}Введіть одне чи більше слів для фільтрування списку STR_TOOLTIP_GROUP_ORDER :{BLACK}Виберіть порядок групування STR_TOOLTIP_SORT_ORDER :{BLACK}Оберіть напрямок сортування (спадаючий/зростаючий) @@ -503,7 +513,7 @@ 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 для показу витрат на розміщення +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Встановити об'єкт. Утримуйте Ctrl для вибору діагональної ділянки. Утримуйте Shift для показу витрат на розміщення # Scenario editor file menu ###length 7 @@ -516,10 +526,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Вихід # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Налаштування гри STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Налаштування -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Налаштування AI / Ігрового скрипта +STR_SETTINGS_MENU_AI_SETTINGS :Налаштування ШІ +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Налаштування сценарію гри STR_SETTINGS_MENU_NEWGRF_SETTINGS :Налаштування NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Налаштування прозорості STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Показувати назви міст @@ -1093,36 +1104,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Індійсь STR_GAME_OPTIONS_CURRENCY_IDR :Індонезійська рупія (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Малайзійський рингіт (MYR) -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}Виберіть стиль назв міст - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Англійські (оригінальні) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Французькі -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Німецькі -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Англійські (додаткові) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Латиноамериканські -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Кумедні -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Шведські -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Нідерландські -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Фінські -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Польські -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Словацькі -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Норвезькі -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Угорські -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Австрійські -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Румунські -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Чеські -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Швейцарські -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Данські -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Турецькі -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Італійські -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Каталонські - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Автозбереження STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Виберіть період автозбереження гри @@ -1153,22 +1134,21 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Нала STR_GAME_OPTIONS_VIDEO_VSYNC :Вертикальна синхронізація STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Увімкнутий прапорець дозволить вертикальну синхронізацію екрану. Налаштування запрацює тільки після перезапуску гри. Працює тільки за увімкнутого прискорення апаратного забезпечення. +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Поточний драйвер: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Розмір інтерфейсу -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Оберіть розмір елементів інтерфейсу +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Розмір інтерфейсу +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Перетягніть повзунок для встановлення розміру інтерфейсу. Тримайте Ctrl для закріплення +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Автоматично визначений розмір +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Увімкнутий прапорець дозволить автоматично визначити розмір інтерфейсу -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(автоматичо) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Нормальний розмір -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Подвійний розмір -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Почетверний розмір +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Межі шкали +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :BLACK}Увімкнутий прапорець дозволить змінити розмір інтерфейсу -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Розмір шрифту -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Виберть розмір шрифту інтерфейсу - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(автоматичо) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Нормальний -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Подвійний розмір -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Почетверний розмір +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Графіка @@ -1220,8 +1200,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Від STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 фунтів (£) у вашій валюті STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Налаштування іншої грошової одиниці -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Кількість конкурентів: {ORANGE}{COMMA} - STR_NONE :нема STR_FUNDING_ONLY :засновувати власноруч STR_MINIMAL :мінімально @@ -1271,6 +1249,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Помірний ландшафт +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Субарктичний ландшафт +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Субтропічний ландшафт +STR_CLIMATE_TOYLAND_LANDSCAPE :Іграшковий ландшафт + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :плаский STR_TERRAIN_TYPE_FLAT :рівнинний @@ -1350,6 +1334,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :правору STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Максимальна сума позики: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Максимальна сума позики для компанії (без урахування інфляції) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Процентна ставка: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Процентна ставка за позиками; також контролює інфляцію, якщо вона увімкнена @@ -1576,6 +1561,8 @@ 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_SHOW_CARGO_IN_LISTS :Показати вантажі, які може перевозити транспорт, у віконному списку{STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :При включенні придатний вантаж для транспортних засобів показано нижче у списку транспорту STR_CONFIG_SETTING_LANDSCAPE :Ландшафт: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Ландшафти визначають базові ігрові сценарії з різними вантажами, необхідними для зростання міст. NewGRF'и й ігрові скрипти дозволяють тонший контроль @@ -1630,6 +1617,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :покраще STR_CONFIG_SETTING_ROAD_SIDE :Автотранспорт: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Виберіть сторону, по якій рухається автотранспорт +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :лівосторонній рух +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :правосторонній рух + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Поворот карти висот: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :проти годинникової стрілки @@ -1656,7 +1647,13 @@ 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_LINKGRAPH_COLOURS :Схема кольорів вантажопотоків: {STRING} +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_HELPTEXT :Встановіть схему кольорів для показу вантажних потоків. ###length 4 +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_RED :Віж зеленого до червоного (оригінальна) +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREEN_TO_BLUE :Від зеленого до синього +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREY_TO_RED :Від сірого до червоного +STR_CONFIG_SETTING_LINKGRAPH_COLOURS_GREYSCALE :Відтінки сірого STR_CONFIG_SETTING_SCROLLMODE :Переміщення вікна обзору: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Спосіб пересування ігрового поля @@ -2158,7 +2155,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Автомат STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Дозволяє поїздам розвертатися на сигналах, котрі не вдається проїхати впродовж довгого часу. ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(рекомендовано) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(рекомендовано) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Змініть значення @@ -2201,7 +2198,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Табл STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Налаштування STR_INTRO_NEWGRF_SETTINGS :{BLACK}Налаштування NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Додатковий контент -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Налаштування AI / GS +STR_INTRO_AI_SETTINGS :{BLACK}Налаштування ШІ +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Налаштування сценарію гри STR_INTRO_QUIT :{BLACK}Вихід STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Почати нову гру. Ctrl+клац мишою пропускає конфігурацію карти @@ -2221,7 +2219,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Пока STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Налаштування відображення STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Показати налаштування NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Перевірити доступний для завантаження додатковий контент -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Показати налаштування AI / Ігрового Скрипта +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Показати налаштування ШІ +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Показати налаштування сценарію гри STR_INTRO_TOOLTIP_QUIT :{BLACK}Вийти з OpenTTD STR_INTRO_BASESET :{BLACK}В обраному наборі базової графіки немає {NUM} спрайт{P а ів ів}. Будь ласка, оновіть набір графіки. @@ -2253,12 +2252,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Змі STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Змінити поточний рік STR_CHEAT_SETUP_PROD :{LTBLUE}Дозволити зміну рівня виробництва: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Помірний ландшафт -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Субарктичний ландшафт -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Субтропічний ландшафт -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Іграшковий ландшафт - # Livery window STR_LIVERY_CAPTION :{WHITE}Кольори компанії «{COMPANY}» @@ -2491,7 +2484,6 @@ 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_CLIENT_COMPANY_COUNT :{BLACK}{NUM} клієнт{P "" и ів} / {NUM} компан{P ія ії ій} # Matches ConnectionType ###length 5 @@ -2618,13 +2610,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :зачекай STR_NETWORK_MESSAGE_CLIENT_LEAVING :виходжу... STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} приєднався до гри -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :{G=m}*** {STRING} приєднався до гри (Клієнт #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} приєднався до компанії №{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :{G=m}*** {0:STRING} приєднався до гри (Клієнт #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} приєднався до компанії №{2:NUM} 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_CLIENT_COMPANY_NEW :*** {0:STRING} заснував нову компанію (№{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} покинув гру ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} змінив(-ла) ім'я на {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** Від {STRING} передано {1:STRING} {2:CURRENCY_LONG} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** Від {0:STRING} до {1:STRING} передано {2:CURRENCY_LONG} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Сервер закрив сеанс STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Перезавантаження сервера...{}Зачекайте... STR_NETWORK_MESSAGE_KICKED :*** {STRING} відключено. Причина: ({STRING}) @@ -2741,6 +2733,11 @@ STR_LINKGRAPH_LEGEND_OVERLOADED.r :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_OVERLOADED.d :{TINY_FONT}{BLACK}перевантаженому STR_LINKGRAPH_LEGEND_OVERLOADED.z :{TINY_FONT}{BLACK}перевантажений +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} треба перевезти за місяць зі {STATION} до {STATION} (місткість: {COMMA}%){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} треба повернути до (місткість: {COMMA}%) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Середній час поїздки (днів): {NUM}{NBSP} + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Підсвічення зони покриття STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Ні @@ -2749,6 +2746,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Не п STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Підсвічувати зону покриття станції STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Приймає: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Постачає: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Витрати на утримання: {GOLD}{CURRENCY_SHORT}/рік # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Об'єднати станцію @@ -2831,8 +2829,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Збіл STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Виберіть міст STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Виберіть дорожній міст STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Вибір мосту - натисніть на міст, який бажаєте збудувати -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Підвісний сталевий STR_BRIDGE_NAME_GIRDER_STEEL :Балочний сталевий STR_BRIDGE_NAME_CANTILEVER_STEEL :Каркасний сталевий @@ -2936,11 +2932,11 @@ 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_PURCHASE_LAND :{BLACK}Купити ділянку для використання у майбутньому. Утримуйте Shift для показу вартості ділянки +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Купити ділянку для використання у майбутньому. Утримуйте Ctrl для виділення діагональної ділянки. Утримуйте Shift для показу вартості ділянки # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Вибір об'єкта -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Виберіть об'єкт для побудови. Утримуйте Shift для показу витрат на будівництво +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Виберіть об'єкт для побудови. Утримуйте Ctrl для вибору діагональної ділянки. Утримуйте Shift для показу витрат на будівництво STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Вибрати тип об'єкту для будівництва STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Попередній перегляд об'єкта STR_OBJECT_BUILD_SIZE :{BLACK}Розмір: {GOLD}{NUM} x {NUM} клітинок @@ -2984,6 +2980,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Випа STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Заснувати місто у випадковому місці STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Багато різних міст STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Випадково розташувати міста по карті +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Розширити всі міста +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Усі міста зростають помалу STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Назва міста: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Введіть назву міста @@ -3262,6 +3260,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Розм STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Оберіть розмір карти в клітинках. Кількість доступних клітинок буде трохи меншою STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Міста: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Назви міст: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Виберіть стиль назв міст STR_MAPGEN_DATE :{BLACK}Дата: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Кількість виробництв: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Найвища гора: @@ -3275,13 +3275,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Покр STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Збільшити покриття пустелею на 10% STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Зменшити покриття пустелею на 10% STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Ландшафт: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Тип ландшафту: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Рівень моря: +STR_MAPGEN_SEA_LEVEL :{BLACK}Рівень моря: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Ріки: STR_MAPGEN_SMOOTHNESS :{BLACK}Гладкість: STR_MAPGEN_VARIETY :{BLACK}Розподіл різноманітності: STR_MAPGEN_GENERATE :{WHITE}Генерувати +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Налаштування NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Показати налаштування NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Налаштування ШІ +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Показати усі налаштування +STR_MAPGEN_GS_SETTINGS :{BLACK}Налаштування сценарію гри +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Показати налаштування сценарію гри + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Англійські (оригінальні) +STR_MAPGEN_TOWN_NAME_FRENCH :Французькі +STR_MAPGEN_TOWN_NAME_GERMAN :Німецькі +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Англійські (додаткові) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Латиноамериканські +STR_MAPGEN_TOWN_NAME_SILLY :Кумедні +STR_MAPGEN_TOWN_NAME_SWEDISH :Шведські +STR_MAPGEN_TOWN_NAME_DUTCH :Нідерландські +STR_MAPGEN_TOWN_NAME_FINNISH :Фінські +STR_MAPGEN_TOWN_NAME_POLISH :Польські +STR_MAPGEN_TOWN_NAME_SLOVAK :Словацькі +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Норвезькі +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Угорські +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Австрійські +STR_MAPGEN_TOWN_NAME_ROMANIAN :Румунські +STR_MAPGEN_TOWN_NAME_CZECH :Чеські +STR_MAPGEN_TOWN_NAME_SWISS :Швейцарські +STR_MAPGEN_TOWN_NAME_DANISH :Данські +STR_MAPGEN_TOWN_NAME_TURKISH :Турецькі +STR_MAPGEN_TOWN_NAME_ITALIAN :Італійські +STR_MAPGEN_TOWN_NAME_CATALAN :Каталонські # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Краї карти: @@ -3340,7 +3368,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Дета STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Активні файли NewGRF STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Неактивні файли NewGRF STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Обрати набір: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Фільтр за строкою: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Фільтр: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Завантажити обрані налаштування STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Записати налаштування STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Записати поточний список як профіль налаштування @@ -3427,6 +3455,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Попе STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Повернутися до попереднього нормального спрайту, пропускаючи будь-які псевдо/перемальовані/шрифтові спрайти і обгортаючи (wrap) навколо починаючи з першого спрайту і закінчуючи останнім STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Відображення обраного спрайту (вирівнювання ігнорується) STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Рухайте спрайт навколо, змінюючи його зміщення за X та Y. Ctrl+клік зміщує спрайт на 8 клітинок + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Віжцентрувати зсув +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Спрайт по центру + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Прицільна сітка + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Відновити відносні STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Відновити поточні зсуви (відносні) STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Зсув по осі X: {NUM}, Зсув по осі Y: {NUM} (Абсолютно) @@ -3441,18 +3476,16 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Попередження: {SILVER}{STRING} 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} не буде працювати з версією TTDPatch, вказаною OpenTTD -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} для {STRING}-версії TTD -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} розроблено для {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Помилковий параметр для {1:STRING}: параметр {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} має бути завантажений до {STRING} -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} має бути завантажений після {STRING} -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} потребує версію OpenTTD не нижче {STRING} +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} для {2:STRING}-версії TTD +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} розроблено для використання з {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Помилковий параметр для {1:STRING}: параметр {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} має бути завантажений до {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} треба завантажити після {2:STRING} +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} потребує версію OpenTTD не нижче {2:STRING} STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF-файл, для якого це призначалось перекласти STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Завантажено забагато NewGRF-файлів -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Завантаження {1:STRING} як статичного NewGRF з {STRING} може викликати десинхронізацію +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Завантаження {1:STRING} як статичного NewGRF з {2:STRING} може викликати десинхронізацію STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Неочікуваний спрайт (спрайт {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Невідомий Action 0 параметр {4:HEX} (спрайт {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Спроба використання некоректного ID (спрайт {3:NUM}) @@ -3584,14 +3617,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Купити є STR_LOCAL_AUTHORITY_ACTION_BRIBE :Підкупити місцеву владу ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Провести малу локальну рекламну кампанію, щоб залучити більше пасажирів і вантажу до послуг вашої компанії.{}Тимчасово збільшить рейтинг станції у малому радіусі від міського центру.{}Вартість: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Провести середню локальну рекламну кампанію, щоб залучити більше пасажирів і вантажу до послуг вашої компанії.{}Тимчасово збільшить рейтинг станції у середньому радіусі від міського центру.{}Вартість: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Провести велику локальну рекламну кампанію, щоб залучити більше пасажирів і вантажу до послуг вашої компанії.{}Тимчасово збільшить рейтинг станції у великому радіусі від міського центру.{}Вартість: {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}Купити ексклюзивне транспортне право у місті на 1 рік.{}Міська влада не дозволить використовувати станції інших компаній.{}Вартість: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Підкупити місцеву владу для збільшення вашого рейтингу, при викритті загрожує суворим покаранням.{}Вартість: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Провести малу локальну рекламну кампанію, щоб залучити більше пасажирів і вантажу до послуг вашої компанії.{}Тимчасово збільшить рейтинг станції у малому радіусі від міського центру.{}{POP_COLOUR}Вартість: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Провести середню локальну рекламну кампанію, щоб залучити більше пасажирів і вантажу до послуг вашої компанії.{}Тимчасово збільшить рейтинг станції у середньому радіусі від міського центру.{}{POP_COLOUR}Вартість: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Провести велику локальну рекламну кампанію, щоб залучити більше пасажирів і вантажу до послуг вашої компанії.{}Тимчасово збільшить рейтинг станції у великому радіусі від міського центру.{}{POP_COLOUR}Вартість: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Фінансувати реконструкцію міських доріг.{}Призведе до значного погіршення руху на 6 місяців.{}{POP_COLOUR}Вартість: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Збудувати монумент на честь вашої компанії.{}Постійно збільшує рейтинг станцій у місті.{}{POP_COLOUR}Вартість: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Фінансувати будівництво нових офісів у місті.{}Тимчасово прискорить зростання міста.{}{POP_COLOUR}Вартість: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Купити ексклюзивне транспортне право у місті на 1 рік.{}Міська влада не дозволить використовувати станції інших компаній.{}{POP_COLOUR}Вартість: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Підкупити місцеву владу для збільшення вашого рейтингу, при викритті загрожує суворим покаранням.{}{POP_COLOUR}Вартість: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}Цілі {COMPANY} @@ -3744,24 +3777,38 @@ STR_FINANCES_CAPTION :{WHITE}Фіна STR_FINANCES_YEAR :{WHITE}{NUM} ###length 3 +STR_FINANCES_REVENUE_TITLE :{WHITE}Дохід +STR_FINANCES_OPERATING_EXPENSES_TITLE :{WHITE}Операційні видатки +STR_FINANCES_CAPITAL_EXPENSES_TITLE :{WHITE}Витрати коштів ###length 13 STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Будівництво STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Нова техніка -STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Витрати, поїзди -STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Витрати, автомобілі -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Витрати, літаки -STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Витрати, кораблі +STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Потяги +STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Дорожній транспорт +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Повітряний транспорт +STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Судна +STR_FINANCES_SECTION_INFRASTRUCTURE :{GOLD}Інфраструктура +STR_FINANCES_SECTION_TRAIN_REVENUE :{GOLD}Потяги +STR_FINANCES_SECTION_ROAD_VEHICLE_REVENUE :{GOLD}Дорожній транспорт +STR_FINANCES_SECTION_AIRCRAFT_REVENUE :{GOLD}Повітряний транспорт +STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Судна STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Відсотки за позикою STR_FINANCES_SECTION_OTHER :{GOLD}Інше -STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} -STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} +STR_FINANCES_TOTAL_CAPTION :{WHITE}Усього +STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} +STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Прибуток STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Рахунок +STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Власні кошти STR_FINANCES_LOAN_TITLE :{WHITE}Позика +STR_FINANCES_INTEREST_RATE :{WHITE}Відсотки за позикою: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Макс. позика: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Позичити {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Збільшити розмір позики. Ctrl+клац мишою позичає якнайбільше STR_FINANCES_REPAY_BUTTON :{BLACK}Повернути {CURRENCY_LONG} @@ -3862,7 +3909,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Виро 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 :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} очікує{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Змінити виробництво (кратне 8, до 2040) @@ -3892,6 +3939,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Дати STR_VEHICLE_LIST_REPLACE_VEHICLES :Оновлення STR_VEHICLE_LIST_SEND_FOR_SERVICING :Відправити на техогляд STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Прибуток цього року: {CURRENCY_LONG} (торік: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Відправити до депо STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Відправити в гараж @@ -3983,6 +4032,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Макс STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Дальність: {GOLD}{COMMA} клітинок STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Тип літака: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Всі типи вантажів +STR_CARGO_TYPE_FILTER_FREIGHT :Вантаж +STR_CARGO_TYPE_FILTER_NONE :нема + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Список поїздів. Клацніть на поїзд для інформації. Ctrl+клац мишою вимикає показ типу транспорту STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Список автомобілів. Клацніть на авто для отримання інформації. Ctrl+клац мишою вимикає показ типу транспорту @@ -4151,7 +4205,7 @@ 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_MAX_TE :{BLACK}Вартість: {CURRENCY_LONG} Вага: {WEIGHT_SHORT}{}Швидкість: {VELOCITY} Потужність: {POWER} Макс. тяга: {6:FORCE}{}Вартість експлуатації: {4:CURRENCY_LONG}/рік{}Місткість: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Вартість: {CURRENCY_LONG} Вага: {1:WEIGHT_SHORT}{}Швидкість: {2:VELOCITY} Потужність: {3: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_CAP_CAP_RUNCOST :{BLACK}Вартість: {CURRENCY_LONG} Макс. швидкість: {VELOCITY}{}Тип: {STRING}{}Місткість: {CARGO_LONG}, {CARGO_LONG}{}Вартість експлуатації: {CURRENCY_LONG}/рік STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Вартість: {CURRENCY_LONG} Макс. швидкість: {VELOCITY}{}Тип: {STRING}{}Місткість: {CARGO_LONG}{}Експлуатація: {CURRENCY_LONG}/рік @@ -4310,12 +4364,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Вага STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Вага: {LTBLUE}{WEIGHT_SHORT} {BLACK}Потужність: {LTBLUE}{POWER}{BLACK} Макс. швидкість: {LTBLUE}{VELOCITY} {BLACK}Макс. тяга: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Дохід цього року: {LTBLUE}{CURRENCY_LONG} (торік: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Дохід цього року: {LTBLUE}{CURRENCY_LONG} (минулого року: {CURRENCY_LONG}) {BLACK}Найгірше: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Надійність: {LTBLUE}{COMMA}% {BLACK}Аварії після останнього техогляду: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Побудований: {LTBLUE}{NUM}{BLACK} Вартість: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Місткість: {LTBLUE}нема{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Місткість: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Місткість: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Місткість: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Місткість: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Місткість: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Плата за трансфер: {LTBLUE}{CURRENCY_LONG} @@ -4341,8 +4396,8 @@ STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE :{LTBLUE}{ENGINE}{BLACK} Ціна: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT :{BLACK}Повна місткість цього поїзду: -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}- {CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT :{LTBLUE}{CARGO_LONG} ({CARGO_SHORT}) (x{NUM}) STR_VEHICLE_DETAILS_CARGO_EMPTY :{LTBLUE}порожній STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_LONG} з {STATION} @@ -4581,25 +4636,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Цей STR_TIMETABLE_STATUS_START_AT :{BLACK}Цей розклад почнеться о {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Дата початку -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Оберіть дату як точку відліку даного розкладу. Ctrl+клац мишою встановлює точку відліку даного розкладу і рівномірно розподіляє весь транспорт, що виконує це завдання згідно його відносного порядку розміщення, якщо порядок повністю розписаний у розкладі +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Оберіть дату як точку відліку даного розкладу. Ctrl+клац мишою рівномірно розподіляє весь транспорт, що має ці спільні завдання, згідно його відносного порядку розміщення, якщо порядок повністю розписаний у розкладі STR_TIMETABLE_CHANGE_TIME :{BLACK}Змінити час -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Змінити час, впродовж якого має виконуватись наказ +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Змінити час, впродовж якого має виконуватись наказ. Ctrl+клац змінить час в усіх завданнях STR_TIMETABLE_CLEAR_TIME :{BLACK}Скасувати час -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Скасувати час виконання виділеного наказу +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Скасувати час виконання виділеного наказу. Ctrl+клац видалить час в усіх завданнях STR_TIMETABLE_CHANGE_SPEED :{BLACK}Змінити обмеж. швидкості -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Змінити обмеження швидкості для виділеного пункту +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Змінити обмеження швидкості для виділеного пункту. Ctrl+клац змінить швидкість в усіх завданнях STR_TIMETABLE_CLEAR_SPEED :{BLACK}Скасувати обмеж. швидкості -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Скасувати обмеження швидкості для виділеного пункту +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Скасувати обмеження швидкості для виділеного пункту. Ctrl+клац видалить швидкість в усіх завданнях STR_TIMETABLE_RESET_LATENESS :{BLACK}Скасувати відхилення -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Скасувати лічильник відхилення від графіка, щоб транспорт встигнув +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Скасувати лічильник відхилення від графіка, щоб транспорт встигнув. Ctrl+клац щоб скасувати лічильник для всіх транспортів. При цьому останній транспорт стане йти за графіком, а інщі опереджати графік. STR_TIMETABLE_AUTOFILL :{BLACK}Авторозрахунок -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Автоматично розрахувати розклад впродовж наступної поїздки (Ctrl+click - спробувати зберегти час очікування) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Автоматично розрахувати розклад впродовж наступної поїздки. Ctrl+клац, щоб спробувати зберегти час очікування STR_TIMETABLE_EXPECTED :{BLACK}Очікується STR_TIMETABLE_SCHEDULED :{BLACK}Призначено @@ -4643,12 +4698,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Один STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Вікно налагодження АІ / Ігрового Скрипта доступне тільки серверу # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Налаштування AI / Ігрового Скрипта +STR_AI_CONFIG_CAPTION_AI :{WHITE}Налаштування ШІ +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Налаштування ігрового скрипта STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Ігровий Скрипт, який буде завантажено в наступній грі STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}АІ, які будуть завантажені в наступній грі STR_AI_CONFIG_HUMAN_PLAYER :Гравець-людина STR_AI_CONFIG_RANDOM_AI :Випадковий AI STR_AI_CONFIG_NONE :(нема) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Кількість конкурентів: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Перемістити вище STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Перемістити обраний AI вверх по списку @@ -4656,12 +4713,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Пере STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Перемістити обраний AI вниз по списку STR_AI_CONFIG_GAMESCRIPT :{SILVER}Ігровий Скрипт +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Параметри STR_AI_CONFIG_AI :{SILVER}АІ -STR_AI_CONFIG_CHANGE :{BLACK}Вибрати {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Ігровий Скрипт +STR_AI_CONFIG_CHANGE_AI :{BLACK}Обрати ШІ +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Обрати ігровий скрипт STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Завантажити інший скрипт STR_AI_CONFIG_CONFIGURE :{BLACK}Настроїти STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Настроїти параметри скрипту @@ -4689,9 +4745,9 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Знят STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Зняток мапи висот STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Зняток мінімапи -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Параметри -STR_AI_SETTINGS_CAPTION_AI :АІ +# Script Parameters +STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Налаштування +STR_AI_SETTINGS_CAPTION_AI :{WHITE}Параметри ШІ STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Ігровий Скрипт STR_AI_SETTINGS_CLOSE :{BLACK}Закрити STR_AI_SETTINGS_RESET :{BLACK}Скидання @@ -4856,6 +4912,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... за STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Неможливо створити виробництво... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Неможливо будувати {STRING.z} тут... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Неможливо будувати тут... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Неможливо виконати геологічну розвідку... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... дуже близько до іншої промисловості STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... спочатку збудуйте місто STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... у місті може бути тільки один @@ -4870,6 +4927,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... са STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... можна будувати тільки вище рівня снігу STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... можна будувати тільки нижче рівня снігу +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Не вдалося виконати геологічну розвідку; спробуйте знову +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Відсутні місця, придатні для геологічної розвідки цього виробництва STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Відсутні місця, придатні для '{STRING}' виробництва STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Змініть параметри генерування карти, щоб отримати кращу карту @@ -5037,6 +5096,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Об'є STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... на шляху Головний офіс STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Неможливо купити цю ділянку ... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... це вже ваша власність! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... досягнуто обмеження будівництва споруд # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Не можна створити групу... @@ -5109,6 +5169,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Не м STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... транспорт знищено +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... не увесь транспорт однаковий + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Недоступний жоден транспортний засіб STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Змінити налаштування встановленого NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Жоден вид транспорту ще не став доступним @@ -5135,6 +5197,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Не м STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... транспорт не може йти на всі станції STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... транспорт не може йти на цю станцію STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... транспорт, що має спільний з цим розклад, не може йти на цю станцію +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... не увесь транспорт має спільні завдання +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :WHITE}... не увесь транспорт має спільні завдання STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Неможливо розділити список завдань... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Неможливо відмінити спільні накази... @@ -5142,6 +5206,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Немо STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... занадто далеко від попереднього пункту призначення STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... літак не може летіти так далеко +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Не можна встановити розклад для транспорту... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Транспорт може чекати тільки на станціях diff --git a/src/lang/urdu.txt b/src/lang/urdu.txt index 9edd2550dfd5d..ae5db34ba4821 100644 --- a/src/lang/urdu.txt +++ b/src/lang/urdu.txt @@ -198,6 +198,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA} ھار STR_UNITS_POWER_METRIC :{COMMA} ھارس پآور STR_UNITS_POWER_SI :{COMMA} کلو واٹ + STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA} من STR_UNITS_WEIGHT_SHORT_SI :{COMMA} kg @@ -360,9 +361,8 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :باہر نکلو # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :کھیل کے اختیارات -STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI / کھیل کے اختیارات STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF اختیارات STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Transparency کے اختیارات STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :آبادیوں کے نام دکھائے جائیں @@ -891,36 +891,6 @@ STR_GAME_OPTIONS_CURRENCY_KRW :جنوبی کو STR_GAME_OPTIONS_CURRENCY_ZAR :جنوبی افریقہ کے رنڈ (ZAR) STR_GAME_OPTIONS_CURRENCY_CUSTOM :اپنی مرضی کی ۔۔۔ -###length 2 -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_DROPDOWN_TOOLTIP :{BLACK}شہروں کے نام کی طرز اختیار کریں - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :انگریزی (اصلی) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :فرانسیسی -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :جرمن -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :انگریزی (اضافی) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :لاطینی امریکی -STR_GAME_OPTIONS_TOWN_NAME_SILLY :سِلی -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :سوئیڈش -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :ڈچ -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :فِنش -STR_GAME_OPTIONS_TOWN_NAME_POLISH :پولش -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :سلواک -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :ناروئیجین -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :ہینگرین -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :آسٹرین -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :رومانین -STR_GAME_OPTIONS_TOWN_NAME_CZECH :چیک -STR_GAME_OPTIONS_TOWN_NAME_SWISS :سوئس -STR_GAME_OPTIONS_TOWN_NAME_DANISH :ڈینش -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :ٹرکش -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :اِٹالین -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :کاٹالن - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}خود مختار بچاو STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}خودمختار کھیل بچانے کے درمیان وقفہ اختیار کریں @@ -950,7 +920,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :دیگر - STR_GAME_OPTIONS_BASE_GRF :{BLACK}بُنیادی گرافک سیٹ STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}بُنیادی گرافک سیٹ اختیار کریں STR_GAME_OPTIONS_BASE_GRF_STATUS :{RED}{NUM} missing/corrupted file{P "" s} @@ -993,8 +962,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}جائ STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}اپنی کرنسی میں 10000 پاونڈ (£) STR_CURRENCY_CHANGE_PARAMETER :{BLACK}اپنی مرضی کے کرنسی پیرامیٹر کو تبدیل کریں -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}مدمقابلوں کی زیادہ سے زیادہ تعداد: {ORANGE}{COMMA} - STR_NONE :کوئی نہیں STR_FUNDING_ONLY :صرف فنڈنگ STR_MINIMAL :کم از کم @@ -1044,6 +1011,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Temperate منظر کشی +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arctic منظر کشی +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropical منظر کشی +STR_CLIMATE_TOYLAND_LANDSCAPE :Toyland منظر کشی + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :بہت سیدھا STR_TERRAIN_TYPE_FLAT :سیدھا @@ -1084,6 +1057,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_LEFT :بائیں STR_CONFIG_SETTING_HORIZONTAL_POS_CENTER :درمیان STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :دائیں +###setting-zero-is-special @@ -1243,6 +1217,10 @@ STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :اصلی STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :بہتر بنایا ہوا +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :بائیں طرف چلے +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :دائیں طرف چلے + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :اونچائی والے نقشے کو گھمانا: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :الٹی گھڑی وار @@ -1520,7 +1498,7 @@ STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS :بحری جہا STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :اشاروں پر خودکار ریورس ہونا: {STRING} ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recommended) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}سیٹنگ کی ولیو بدلیں @@ -1554,7 +1532,6 @@ STR_INTRO_MULTIPLAYER :{BLACK}زیاد STR_INTRO_GAME_OPTIONS :{BLACK}کھیل کے اختیارات STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF چنئے STR_INTRO_ONLINE_CONTENT :{BLACK}آن لائن مواد دیکھیں -STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI / کھیل کے اختیارات STR_INTRO_QUIT :{BLACK}باہر نکلو STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}نیا کھیل شروع کریں۔ Ctrl+Click نقشے کی ترتیب کو چھوڑ دے گا @@ -1572,7 +1549,6 @@ STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}منظر STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}کھیل کے اختیارات دکھائیں STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF سیٹنگز دیکھیئے STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}نئے اور ترمیم شدہ مواد کو ڈاون لوڈ کرنے کے لئے چیک کریں -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK} AI اور کھیل کے اختیارات دکھائیں STR_INTRO_TOOLTIP_QUIT :{BLACK}'OpenTTD' سے باہر نکلو STR_INTRO_TRANSLATION :{BLACK}اس ترجمے میں {NUM} لائنین{P "" یں} غیر ترجمہ سدہ ہیں۔ براہ مہربانی ترجمہ کُنندہ بن کر OpenTTD کی مدد کریں۔ تفصیلات کے لئے readme.txt دیکھیں @@ -1599,12 +1575,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}تار STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}موجودہ سال بدلیں STR_CHEAT_SETUP_PROD :{LTBLUE}پیداوار میں تبدیلی کو فعال کریں: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Temperate منظر کشی -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-arctic منظر کشی -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropical منظر کشی -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Toyland منظر کشی - # Livery window STR_LIVERY_GENERAL_TOOLTIP :{BLACK}رنگوں کا عام انتخاب دکھائیں @@ -1989,6 +1959,8 @@ STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}چیزو # Linkgraph legend window and linkgraph legend in smallmap +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}کوریج والے علاقے کو واضح کریں STR_STATION_BUILD_COVERAGE_OFF :{BLACK}بند @@ -2063,8 +2035,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}کھین STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}ریل کا پل منتخب کریں STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}سڑک کا پل منتخب کریں STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}پل کا انتخاب - تعمیر کرنے کے لئے اپنی مرضی کے پل پر کلک کریں -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :لٹکا ہوا، سٹیل کا STR_BRIDGE_NAME_GIRDER_STEEL :گارڈر، سٹیل کا STR_BRIDGE_NAME_CANTILEVER_STEEL :Cantilever، سٹیل @@ -2256,6 +2226,31 @@ STR_ABOUT_OPENTTD :{WHITE}اوپن # World generation STR_MAPGEN_BY :{BLACK}* +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}شہروں کے نام +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}شہروں کے نام کی طرز اختیار کریں + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :انگریزی (اصلی) +STR_MAPGEN_TOWN_NAME_FRENCH :فرانسیسی +STR_MAPGEN_TOWN_NAME_GERMAN :جرمن +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :انگریزی (اضافی) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :لاطینی امریکی +STR_MAPGEN_TOWN_NAME_SILLY :سِلی +STR_MAPGEN_TOWN_NAME_SWEDISH :سوئیڈش +STR_MAPGEN_TOWN_NAME_DUTCH :ڈچ +STR_MAPGEN_TOWN_NAME_FINNISH :فِنش +STR_MAPGEN_TOWN_NAME_POLISH :پولش +STR_MAPGEN_TOWN_NAME_SLOVAK :سلواک +STR_MAPGEN_TOWN_NAME_NORWEGIAN :ناروئیجین +STR_MAPGEN_TOWN_NAME_HUNGARIAN :ہینگرین +STR_MAPGEN_TOWN_NAME_AUSTRIAN :آسٹرین +STR_MAPGEN_TOWN_NAME_ROMANIAN :رومانین +STR_MAPGEN_TOWN_NAME_CZECH :چیک +STR_MAPGEN_TOWN_NAME_SWISS :سوئس +STR_MAPGEN_TOWN_NAME_DANISH :ڈینش +STR_MAPGEN_TOWN_NAME_TURKISH :ٹرکش +STR_MAPGEN_TOWN_NAME_ITALIAN :اِٹالین +STR_MAPGEN_TOWN_NAME_CATALAN :کاٹالن # Strings for map borders at game generation @@ -2301,6 +2296,10 @@ STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK} جای STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK} پچھلا sprite STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK} منتخب sprite کا اظھار۔ اس sprite کے نقش میں سف بندی نظر اندازکی جائے گی۔ STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK} ارد گرد sprite ھلایئے، X اور Y offset تبدیل کیجئے + +###length 2 + + STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK} منتخب sprite کیجئے STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK} اسکرین سے کسی sprite کو منتخب کیجئے @@ -2483,6 +2482,8 @@ STR_BUY_VEHICLE_AIRCRAFT_CAPTION :نیا طیار STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}پہنچ: {GOLD}{COMMA} ٹائلیں +###length 3 + ###length VEHICLE_TYPES ###length VEHICLE_TYPES @@ -2715,18 +2716,18 @@ STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK} وقف # AI configuration window +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}مدمقابلوں کی زیادہ سے زیادہ تعداد: {ORANGE}{COMMA} STR_AI_CONFIG_GAMESCRIPT :{SILVER}کھیل کا سکرپٹ -STR_AI_CONFIG_CHANGE_NONE : # Available AIs window -# AI Parameters +# Script Parameters # Textfile window @@ -2901,6 +2902,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}مرمت + # Specific vehicle errors @@ -2909,6 +2911,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}مرمت STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE} ۔ ۔ ۔ ہوائی جہاز کی اتنی پہنچ نہیں ہے +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors # Sign related errors diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index ce58ecc3a44de..9d4cd51a8b6c4 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -200,6 +200,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t +STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -225,9 +235,9 @@ STR_UNITS_HEIGHT_METRIC :{COMMA}{NBSP}m STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m # Common window strings -STR_LIST_FILTER_TITLE :{BLACK}Lọc chuỗi: -STR_LIST_FILTER_OSKTITLE :{BLACK}Nhập chuỗi lọc -STR_LIST_FILTER_TOOLTIP :{BLACK}Nhập từ khóa vào để lọc danh sách +STR_LIST_FILTER_TITLE :{BLACK}Lọc: +STR_LIST_FILTER_OSKTITLE :{BLACK}Nhập một hoặc nhiều từ khóa để lọc danh sách +STR_LIST_FILTER_TOOLTIP :{BLACK}Nhập một hoặc nhiều từ khóa để lọc danh sách STR_TOOLTIP_GROUP_ORDER :{BLACK}Chọn cách gom nhóm STR_TOOLTIP_SORT_ORDER :{BLACK}Chọn thứ tự sắp xếp (giảm dần/tăng dần) @@ -376,9 +386,9 @@ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Tạo th STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Tạo nhà máy STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Xây dựng đường STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Xây dựng đường xe điện -STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Trồng cây. Nhấn Shift để xem chi phí dự tính +STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Trồng cây. Ctrl chọn vùng theo đường chéo. Shift bật tắt xây dựng/hiển thị ước tính chi phí STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Tạo bảng ký hiệu -STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Đặt đối tượng. Nhấn Shift để xem chi phí dự tính +STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Đặt đối tượng. Ctrl để chọn khu vực theo đường chéo. Shift để xem chi phí dự tính # Scenario editor file menu ###length 7 @@ -391,10 +401,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Thoát # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Cấu hình trò chơi STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Thiết lập -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Thiết lập AI / Game script +STR_SETTINGS_MENU_AI_SETTINGS :Thiết lập AI +STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Thiết lập kịch bản màn chơi STR_SETTINGS_MENU_NEWGRF_SETTINGS :Thông số NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Thiết lập hiệu ứng trong suốt STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Hiển thị tên thị trấn @@ -965,36 +976,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rupee Ấn Đ STR_GAME_OPTIONS_CURRENCY_IDR :Rupiah Indonesia (IDR) STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit Malaysia (MYR) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Lái bên trái -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Lái bên phải - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Tên thị trấn: -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Lựa chọn kiểu tên thị trấn - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Tiếng Anh (Nguyên bản) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Pháp -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Đức -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Tiếng Anh (Bổ sung) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Mỹ-Latin -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Silly -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Thụy Điển -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Hà Lan -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Phần Lan -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Ba Lan -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovakia -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Na Uy -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungary -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Úc -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Ru-ma-ni -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Séc -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Thụy Sỹ -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Đan Mạch -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Thổ Nhĩ Kỳ -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Ý -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalan - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Lưu tự động STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Lựa chọn khoảng thời gian tự động lưu @@ -1027,21 +1008,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Đánh d STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Trình điều khiển hiện tại: {STRING} -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Kích thước giao diện -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Chọn kích thước của các đối tượng trên giao diện +STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Kích thước giao diện +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Kéo thanh trượt để điều chỉnh kích thước giao diện. Giữ Ctrl để điều chỉnh liên tục +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Tự động nhận dạng kích thước +STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Đánh dấu vào ô này để điều chỉnh kích thước giao diện tự động -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(nhận diện tự động) -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Bình thường -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Gấp 2 lần -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Gấp 4 lần +STR_GAME_OPTIONS_GUI_SCALE_BEVELS :Tỷ lệ góc xiên +STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Đánh dấu vào ô này để điều chỉnh tỷ lệ góc xiên theo kích thước giao diện -STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Cỡ chữ -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Chọn cỡ chữ trong giao diện - -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(nhận diện tự động) -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Bình thường -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Phóng to gấp đôi -STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Phóng nhân bốn +STR_GAME_OPTIONS_GUI_SCALE_1X :1x +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_4X :4x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Hình ảnh @@ -1093,8 +1072,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Xem tr STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pound (£) tính bằng tiền của bạn STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Sửa tham số của tiền tự chỉnh -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Số đối thủ cạnh tranh tối đa: {ORANGE}{COMMA} - STR_NONE :Không Có STR_FUNDING_ONLY :Chỉ Cấp Vốn STR_MINIMAL :Tối Thiểu @@ -1144,6 +1121,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Địa hình vừa phải +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Địa hình giá lạnh +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Địa hình cận nhiệt đới +STR_CLIMATE_TOYLAND_LANDSCAPE :Địa hình đồ chơi + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Rất Phẳng STR_TERRAIN_TYPE_FLAT :Phẳng @@ -1163,7 +1146,7 @@ STR_WARNING_NO_SUITABLE_AI :{WHITE}Không c # Settings tree window STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Thiết lập -STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Lọc chuỗi: +STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Lọc: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Mở xuống tất cả STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Đóng lại tất cả STR_CONFIG_SETTING_RESET_ALL :{BLACK}Thiết lập lại tất cả @@ -1223,6 +1206,9 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :Phải STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Khoảng vay khởi nghiệp tối đa: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Hạn mức tối đa một công ty có thể vay (không tính lạm phát) +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE :{CURRENCY_LONG} +###setting-zero-is-special +STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_DISABLED :Không có khoản vay {RED}Cần Game Script để cung cấp khoảng vốn ban đầu STR_CONFIG_SETTING_INTEREST_RATE :Lãi suất vay: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Lãi xuất vay; ảnh hưởng tới cả lạm phát nếu bật tùy chọn đó @@ -1449,6 +1435,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Độ đậm c STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Hiển thị tên NewGRF trong cửa sổ xây phương tiện: {STRING} STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Thêm một dòng vào cửa sổ xây phương tiện, hiển thị phương tiện đến từ NewGRF nào. +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Liệt kê hàng hoá mà phương tiện có thể chuyên chở trong cửa sổ danh sách {STRING} +STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Nếu được bật, những hàng hóa có thể vận chuyển của phương tiện sẽ được hiển thị phía trên chúng trong danh sách phương tiện STR_CONFIG_SETTING_LANDSCAPE :Nền đất: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Nền đất là định nghĩa cơ bản của các màn chơi với các kiểu hàng hóa và yêu cầu cho sự phát triển đô thị khác nhau. NewGRF và kịch bản chơi cho phép các điều chỉnh nhỏ hơn @@ -1503,6 +1491,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Tối Ưu Hóa STR_CONFIG_SETTING_ROAD_SIDE :Xe cộ: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Chọn phía xe chạy +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Lái bên trái +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Lái bên phải + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Xoay bản đồ địa hình: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Ngược chiều đồng hồ @@ -1936,13 +1928,13 @@ STR_CONFIG_SETTING_LINKGRAPH_TIME :Dùng {STRING}{ STR_CONFIG_SETTING_LINKGRAPH_TIME_HELPTEXT :Thời gian cần thiết cho mỗi bước tính toán đồ thị liên kết. Mỗi khi bắt đầu, chương trình tính toán sẽ được phép chạy trong một số ngày nào đó tùy theo giá trị này. Nếu quá ít có thể không đủ để tính toán, mà nếu quá nhiều thì nó sẽ kéo dài việc tính toán lại phân phối mỗi khi đường đi thay đổi. STR_CONFIG_SETTING_DISTRIBUTION_PAX :Chế độ phân phối đối với hành khách: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :Hành khách có thể di chuyển đối xứng (số lượng A đến B bằng B đến A) hoặc bất đối xứng, hoặc bằng tay. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"Đối xứng" có nghĩa là số lượng hành khách đi từ nhà ga A đến nhà ga B và từ B đến A sẽ tương đương nhau . "Không đối xứng" có nghĩa là số lượng hành khách tùy ý có thể đi theo một trong hai hướng. "Thủ công" có nghĩa là hành khách sẽ không được phân phối tự động. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Chế độ phân phối đối với thư tín: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :Thư tín có thể gửi đối xứng (khối lượng từ A đến B bằng B đến A) hoặc bất đối xứng, hoặc bằng tay. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"Đối xứng" có nghĩa là cùng một lượng thư sẽ được gửi từ trạm A đến trạm B cũng như từ B đến A. "Không đối xứng" có nghĩa là lượng thư tùy ý có thể được gửi theo một trong hai hướng. "Thủ công" có nghĩa là thư sẽ không được phân phối tự động. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Chế độ phân phối đối với hàng hóa đóng két: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Hàng hóa được đóng két là gói hàng có giá trong địa hình nhiệt đới, kim cương trong hoang mạc, vàng trong địa hình vùng cực lạnh. NewGRF có thể khác. Bạn nên đặt là bất đối xứng hoặc bằng tay nếu ở địa hình cực lạnh, vì ngân hàng sẽ không gửi vàng trở lại mỏ vàng. Với địa hình nhiệt đới hoặc hoang mạc thì có thể chọn đối xứng bởi các ngân hàng có thể gửi hai chiều với nhau. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Loại hàng hóa "ARMORED" chứa các vật có giá trị ở vùng ôn đới, kim cương ở vùng cận nhiệt đới hoặc vàng ở vùng khí hậu cận Bắc Cực. NewGRF có thể thay đổi điều đó. "Đối xứng" có nghĩa là cùng một lượng hàng hóa đó sẽ được gửi từ nhà ga A đến nhà ga B cũng như từ B đến A. "Không đối xứng" có nghĩa là lượng hàng hóa đó có thể được gửi tùy ý theo một trong hai hướng. "Thủ công" có nghĩa là sẽ không có hoạt động phân phối tự động nào đối với hàng hóa đó. Bạn nên đặt chế độ này thành bất đối xứng hoặc thủ công khi chơi ở vùng cận Bắc cực hoặc cận nhiệt đới, vì các ngân hàng chỉ nhận hàng ở những vùng khí hậu này. Đối với ôn hòa, bạn cũng có thể chọn đối xứng vì các ngân hàng sẽ gửi các vật có giá trị trở lại ngân hàng gốc. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Chế độ phân phối đối với các loại hàng hóa mặc định: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"bất đối xứng" là khối lượng hàng hóa tùy ý có thể gửi theo chiều bất kỳ. "bằng tay" là sẽ không phân phối tự động mà bạn sẽ phải chỉ ra. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Không đối xứng" có nghĩa là số lượng hàng hóa tùy ý có thể được gửi theo một trong hai hướng. "Thủ công" có nghĩa là những loại hàng hóa đó sẽ không được phân phối tự động. ###length 3 STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :bằng tay STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :bất đối xứng @@ -2037,7 +2029,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Tự động đ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Cho phép xe lửa vòng lại nơi đèn báo, khi nó chờ quá lâu ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Nên dùng) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Nên dùng) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Thay đổi giá trị @@ -2080,7 +2072,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Bảng STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Thiết lập STR_INTRO_NEWGRF_SETTINGS :{BLACK}Thiết Lập NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Các Nội Dung Trên Mạng -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Thiết Lập AI / Game Script +STR_INTRO_AI_SETTINGS :{BLACK}Thiết Lập AI +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Thiết lập Game Script STR_INTRO_QUIT :{BLACK}Thoát STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Màn chơi mới.Ctrl+Click để bỏ qua phần điều chỉnh màn @@ -2100,7 +2093,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Hiện b STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Thiết lập hiển thị STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Hiển thị tùy chỉnh NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Kiểm tra những nội dung mới & cập nhật để tải về -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Hiển thị thiết lập AI và Game script +STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Hiển thị tùy chỉnh AI +STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Hiển thị thiết lập kịch bản màn chơi STR_INTRO_TOOLTIP_QUIT :{BLACK}Thoát 'OpenTTD' STR_INTRO_BASESET :{BLACK}Gói đồ họa cơ sở đang chọn bị thiếu {NUM} sprite. Hãy cập nhật gói cơ sở này. @@ -2132,12 +2126,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Sửa t STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Thay đổi thời gian hiện tại STR_CHEAT_SETUP_PROD :{LTBLUE}Cho phép khả năng sửa giá trị sản xuất: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Địa hình vừa phải -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Địa hình giá lạnh -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Địa hình cận nhiệt đới -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Địa hình đồ chơi - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Cách Phối Màu Mới @@ -2370,7 +2358,8 @@ STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Công ty mới STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Khai sinh một công ty và gia nhập STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Đây là bạn STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Đây là người tổ chức ván chơi -STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} người chơi / {NUM} công ty +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT :{BLACK}{NUM} nguời chơi - {NUM}/{NUM} công ty +STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP :{BLACK}Số lượng máy trạm, số lượng công ty và số lượng công ty tối đa mà quản lý máy chủ cho phép # Matches ConnectionType ###length 5 @@ -2497,13 +2486,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :đợi cập nh STR_NETWORK_MESSAGE_CLIENT_LEAVING :ra khỏi ván STR_NETWORK_MESSAGE_CLIENT_JOINED :*** Máy trạm {STRING} gia nhập ván chơi -STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** Máy trạm {STRING} đã vào trò chơi (Máy trạm #{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} gia nhập công ty #{2:NUM} +STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** Máy trạm {0:STRING} đã vào trò chơi (Máy trạm #{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} đã gia nhập công ty #{2:NUM} STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} vào xem ván chơi -STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} khai trương công ty mới (#{2:NUM}) -STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} rời bỏ ván chơi ({2:STRING}) +STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} khai trương công ty mới (#{2:NUM}) +STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} rời bỏ ván chơi ({2:STRING}) STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} đã đổi tên thành {STRING} -STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} tặng {2:CURRENCY_LONG} cho {1:STRING} +STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} tặng {2:CURRENCY_LONG} cho {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Server kết thúc phiên STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Server khởi động lại...{}Xin chờ... STR_NETWORK_MESSAGE_KICKED :*** {STRING} đã bị đá khỏi ván chơi. Lý do: ({STRING}) @@ -2617,6 +2606,11 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}bão hòa STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}quá tải +# Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} sẽ được vận chuyển hằng tháng từ {STATION} đến {STATION} ({COMMA}% dung lượng){STRING} +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} sẽ được hoàn chuyển ({COMMA}% dung lượng) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Thời gian đi lại trung bình: {NUM}{NBSP}ngày + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Hiện rõ vùng phủ ảnh hưởng STR_STATION_BUILD_COVERAGE_OFF :{BLACK}Tắt @@ -2625,6 +2619,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Không h STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Hiện vùng che phủ của điểm đề xuất STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Chấp nhận: {GOLD}{CARGO_LIST} STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Cung cấp: {GOLD}{CARGO_LIST} +STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Chi phí bảo trì: {GOLD}{CURRENCY_SHORT}/năm # Join station window STR_JOIN_STATION_CAPTION :{WHITE}Nối ga, bến @@ -2707,8 +2702,10 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Tăng m STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Chọn Loại Cầu Tàu Hỏa STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Chọn Loại Cầu Đường Bộ STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Chọn cầu - chọn loại cầu bạn muốn xây dựng -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME :{GOLD}{STRING} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED :{GOLD}{STRING},{} {VELOCITY} +STR_SELECT_BRIDGE_INFO_NAME_COST :{GOLD}{0:STRING},{} {WHITE}{2:CURRENCY_LONG} +STR_SELECT_BRIDGE_INFO_NAME_MAX_SPEED_COST :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} STR_BRIDGE_NAME_SUSPENSION_STEEL :Cầu treo thép STR_BRIDGE_NAME_GIRDER_STEEL :Cầu dầm thép STR_BRIDGE_NAME_CANTILEVER_STEEL :Cầu dầm chìa thép @@ -2812,11 +2809,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Tôn h STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Hạ thấp một góc đất. Kéo để hạ đất từ điểm đã chọn tới điểm thấp mới. Ctrl để chọn đường chéo. Shift để hiện chi phí dự tính STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Nâng cao một góc đất. Kéo để nâng đất từ điểm đã chọn tới điểm cao mới. Ctrl để chọn đường chéo. Shift để hiện chi phí dự tính STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Làm bình địa tới độ cao của điểm chọn đầu tiên. Ctrl để chọn vùng theo đường chéo. Shift để hiện chi phí dự tính -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Mua đất dành cho tương lai. Shift+Click để xem chi phí dự tính +STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Mua đất dành cho tương lai. Ctrl để chọn khu vực theo đường chéo. Shift để xem chi phí dự tính # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Trình Chọn Đối Tượng -STR_OBJECT_BUILD_TOOLTIP :{BLACK}Chọn đối tượng để xây. Shift+Click để xem chi phí dự tính +STR_OBJECT_BUILD_TOOLTIP :{BLACK}Chọn đối tượng để xây. Ctrl để chọn khu vực theo đường chéo. Shift để xem chi phí dự tính STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Chọn lớp đối tượng để xây dựng STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Xem trước đối tượng STR_OBJECT_BUILD_SIZE :{BLACK}Kích thước: {GOLD}{NUM} x {NUM} ô @@ -2828,7 +2825,7 @@ STR_OBJECT_CLASS_TRNS :Tháp tín hi STR_PLANT_TREE_CAPTION :{WHITE}Cây Cối STR_PLANT_TREE_TOOLTIP :{BLACK}Chọn loại cây để trồng. Nếu ô đó đã có cây, thao tác này sẽ thêm hỗn hợp nhiều cây khác độc lập với loại đã chọn STR_TREES_RANDOM_TYPE :{BLACK}Loại cây ngẫu nhiên -STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Trồng ngẫu nhiên các loại cây. Shift+Click để xem chi phí dự tính +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Đặt các loại cây ngẫu nhiên. Ctrl chọn vùng theo đường chéo. Shift bật tắt xây dựng/hiển thị ước tính chi phí STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Trồng ngẫu nhiên STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Trồng cây ngẫu nhiên trên khoảnh đất STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Bình thường @@ -2860,6 +2857,8 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Tạo đ STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Tìm đô thị vị trí ngẫu nhiên STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Nhiều đô thị ngẫu nhiên STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Phủ bản đồ bằng cách tạo đô thị ngẫu nhiên +STR_FOUND_TOWN_EXPAND_ALL_TOWNS :{BLACK}Mở xuống tất cả đô thị +STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Làm cho mọi đô thị tăng trưởng một chút STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Tên thị trấn: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Nhập tên thị trấn @@ -3124,7 +3123,7 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Chi Ti STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Không có thông tin gì cả. STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}NewGRF: {WHITE}{STRING} -STR_SAVELOAD_FILTER_TITLE :{BLACK}Chuỗi lọc: +STR_SAVELOAD_FILTER_TITLE :{BLACK}Lọc: STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Ghi đè file STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Bạn có chắc chắn ghi đè lên file đang tồn tại? STR_SAVELOAD_DIRECTORY :{STRING} (Thư mục) @@ -3138,6 +3137,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kích th STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Lựa chọn kích thước bản đồ theo đơn vị ô. Số lượng ô thực sự có thể nhỏ hơn 1 chút. STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Số lượng đô thị: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Tên thị trấn: +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Lựa chọn kiểu tên thị trấn STR_MAPGEN_DATE :{BLACK}Thời điểm: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Số lượng nhà máy: STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Độ cao đỉnh cao nhất: @@ -3151,13 +3152,41 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}Độ ph STR_MAPGEN_DESERT_COVERAGE_UP :{BLACK}Tăng độ phủ sa mạc lên mười phần trăm STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Giảm độ phủ sa mạc đi mười phần trăm STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}% -STR_MAPGEN_LAND_GENERATOR :{BLACK}Tạo nền đất: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Kiểu nền đất: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Mực nước biển: +STR_MAPGEN_SEA_LEVEL :{BLACK}Mực nước biển: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Số sông/suối: STR_MAPGEN_SMOOTHNESS :{BLACK}Độ phẳng phiu: STR_MAPGEN_VARIETY :{BLACK}Phân bổ sự đa dạng: STR_MAPGEN_GENERATE :{WHITE}Khởi Tạo +STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Thiết Lập NewGRF +STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Hiển thị tùy chỉnh NewGRF +STR_MAPGEN_AI_SETTINGS :{BLACK}Thiết lập AI +STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Hiển thị tùy chỉnh AI +STR_MAPGEN_GS_SETTINGS :{BLACK}Thiết lập Game Script +STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Hiển thị thiết lập game script + +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Tiếng Anh (Nguyên bản) +STR_MAPGEN_TOWN_NAME_FRENCH :Pháp +STR_MAPGEN_TOWN_NAME_GERMAN :Đức +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Tiếng Anh (Bổ sung) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Mỹ-Latin +STR_MAPGEN_TOWN_NAME_SILLY :Silly +STR_MAPGEN_TOWN_NAME_SWEDISH :Thụy Điển +STR_MAPGEN_TOWN_NAME_DUTCH :Hà Lan +STR_MAPGEN_TOWN_NAME_FINNISH :Phần Lan +STR_MAPGEN_TOWN_NAME_POLISH :Ba Lan +STR_MAPGEN_TOWN_NAME_SLOVAK :Slovakia +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Na Uy +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungary +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Úc +STR_MAPGEN_TOWN_NAME_ROMANIAN :Ru-ma-ni +STR_MAPGEN_TOWN_NAME_CZECH :Séc +STR_MAPGEN_TOWN_NAME_SWISS :Thụy Sỹ +STR_MAPGEN_TOWN_NAME_DANISH :Đan Mạch +STR_MAPGEN_TOWN_NAME_TURKISH :Thổ Nhĩ Kỳ +STR_MAPGEN_TOWN_NAME_ITALIAN :Ý +STR_MAPGEN_TOWN_NAME_CATALAN :Catalan # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Rìa bản đồ: @@ -3216,7 +3245,7 @@ STR_NEWGRF_SETTINGS_INFO_TITLE :{WHITE}Thông t STR_NEWGRF_SETTINGS_ACTIVE_LIST :{WHITE}Các NewGRP đã kích hoạt STR_NEWGRF_SETTINGS_INACTIVE_LIST :{WHITE}Các NewGRF chưa kích hoạt STR_NEWGRF_SETTINGS_SELECT_PRESET :{ORANGE}Chọn bộ tham số: -STR_NEWGRF_FILTER_TITLE :{ORANGE}Lọc giá trị: +STR_NEWGRF_FILTER_TITLE :{ORANGE}Lọc: STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP :{BLACK}Nạp các thiết lập đã chọn STR_NEWGRF_SETTINGS_PRESET_SAVE :{BLACK}Lưu thiết lập STR_NEWGRF_SETTINGS_PRESET_SAVE_TOOLTIP :{BLACK}Lưu danh sách này như là thiết lập @@ -3303,6 +3332,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Sprite t STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Xử lý sprite bình thường ở trước, bỏ qua các loại pseudo/recolour/font sprite căn theo điểm bắt đầu STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Theo những thông tin của sprite đã chọn. Thì việc căn chỉnh khi vẽ đối với sprite này sẽ bị bỏ qua STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Di chuyển sprite xung quanh, thay đổi X và Y offsets. Ctrl+Click để di chuyển sprite tám đơn vị một lúc + +###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Toạ độ về trung tâm +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite về trung tâm + +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Chữ thập + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Đặt lại tương đối STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Đặt lại các dịch chuyển tương đối hiện tại STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK} dịch X: {NUM}, dịch Y: {NUM} (tuyệt đối) @@ -3317,18 +3353,18 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Cảnh báo: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Lỗi: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Lỗi nghiêm trọng: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Xảy ra lỗi NewGRF nghiêm trọng:{}{STRING} -STR_NEWGRF_ERROR_POPUP :{WHITE}Có lỗi NewGRF xảy ra:{}{STRING} +STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}NewGRF "{STRING}" đã xảy ra một lỗi nghiêm trọng:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF "{STRING}" đã xảy ra lỗi:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} sẽ không hoạt động với phiên bản TTDPatch version theo như báo cáo của OpenTTD. -STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} để dành cho phiên bản {STRING} của TTD. -STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} được thiết kế để xài với {STRING} -STR_NEWGRF_ERROR_INVALID_PARAMETER :Tham số không hợp lệ {1:STRING}: tham số {STRING} ({NUM}) -STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} phải được nạp trước {STRING}. -STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} phỉa được nạp sau {STRING}. -STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} yêu cầu phiên bản OpenTTD {STRING} hoặc cao hơn. +STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} để dành cho phiên bản {2:STRING} của TTD. +STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} được thiết kế để dùng với {2:STRING} +STR_NEWGRF_ERROR_INVALID_PARAMETER :Tham số không hợp lệ {1:STRING}: tham số {2:STRING} ({3:NUM}) +STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} phải được nạp trước {2:STRING} +STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} phỉa được nạp sau {2:STRING}. +STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} yêu cầu phiên bản OpenTTD {2:STRING} hoặc cao hơn. STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :GRF file được thiết kế để phiên dịch STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Quá nhiều NewGRFs đã nạp. -STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Nạp {1:STRING} như là NewGRF tĩnh với {STRING} có thể gây mất đồng bộ +STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Nạp {1:STRING} như là NewGRF tĩnh với {2:STRING} có thể gây mất đồng bộ STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :sprite không hợp lệ (sprite {3:NUM}) STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Thuộc tính thực thi 0 chưa định nghĩa {4:HEX} (sprite {3:NUM}) STR_NEWGRF_ERROR_INVALID_ID :Sử dụng IT không hợp lệ (sprite {3:NUM}) @@ -3460,14 +3496,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Mua độc quy STR_LOCAL_AUTHORITY_ACTION_BRIBE :Hối lộ quan chức địa phương ###length 8 -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Thực hiện chiến dịch quảng cáo nhỏ để thu hút khách và hàng hoá vận chuyển.{}Tăng xếp hạng cho các trạm gần trung tâm trong thời gian ngắn.{}Chi phí: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Thực hiện chiến dịch quảng cáo trung bình để thu hút khách và hàng hoá vận chuyển.{}Tăng xếp hạng cho các trạm xung quanh trung tâm trong thời gian ngắn.{}Chi phí: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Thực hiện chiến dịch quảng cáo lớn để thu hút khách và hàng hoá vận chuyển.{}Tăng xếp hạng cho các trạm xung quanh & xa trung tâm trong thời gian ngắn.{}Chi phí: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Tài trợ xây dựng lại đường sá của đô thị.{} Sẽ gây ách tắc giao thông đường bộ trong 6 tháng.{}Chi phí: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Dựng tượng đài tôn vinh để quảng bá hình ảnh công ty.{} Tăng xếp hạng cho các trạm trong khu vực.{} Chi phí: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Tài trợ xây dựng các toà nhà để thúc đẩy phát triển đô thị.{}Tăng sự phát triển đô thị trong một thời gian ngắn.{}Chi phí: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Mua 1 năm độc quyền kinh doanh vận tải của đô thị.{} Chính quyền địa phương sẽ ra luật chỉ cho phép hành khách và hàng hoá vào nhà ga, bến, cảng của công ty.{}Chi phí: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Đút lót quan chức địa phương để nâng cao quyền lợi, có một tỉ lệ rủi ro nếu bại lộ và sẽ mất hết quyền lợi lẫn tiền hối lộ.{}Chi phí: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Thực hiện chiến dịch quảng cáo nhỏ để thu hút khách và hàng hoá vận chuyển.{}Tăng xếp hạng cho các trạm gần trung tâm trong thời gian ngắn.{}{POP_COLOUR}Chi phí: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Thực hiện chiến dịch quảng cáo trung bình để thu hút khách và hàng hoá vận chuyển.{}Tăng xếp hạng cho các trạm xung quanh trung tâm trong thời gian ngắn.{}{POP_COLOUR}Chi phí: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Thực hiện chiến dịch quảng cáo lớn để thu hút khách và hàng hoá vận chuyển.{}Tăng xếp hạng cho các trạm xung quanh & xa trung tâm trong thời gian ngắn.{}{POP_COLOUR}Chi phí: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Tài trợ xây dựng lại đường sá của đô thị.{} Sẽ gây ách tắc giao thông đường bộ trong 6 tháng.{}{POP_COLOUR}Chi phí: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Dựng tượng đài tôn vinh để quảng bá hình ảnh công ty.{} Tăng xếp hạng cho các trạm trong khu vực.{}{POP_COLOUR} Chi phí: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Tài trợ xây dựng các toà nhà để thúc đẩy phát triển đô thị.{}Tăng sự phát triển đô thị trong một thời gian ngắn.{}{POP_COLOUR}Chi phí: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Mua 1 năm độc quyền kinh doanh vận tải của đô thị.{} Chính quyền địa phương sẽ ra luật chỉ cho phép hành khách và hàng hoá vào nhà ga, bến, cảng của công ty.{}{POP_COLOUR}Chi phí: {CURRENCY_LONG} +STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Đút lót quan chức địa phương để nâng cao quyền lợi, có một tỉ lệ rủi ro nếu bại lộ và sẽ mất hết quyền lợi lẫn tiền hối lộ.{}{POP_COLOUR}Chi phí: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}Mục Tiêu Của {COMPANY} @@ -3640,15 +3676,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Tàu thuy STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Lãi vay vốn STR_FINANCES_SECTION_OTHER :{GOLD}Khác +STR_FINANCES_TOTAL_CAPTION :{WHITE}Tổng số STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} -STR_FINANCES_NET_PROFIT :{WHITE}Lợi Nhuận Ròng +STR_FINANCES_PROFIT :{WHITE}Lợi nhuận STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Số dư hiện có STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Nguồn Vốn Riêng STR_FINANCES_LOAN_TITLE :{WHITE}Đi vay STR_FINANCES_INTEREST_RATE :{WHITE}Lãi Vay Vốn: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Hạn mức vay: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Vay {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Vay thêm tiền. Ctrl+Click vay hết hạn mức ngay STR_FINANCES_REPAY_BUTTON :{BLACK}Trả nợ {CURRENCY_LONG} @@ -3749,7 +3788,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Sản l STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Cần cung cấp: -STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} đang chờ{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}Thay đổi sản lượng (bội số của 8, max 2040) @@ -3779,6 +3818,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Gửi ch STR_VEHICLE_LIST_REPLACE_VEHICLES :Thay phương tiện STR_VEHICLE_LIST_SEND_FOR_SERVICING :Gửi về bảo trì STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Lợi nhuận năm nay: {CURRENCY_LONG} (năm ngoái: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Gửi về xưởng STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Gửi về xưởng @@ -3870,6 +3911,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Lực k STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Tầm xa: {GOLD}{COMMA} ô STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Kiểu máy bay: {GOLD}{STRING} +###length 3 +STR_CARGO_TYPE_FILTER_ALL :Tất cả hàng hóa +STR_CARGO_TYPE_FILTER_FREIGHT :Hàng hóa +STR_CARGO_TYPE_FILTER_NONE :Không + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Danh sách tàu hỏa có thể chọn. Click vào tàu hỏa để xem thông tin. Ctrl+Click để ẩn/hiện loại được chọn STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Danh sách xe có thể chọn. Click vào xe để xem thông tin. Ctrl+Click để ẩn/hiện loại được chọn @@ -4038,7 +4084,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :máy bay STR_ENGINE_PREVIEW_SHIP :tàu thuỷ STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Giá thành: {CURRENCY_LONG} Tải trọng: {WEIGHT_SHORT}{}Tốc độ: {VELOCITY} Công suất: {POWER}{}Chi phí hoạt động: {CURRENCY_LONG}/năm{}Sức chứa: {CARGO_LONG} -STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Giá: {CURRENCY_LONG} Nặng: {WEIGHT_SHORT}{}Tốc độ: {VELOCITY} Công suất: {POWER} Max. T.E.: {6:FORCE}{}Giá vận hành: {4:CURRENCY_LONG}/yr{}Năng suất: {5:CARGO_LONG} +STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Giá: {0:CURRENCY_LONG} Nặng: {1:WEIGHT_SHORT}{}Tốc độ: {2:VELOCITY} Công suất: {3:POWER} Max. T.E.: {6:FORCE}{}Giá vận hành: {4:CURRENCY_LONG}/yr{}Năng suất: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Giá thành: {CURRENCY_LONG} Tốc độ tối đa: {VELOCITY}{}Sức chứa: {CARGO_LONG}{}Chi phí hoạt động: {CURRENCY_LONG}/năm STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Giá: {CURRENCY_LONG} Tốc độ tối đa: {VELOCITY}{}Kiểu máy bay: {STRING}{}Sức chứa: {CARGO_LONG}, {CARGO_LONG}{}Chi phí hoạt động: {CURRENCY_LONG}/năm STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}GIá: {CURRENCY_LONG} Tốc độ tối đa: {VELOCITY}{}Kiểu máy bay: {STRING}{}Sức chứa: {CARGO_LONG}{}Chi phí hoạt động: {CURRENCY_LONG}/năm @@ -4197,12 +4243,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Tải tr STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Tải trọng: {LTBLUE}{WEIGHT_SHORT} {BLACK}Công suất: {LTBLUE}{POWER}{BLACK} Tốc độ tối đa: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lợi nhuận năm nay: {LTBLUE}{CURRENCY_LONG} (năm ngoái: {CURRENCY_LONG}) +STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Lợi nhuận năm nay: {LTBLUE}{CURRENCY_LONG} (năm ngoái: {CURRENCY_LONG}) {BLACK}Hiệu suất tối thiểu: {LTBLUE}{POWER_TO_WEIGHT} STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Độ tin cậy: {LTBLUE}{COMMA}% {BLACK}Hỏng hóc kể từ lần bảo trì cuối: {LTBLUE}{COMMA} STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Mua lúc: {LTBLUE}{NUM}{BLACK} Giá trị: {LTBLUE}{CURRENCY_LONG} STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Sức chứa: {LTBLUE}Không{STRING} -STR_VEHICLE_INFO_CAPACITY :{BLACK}Sức chứa: {LTBLUE}{CARGO_LONG}{3:STRING} -STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Sức chứa: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM}) +STR_VEHICLE_INFO_CAPACITY :{BLACK}Sức chứa: {LTBLUE}{0:CARGO_LONG}{3:STRING} +STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Sức chứa: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM}) STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Sức chứa: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING} STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Cước trung chuyển: {LTBLUE}{CURRENCY_LONG} @@ -4468,25 +4515,25 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Bảng l STR_TIMETABLE_STATUS_START_AT :{BLACK}Bảng lịch trình sẽ bắt đầu lúc {STRING} STR_TIMETABLE_STARTING_DATE :{BLACK}Ngày bắt đầu -STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Lựa chọn ngày bắt đầu trong bảng lịch trình này. Ctrl+Click chọn ngày bắt đầu trong bảng lịch trình và phân bổ nó cho tất cả các phương tiện chia sẻ lộ trình này, nếu như lộ trình đã lên lịch đầy đủ. +STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Lựa chọn ngày bắt đầu trong bảng lịch trình này. Ctrl+Click phân bổ cho tất cả các phương tiện chia sẻ lộ trình này bắt đầu từ ngày được chọn một cách đồng đều theo thứ tự tương đối giữa chúng, nếu như lộ trình đã lên lịch đầy đủ. STR_TIMETABLE_CHANGE_TIME :{BLACK}Đổi thời gian -STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Thay đổi thời lượng của điểm lộ trình được phép sử dụng +STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Thay đổi thời lượng của điểm lộ trình được phép sử dụng. Ctrl+Click đặt thời gian cho mọi lộ trình STR_TIMETABLE_CLEAR_TIME :{BLACK}Xoá thời gian -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Xóa thời lượng áp dụng cho điểm lộ trình +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Xóa thời lượng áp dụng cho điểm lộ trình. Ctrl+Click xoá tất cả thời gian cho mọi lộ trình STR_TIMETABLE_CHANGE_SPEED :{BLACK}Thay Đổi Giới Hạn Tốc Độ -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Thay đổi tốc độ tối đa của lộ trình được chọn +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Thay đổi tốc độ tối đa của lộ trình được chọn. Ctrl+Click đặt tốc độ cho mọi lộ trình STR_TIMETABLE_CLEAR_SPEED :{BLACK}Xóa Giới Hạn Tốc Độ -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Xóa tốc độ đối đa đối với lộ trình được chọn +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Xóa tốc độ đối đa đối với lộ trình được chọn. Ctrl+Click xoá tốc độ cho mọi lộ trình STR_TIMETABLE_RESET_LATENESS :{BLACK}Lập lại bộ đếm trễ -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Thiết lập lại bộ đếm trễ giờ, để việc di chuyển phương tiện được tính lại đúng đắn +STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}Thiết lập lại bộ đếm trễ giờ, để phương tiện được tính là đúng giờ. Ctrl+Click sẽ thiết lập lại nguyên nhóm, phương tiện mới nhất sẽ được tính là đúng giờ, và các phương tiện khác được tính là sớm STR_TIMETABLE_AUTOFILL :{BLACK}Tự điền -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Tự điền bảng lịch trình qua việc đo thời gian hành trình kế tiếp (Ctrl+Click để cố giữ thời gian chờ không đổi) +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Tự điền bảng lịch trình qua việc đo thời gian hành trình kế tiếp. Ctrl+Click để cố giữ thời gian chờ không đổi STR_TIMETABLE_EXPECTED :{BLACK}Mong muốn STR_TIMETABLE_SCHEDULED :{BLACK}Chốt lịch @@ -4530,12 +4577,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Có mộ STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Cửa sổ gỡ lỗi AI/Game Script chỉ có trên server # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Thiết Lập Game AI/Game Script +STR_AI_CONFIG_CAPTION_AI :{WHITE}Cấu hình AI +STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Cấu hình Game Script STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Các Game Script sẽ được chạy trong ván chơi tiếp theo STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Các AIs sẽ được chạy trong ván chơi tiếp theo STR_AI_CONFIG_HUMAN_PLAYER :Nhân vật người STR_AI_CONFIG_RANDOM_AI :AI ngẫu nhiên STR_AI_CONFIG_NONE :(không) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Số đối thủ cạnh tranh tối đa: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Chuyển Lên Trên STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Di chuyển AI lên trên danh sách @@ -4543,12 +4592,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Di Chuy STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Di chuyển AI xuống dưới danh sách STR_AI_CONFIG_GAMESCRIPT :{SILVER}Game Script +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Tham số STR_AI_CONFIG_AI :{SILVER}AIs -STR_AI_CONFIG_CHANGE :{BLACK}Chọn {STRING} -STR_AI_CONFIG_CHANGE_NONE : -STR_AI_CONFIG_CHANGE_AI :AI -STR_AI_CONFIG_CHANGE_GAMESCRIPT :Game Script +STR_AI_CONFIG_CHANGE_AI :{BLACK}Chọn AI +STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Chọn Game Script STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Chạy tập lệnh khác STR_AI_CONFIG_CONFIGURE :{BLACK}Tham Số STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Cấu hình tham số cho AI @@ -4576,8 +4624,8 @@ STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Chụp t STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Chụp bản đồ địa hình STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Chụp màn hình bản đồ nhỏ -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Các Thông Số +# Script Parameters +STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Tham số STR_AI_SETTINGS_CAPTION_AI :AI STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Game Script STR_AI_SETTINGS_CLOSE :{BLACK}Đóng @@ -4743,6 +4791,7 @@ STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... quá STR_ERROR_CAN_T_GENERATE_INDUSTRIES :{WHITE}Không thể tạo nhà máy... STR_ERROR_CAN_T_BUILD_HERE :{WHITE}Không thể xây {STRING} ở đây... STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}Không thể xây loại nhà máy này ở đây... +STR_ERROR_CAN_T_PROSPECT_INDUSTRY :{WHITE}Không thể dò tìm nhà máy... STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... quá gần nhà máy khác STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... phải có ở thị trấn cái đã STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... mỗi đô thị chỉ được có một cái @@ -4757,6 +4806,8 @@ STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... rừ STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... chỉ có thể xây phía trên núi cao có tuyết STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... chỉ có thể xây phía dưới núi cao có tuyết +STR_ERROR_PROSPECTING_WAS_UNLUCKY :{WHITE}Không may là việc góp vốn cho tìm kiếm nhà máy thất bại; hãy thử lại +STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING :{WHITE}Không có một nơi phù hợp nào để dò tìm nhà máy này STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}Không có vùng đất nào phù hợp với nhà máy '{STRING}' STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}Thay đổi thông số khởi tạo bản đồ để có được bản đồ tốt hơn @@ -4924,6 +4975,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Có vậ STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... trụ sở công ty nằm trên đường STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Không thể mua được mảnh đất này... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... bạn đã có nó rồi! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... đã đến giới hạn xây của đối tượng # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Không thể tạo nhóm... @@ -4996,6 +5048,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Không t STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... xe đã bị phá hủy +STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... các phương tiện không như nhau + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Không có phương tiện nào sẵn sàng cả STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Thay đổi tham số NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Chưa có phương tiện nào có sẵn @@ -5022,6 +5076,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Không t STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... phương tiện không thể tới được mọi ga, bến STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... phương tiện không thể tới ga, bến đó được STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... phương tiện dùng lộ trình chia sẻ này không tới được ga, bến đó +STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... các phương tiện không có cùng lộ trình +STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... không phải tất cả phương tiện đang chia sẻ lộ trình STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Không thể chia sẻ lộ trình... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Không thể dừng chia sẻ danh sách lịch trình... @@ -5029,6 +5085,9 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Không t STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... quá xa điểm lộ trình kế trước STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... máy bay không đủ tầm xa +# Extra messages which go on the third line of errors, explaining why orders failed +STR_ERROR_AIRPORT_NO_HELICOPTERS :{WHITE}Không thể hạ cánh trực thăng ở sân bay này + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Không thể lập lịch trình cho phương tiện... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Phương tiện chỉ có thể chờ ở nhà ga, bến, cảng. diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index aa422f379c499..b242620988b66 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -170,6 +170,7 @@ STR_LITERS :{COMMA}{NBSP}li STR_ITEMS :{COMMA}{NBSP}eitem STR_CRATES :{COMMA}{NBSP}crât +STR_COLOUR_DEFAULT :Rhagosodiad ###length 17 STR_COLOUR_DARK_BLUE :Glas Tywyll STR_COLOUR_PALE_GREEN :Gwyrdd Golau @@ -197,6 +198,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp STR_UNITS_POWER_SI :{COMMA}{NBSP}kW + STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg @@ -374,10 +376,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR : STR_SCENEDIT_FILE_MENU_QUIT :Gadael # Settings menu -###length 14 +###length 15 STR_SETTINGS_MENU_GAME_OPTIONS :Dewisiadau Gêm STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Gosodiadau -STR_SETTINGS_MENU_SCRIPT_SETTINGS :Gosodiadau AI / sgript Gêm STR_SETTINGS_MENU_NEWGRF_SETTINGS :Gosodiadau NewGRF STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Dewisiadau tryloywder STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Dangos enwau trefi @@ -927,36 +928,6 @@ STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iran (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Rwbl Rwsaidd Newydd (RUB) STR_GAME_OPTIONS_CURRENCY_CNY :Renminbi Tseina (CNY) -###length 2 -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Gyrru ar y chwith -STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Gyrru ar y dde - -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Enwau Trefi -STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Dewis arddull yr enwau trefi - -###length 21 -STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Saesneg (Gwreiddiol) -STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Ffrangeg -STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Almaeneg -STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Saesneg (Ychwanegol) -STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :America Ladin -STR_GAME_OPTIONS_TOWN_NAME_SILLY :Gwirion -STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Swedaidd -STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Iseldireg -STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Ffinnaidd -STR_GAME_OPTIONS_TOWN_NAME_POLISH :Pwylaidd -STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slofacaidd -STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norwyaidd -STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hwngaraidd -STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Awstriaidd -STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Rwmaniaidd -STR_GAME_OPTIONS_TOWN_NAME_CZECH :Tsecaidd -STR_GAME_OPTIONS_TOWN_NAME_SWISS :Swisaidd -STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danaidd -STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Twrcaidd -STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Eidalaidd -STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalanaidd - STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Awtogadw STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Dewiswch pa mor aml y dylid awtogadw gemau @@ -981,12 +952,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :arall -STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Maint rhyngwyneb -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Dewis maint yr elfennau rhyngwyneb i'w defnyddio - -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Arferol -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dyblyg -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Pedwarplyg @@ -1035,8 +1000,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Rhagolw STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Punt (£) yn eich arian cyfaddas STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Newid paramedrau arian cyfaddas -STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Uchafswm nifer y cystadleuwyr: {ORANGE}{COMMA} - STR_NONE :Dim STR_FUNDING_ONLY :Ariannu'n unig STR_MINIMAL :Lleiafsymol @@ -1086,6 +1049,12 @@ STR_SUBSIDY_X2 :x2 STR_SUBSIDY_X3 :x3 STR_SUBSIDY_X4 :x4 +###length 4 +STR_CLIMATE_TEMPERATE_LANDSCAPE :Tirwedd Tymherus +STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Tirwedd Is-arctig +STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Tirwedd trofannol +STR_CLIMATE_TOYLAND_LANDSCAPE :Tirwedd Teganau + ###length 7 STR_TERRAIN_TYPE_VERY_FLAT :Gwastad Iawn STR_TERRAIN_TYPE_FLAT :Gwastad @@ -1159,6 +1128,7 @@ STR_CONFIG_SETTING_HORIZONTAL_POS_RIGHT :De STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN :Benthyciad agoriadol uchafsymol: {STRING} STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Y swm uchaf y gall cwmni fenthyca (heb ustyried chwyddiant) +###setting-zero-is-special STR_CONFIG_SETTING_INTEREST_RATE :Cyfradd chwyddiant: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Cyfradd chwyddiant y benthyciad; hefyd chwyddiant yr economi os y galluogir @@ -1323,6 +1293,7 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Nid yw'n STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Cynnal a chadw tanadeiledd: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Pan fo wedi'i alluogi, mae tanadeiledd yn creu costau cynnal a chadw. Mae'r cost yn codi'n gyflymach na'i gyfradd gyda thŵf y rhwydwaith, gan effeithio'n fwy ar gwmniau mawr na rhai bychan +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Dewiswch liw dechreuol am y cwmni STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Maes awyr ddim yn dibennu: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Mae galluogi'r dewis yma'n peri i bob math o faes awyr aros ar gael am byth wedi ei gyflwyniad gyntaf @@ -1419,6 +1390,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Gwell STR_CONFIG_SETTING_ROAD_SIDE :Cerbydau ffordd: {STRING} STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Dewis yr ochr gyrru +###length 2 +STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Gyrru ar y chwith +STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Gyrru ar y dde + STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Tro Map Uchder: {STRING} ###length 2 STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Gwrthglocwedd @@ -1896,7 +1871,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Troi'n ôl yn a STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Caniatáu i drenau gwrthdroi wrth signal, os ydynt wedi aros yno am beth amser ###length 2 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF -STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Argymellir) +STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Argymellir) STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Newid gwerth gosodiad @@ -1921,6 +1896,7 @@ STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}Allan o STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}Methwyd dyroddi {BYTES} o storfa corluniau. Lleihawyd y storfa corluniau at {BYTES}. Bydd hyn yn lleihau perfformiad OpenTTD. I leihau gofynion cof gallwch roi cynnig ar analluogi graffigiau 32 did a/neu lefelau mwyháu # Video initalization errors +STR_VIDEO_DRIVER_ERROR :{WHITE}Gwall gyda'r gosodiadau fideo... # Intro window STR_INTRO_CAPTION :{WHITE}OpenTTD {REV} @@ -1937,7 +1913,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Tabl Sg STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Gosodiadau STR_INTRO_NEWGRF_SETTINGS :{BLACK}Gosodiadau NewGRF STR_INTRO_ONLINE_CONTENT :{BLACK}Gwirio Cynnwys Ar-lein -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Gosodiadau AI / Sgript Gêm STR_INTRO_QUIT :{BLACK}Gadael STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Dechrau gêm newydd. Mae Ctrl+Clic yn hepgor dewisiadau map @@ -1957,7 +1932,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Dangos y STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Gosodiadau arddangos STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Dangos gosodiadau NewGRF STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Gwirio am gynnwys newydd neu wedi'i ddiweddaru i'w lwytho i lawr -STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Dangos gosodiadau AI a sgript Gêm STR_INTRO_TOOLTIP_QUIT :{BLACK}Gadael 'OpenTTD' STR_INTRO_BASESET :{BLACK}Mae {NUM} corlun ar goll o'r set raffeg sylfaenol a ddewiswyd. Gwiriwch am ddiweddariadau i'r set raffeg. @@ -1987,12 +1961,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Newid d STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Newid y flwyddyn bresennol STR_CHEAT_SETUP_PROD :{LTBLUE}Galluogi newid graddfeydd cynhyrchu: {ORANGE}{STRING} -###length 4 -STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Tirwedd Tymherus -STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Tirwedd Is-arctig -STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Tirwedd trofannol -STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Tirwedd Teganau - # Livery window STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Cynllun Lliw @@ -2182,6 +2150,7 @@ STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Mae'r cw STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Rhestr Cleientiaid # Network client list +STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Anfon neges i bob gwyliwr # Matches ConnectionType ###length 5 @@ -2391,6 +2360,8 @@ STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLACK}dirlawn STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}gorlwythiedig +# Linkgraph tooltip + # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Amlygu ardal ddylanwad STR_STATION_BUILD_COVERAGE_OFF :{BLACK}I Ffwrdd @@ -2479,8 +2450,6 @@ STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Cynyddu STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Dewiswch Bont Rheilffordd STR_SELECT_ROAD_BRIDGE_CAPTION :{WHITE}Dewiswch Bont Ffordd STR_SELECT_BRIDGE_SELECTION_TOOLTIP :{BLACK}Dewis pont - cliciwch ar y eich dewis i'w hadeiladu -STR_SELECT_BRIDGE_INFO :{GOLD}{STRING},{} {VELOCITY} {WHITE}{CURRENCY_LONG} -STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING},{} {VELOCITY} STR_BRIDGE_NAME_SUSPENSION_STEEL :Crog, Dur STR_BRIDGE_NAME_GIRDER_STEEL :Hytrawst, Dur STR_BRIDGE_NAME_CANTILEVER_STEEL :Canttilifer, Dur @@ -2797,6 +2766,7 @@ STR_ABOUT_VERSION :{BLACK}fersiwn STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-{STRING} Y tîm OpenTTD # Framerate display window +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Nifer y ticiau gêm a efelychir bob eiliad. STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Nifer o fframiau fideo a lunir bob eiliad. STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Pa mor gyflym mae'r gêm yn rhedeg, o gymharu a'r cyflymder i'w ddisgwyl ar gyfradd efelychu arferol. @@ -2805,6 +2775,7 @@ STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMA ###length 15 STR_FRAMERATE_GL_ECONOMY :{BLACK} Trin cargo: +STR_FRAMERATE_VIDEO :{BLACK}Allbwn fideo: ###length 15 STR_FRAMETIME_CAPTION_VIDEO :Allbwn fideo @@ -2842,16 +2813,40 @@ STR_MAPGEN_MAPSIZE :{BLACK}Maint Ma STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Dewis maint y map mewn teiliau. Bydd y nifer o deiliau sydd ara gael ychydig yn llai STR_MAPGEN_BY :{BLACK}* STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Nifer trefi: +STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Enwau Trefi +STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Dewis arddull yr enwau trefi STR_MAPGEN_DATE :{BLACK}Dyddiad: STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Nifer diwydiannau: -STR_MAPGEN_LAND_GENERATOR :{BLACK}Cynhyrchydd Tir: STR_MAPGEN_TERRAIN_TYPE :{BLACK}Math Tirwedd: -STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Lefel y Môr: +STR_MAPGEN_SEA_LEVEL :{BLACK}Lefel y Môr: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Afonydd: STR_MAPGEN_SMOOTHNESS :{BLACK}Llyfnder: STR_MAPGEN_VARIETY :{BLACK}Dosbarthiad amrywiaeth: STR_MAPGEN_GENERATE :{WHITE}Cynhyrchu +###length 21 +STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Saesneg (Gwreiddiol) +STR_MAPGEN_TOWN_NAME_FRENCH :Ffrangeg +STR_MAPGEN_TOWN_NAME_GERMAN :Almaeneg +STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Saesneg (Ychwanegol) +STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :America Ladin +STR_MAPGEN_TOWN_NAME_SILLY :Gwirion +STR_MAPGEN_TOWN_NAME_SWEDISH :Swedaidd +STR_MAPGEN_TOWN_NAME_DUTCH :Iseldireg +STR_MAPGEN_TOWN_NAME_FINNISH :Ffinnaidd +STR_MAPGEN_TOWN_NAME_POLISH :Pwylaidd +STR_MAPGEN_TOWN_NAME_SLOVAK :Slofacaidd +STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norwyaidd +STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hwngaraidd +STR_MAPGEN_TOWN_NAME_AUSTRIAN :Awstriaidd +STR_MAPGEN_TOWN_NAME_ROMANIAN :Rwmaniaidd +STR_MAPGEN_TOWN_NAME_CZECH :Tsecaidd +STR_MAPGEN_TOWN_NAME_SWISS :Swisaidd +STR_MAPGEN_TOWN_NAME_DANISH :Danaidd +STR_MAPGEN_TOWN_NAME_TURKISH :Twrcaidd +STR_MAPGEN_TOWN_NAME_ITALIAN :Eidalaidd +STR_MAPGEN_TOWN_NAME_CATALAN :Catalanaidd + # Strings for map borders at game generation STR_MAPGEN_BORDER_TYPE :{BLACK}Ymylon mapiau: STR_MAPGEN_NORTHWEST :{BLACK}Gog. Orllewin @@ -2987,6 +2982,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Corlun b STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Mynd i'r corlun cyffredin blaenorol, gan hepgor unrhyw gorluniau ailliwio/ffont/llidgorluniau, ac amlapio o'r corlun cyntaf i'r olaf STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Cynrychioliad o'r corlun a ddewiswyd. Fe anwybyddir yr aliniad wrth lunio'r corlun STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Symud y corlun, gan newid yr atredau X ac Y. Mae Ctrl+Clic yn symud y corlun wyth uned ar y tro + +###length 2 + + STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Ailosod perthyniad STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Ailosod y dodiadau perthynol STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Dodiad X: {NUM}, Dodiad Y: {NUM} (Absoliwt) @@ -3001,7 +3000,6 @@ STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING STR_NEWGRF_ERROR_MSG_WARNING :{RED}Rhybudd: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_ERROR :{RED}Gwall: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Angheuol: {SILVER}{STRING} -STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Mae gwall angheuol NewGRF wedi digwydd:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :Ni fydd {1:STRING} yn gweithio gyda'r fersiwn o TTDPatch yr adroddir gan OpenTTD STR_NEWGRF_ERROR_DOS_OR_WINDOWS :Mae {1:STRING} ar gyfer y fersiwn {STRING} o TTD STR_NEWGRF_ERROR_UNSET_SWITCH :Mae {1:STRING} wedi ei gynllunio i gael ei ddefnyddio gyda {STRING} @@ -3344,6 +3342,7 @@ STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}Ail-leol STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Ailadeiladu pencadlys cwmni mewn man arall am 1% o werth y cwmni. Mae Shift+Clic yn dangos amcangyfrif o'r gost heb adleoli STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}Manylion STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}Gweld cyfansymau tanadeiledd manwl +STR_COMPANY_VIEW_GIVE_MONEY_BUTTON :{BLACK}Rhoi arian STR_COMPANY_VIEW_NEW_FACE_BUTTON :{BLACK}Gwyneb Newydd STR_COMPANY_VIEW_NEW_FACE_TOOLTIP :{BLACK}Dewiswch wyneb newydd ar gyfer y rheolwr @@ -3504,6 +3503,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Grym Tyn STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Pellter cyrhaeddiad: {GOLD}{COMMA} teil STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Math awyren: {GOLD}{STRING} +###length 3 + ###length VEHICLE_TYPES STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Rhestr dewis trenau. Cliciwch ar gerbyd am wybodaeth. Mae Ctrl+Clicio'n toglu cuddio'r math cerbyd STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Rhestr dewis cerbydau ffordd. Cliciwch ar gerbyd am wybodaeth. Mae Ctrl+Clicio'n toglu cuddio'r math cerbyd @@ -3995,6 +3996,7 @@ STR_ORDER_REFIT_STOP_ORDER :(Ailfitio i {ST STR_ORDER_STOP_ORDER :(Stopio) STR_ORDER_GO_TO_STATION :{STRING} {STATION} {STRING} +STR_ORDER_GO_TO_STATION_CAN_T_USE_STATION :{PUSH_COLOUR}{RED}(Methu defnyddio gorsaf){POP_COLOUR} {STRING} {STATION} {STRING} STR_ORDER_IMPLICIT :(Ymhlyg) @@ -4136,12 +4138,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Mae sgri STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Mae'r Ffenestr Ddadnamu AI / Sgript Gêm ar gael ar gyfer y gweinydd yn unig # AI configuration window -STR_AI_CONFIG_CAPTION :{WHITE}Ffurfweddiad AI / Sgript Gêm STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Y Sgriptiau Gêm a lwythir yn y gêm nesaf STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Yr AIau a lwythir yn y gêm nesaf STR_AI_CONFIG_HUMAN_PLAYER :Chwaraewr dynol STR_AI_CONFIG_RANDOM_AI :AI ar hap STR_AI_CONFIG_NONE :(dim) +STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Uchafswm nifer y cystadleuwyr: {ORANGE}{COMMA} STR_AI_CONFIG_MOVE_UP :{BLACK}Symud i Fyny STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Symud yr AI a ddewiswyd i fyny'r rhestr @@ -4151,8 +4153,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Symud yr STR_AI_CONFIG_GAMESCRIPT :{SILVER}Sgript Gêm STR_AI_CONFIG_AI :{SILVER}AIau -STR_AI_CONFIG_CHANGE :{BLACK}Dewis {STRING} -STR_AI_CONFIG_CHANGE_NONE : STR_AI_CONFIG_CHANGE_AI :AI STR_AI_CONFIG_CHANGE_GAMESCRIPT :Sgript Gêm STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Llwytho sgript arall @@ -4175,10 +4175,8 @@ STR_AI_LIST_CANCEL :{BLACK}Canslo STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Peidio newid y sgript -# AI Parameters -STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Paramedrau +# Script Parameters STR_AI_SETTINGS_CAPTION_AI :AI -STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Sgript Gêm STR_AI_SETTINGS_CLOSE :{BLACK}Cau STR_AI_SETTINGS_RESET :{BLACK}Ailosod STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} @@ -4585,6 +4583,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Methu ne STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... cerbyd wedi ei ddinistrio + STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Ni fydd cerbydau ar gael o gwbl STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Newid eich ffurfweddiad NewGRF STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Dim cerbydau ar gael eto @@ -4618,6 +4617,8 @@ STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Does dim STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... rhy bell o'r gyrchfan flaenorol STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... nid yw o fewn cyrraedd yr awyren +# Extra messages which go on the third line of errors, explaining why orders failed + # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Methu amserlennu cerbyd... STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}Dim ond mewn gorsafoedd y gall cerbydau aros diff --git a/src/league_base.h b/src/league_base.h new file mode 100644 index 0000000000000..6195d2c3ee4c6 --- /dev/null +++ b/src/league_base.h @@ -0,0 +1,68 @@ +/* + * 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 league_base.h %LeagueTable base class. */ + +#ifndef LEAGUE_BASE_H +#define LEAGUE_BASE_H + +#include "company_type.h" +#include "goal_type.h" +#include "league_type.h" +#include "core/pool_type.hpp" + +bool IsValidLink(Link link); + +typedef Pool LeagueTableElementPool; +extern LeagueTableElementPool _league_table_element_pool; + +typedef Pool LeagueTablePool; +extern LeagueTablePool _league_table_pool; + + +/** + * Struct about league table elements. + * Each LeagueTable is composed of one or more elements. Elements are sorted by their rating (higher=better). + **/ +struct LeagueTableElement : LeagueTableElementPool::PoolItem<&_league_table_element_pool> { + LeagueTableID table; ///< Id of the table which this element belongs to + int64 rating; ///< Value that determines ordering of elements in the table (higher=better) + CompanyID company; ///< Company Id to show the color blob for or INVALID_COMPANY + std::string text; ///< Text of the element + std::string score; ///< String representation of the score associated with the element + Link link; ///< What opens when element is clicked + + /** + * We need an (empty) constructor so struct isn't zeroed (as C++ standard states) + */ + LeagueTableElement() { } + + /** + * (Empty) destructor has to be defined else operator delete might be called with nullptr parameter + */ + ~LeagueTableElement() { } +}; + + +/** Struct about custom league tables */ +struct LeagueTable : LeagueTablePool::PoolItem<&_league_table_pool> { + std::string title; ///< Title of the table + std::string header; ///< Text to show above the table + std::string footer; ///< Text to show below the table + + /** + * We need an (empty) constructor so struct isn't zeroed (as C++ standard states) + */ + LeagueTable() { } + + /** + * (Empty) destructor has to be defined else operator delete might be called with nullptr parameter + */ + ~LeagueTable() { } +}; + +#endif /* LEAGUE_BASE_H */ diff --git a/src/league_cmd.cpp b/src/league_cmd.cpp new file mode 100644 index 0000000000000..6e715fd03025b --- /dev/null +++ b/src/league_cmd.cpp @@ -0,0 +1,176 @@ +/* + * 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 league_cmd.cpp Handling of league tables. */ + +#include "stdafx.h" +#include "league_cmd.h" +#include "league_base.h" +#include "command_type.h" +#include "command_func.h" +#include "industry.h" +#include "story_base.h" +#include "town.h" +#include "window_func.h" +#include "core/pool_func.hpp" + +#include "safeguards.h" + +LeagueTableElementPool _league_table_element_pool("LeagueTableElement"); +INSTANTIATE_POOL_METHODS(LeagueTableElement) + +LeagueTablePool _league_table_pool("LeagueTable"); +INSTANTIATE_POOL_METHODS(LeagueTable) + +/** + * Checks whether a link is valid, i.e. has a valid target. + * @param link the link to check + * @return true iff the link is valid + */ +bool IsValidLink(Link link) +{ + switch (link.type) { + case LT_NONE: return (link.target == 0); + case LT_TILE: return IsValidTile(link.target); + case LT_INDUSTRY: return Industry::IsValidID(link.target); + case LT_TOWN: return Town::IsValidID(link.target); + case LT_COMPANY: return Company::IsValidID(link.target); + case LT_STORY_PAGE: return StoryPage::IsValidID(link.target); + default: return false; + } + return false; +} + +/** + * Create a new league table. + * @param flags type of operation + * @param title Title of the league table + * @param header Text to show above the table + * @param footer Text to show below the table + * @return the cost of this operation or an error + */ +std::tuple CmdCreateLeagueTable(DoCommandFlag flags, const std::string &title, const std::string &header, const std::string &footer) +{ + if (_current_company != OWNER_DEITY) return { CMD_ERROR, INVALID_LEAGUE_TABLE }; + if (!LeagueTable::CanAllocateItem()) return { CMD_ERROR, INVALID_LEAGUE_TABLE }; + if (title.empty()) return { CMD_ERROR, INVALID_LEAGUE_TABLE }; + + if (flags & DC_EXEC) { + LeagueTable *lt = new LeagueTable(); + lt->title = title; + lt->header = header; + lt->footer = footer; + return { CommandCost(), lt->index }; + } + + return { CommandCost(), INVALID_LEAGUE_TABLE }; +} + + +/** + * Create a new element in a league table. + * @param flags type of operation + * @param table Id of the league table this element belongs to + * @param rating Value that elements are ordered by + * @param company Company to show the color blob for or INVALID_COMPANY + * @param text Text of the element + * @param score String representation of the score associated with the element + * @param link_type Type of the referenced object + * @param link_target Id of the referenced object + * @return the cost of this operation or an error + */ +std::tuple CmdCreateLeagueTableElement(DoCommandFlag flags, LeagueTableID table, int64 rating, CompanyID company, const std::string &text, const std::string &score, LinkType link_type, LinkTargetID link_target) +{ + if (_current_company != OWNER_DEITY) return { CMD_ERROR, INVALID_LEAGUE_TABLE_ELEMENT }; + if (!LeagueTableElement::CanAllocateItem()) return { CMD_ERROR, INVALID_LEAGUE_TABLE_ELEMENT }; + Link link{link_type, link_target}; + if (!IsValidLink(link)) return { CMD_ERROR, INVALID_LEAGUE_TABLE_ELEMENT }; + if (company != INVALID_COMPANY && !Company::IsValidID(company)) return { CMD_ERROR, INVALID_LEAGUE_TABLE_ELEMENT }; + + if (flags & DC_EXEC) { + LeagueTableElement *lte = new LeagueTableElement(); + lte->table = table; + lte->rating = rating; + lte->company = company; + lte->text = text; + lte->score = score; + lte->link = link; + InvalidateWindowData(WC_COMPANY_LEAGUE, table); + return { CommandCost(), lte->index }; + } + return { CommandCost(), INVALID_LEAGUE_TABLE_ELEMENT }; +} + +/** + * Update the attributes of a league table element. + * @param flags type of operation + * @param element Id of the element to update + * @param company Company to show the color blob for or INVALID_COMPANY + * @param text Text of the element + * @param link_type Type of the referenced object + * @param link_target Id of the referenced object + * @return the cost of this operation or an error + */ +CommandCost CmdUpdateLeagueTableElementData(DoCommandFlag flags, LeagueTableElementID element, CompanyID company, const std::string &text, LinkType link_type, LinkTargetID link_target) +{ + if (_current_company != OWNER_DEITY) return CMD_ERROR; + auto lte = LeagueTableElement::GetIfValid(element); + if (lte == nullptr) return CMD_ERROR; + if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR; + Link link{link_type, link_target}; + if (!IsValidLink(link)) return CMD_ERROR; + + if (flags & DC_EXEC) { + lte->company = company; + lte->text = text; + lte->link = link; + InvalidateWindowData(WC_COMPANY_LEAGUE, lte->table); + } + return CommandCost(); +} + +/** + * Update the score of a league table element. + * @param flags type of operation + * @param element Id of the element to update + * @param rating Value that elements are ordered by + * @param score String representation of the score associated with the element + * @return the cost of this operation or an error + */ +CommandCost CmdUpdateLeagueTableElementScore(DoCommandFlag flags, LeagueTableElementID element, int64 rating, const std::string &score) +{ + if (_current_company != OWNER_DEITY) return CMD_ERROR; + auto lte = LeagueTableElement::GetIfValid(element); + if (lte == nullptr) return CMD_ERROR; + + if (flags & DC_EXEC) { + lte->rating = rating; + lte->score = score; + InvalidateWindowData(WC_COMPANY_LEAGUE, lte->table); + } + return CommandCost(); +} + +/** + * Remove a league table element. + * @param flags type of operation + * @param element Id of the element to update + * @return the cost of this operation or an error + */ +CommandCost CmdRemoveLeagueTableElement(DoCommandFlag flags, LeagueTableElementID element) +{ + if (_current_company != OWNER_DEITY) return CMD_ERROR; + auto lte = LeagueTableElement::GetIfValid(element); + if (lte == nullptr) return CMD_ERROR; + + if (flags & DC_EXEC) { + auto table = lte->table; + delete lte; + InvalidateWindowData(WC_COMPANY_LEAGUE, table); + } + return CommandCost(); +} diff --git a/src/league_cmd.h b/src/league_cmd.h new file mode 100644 index 0000000000000..39adb4aee470a --- /dev/null +++ b/src/league_cmd.h @@ -0,0 +1,29 @@ +/* + * 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 league_cmd.h Command definitions related to league tables. */ + +#ifndef LEAGUE_CMD_H +#define LEAGUE_CMD_H + +#include "league_type.h" +#include "command_type.h" +#include "company_type.h" + +std::tuple CmdCreateLeagueTable(DoCommandFlag flags, const std::string &title, const std::string &header, const std::string &footer); +std::tuple CmdCreateLeagueTableElement(DoCommandFlag flags, LeagueTableID table, int64 rating, CompanyID company, const std::string &text, const std::string &score, LinkType link_type, LinkTargetID link_target); +CommandCost CmdUpdateLeagueTableElementData(DoCommandFlag flags, LeagueTableElementID element, CompanyID company, const std::string &text, LinkType link_type, LinkTargetID link_target); +CommandCost CmdUpdateLeagueTableElementScore(DoCommandFlag flags, LeagueTableElementID element, int64 rating, const std::string &score); +CommandCost CmdRemoveLeagueTableElement(DoCommandFlag flags, LeagueTableElementID element); + +DEF_CMD_TRAIT(CMD_CREATE_LEAGUE_TABLE, CmdCreateLeagueTable, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CREATE_LEAGUE_TABLE_ELEMENT, CmdCreateLeagueTableElement, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_UPDATE_LEAGUE_TABLE_ELEMENT_DATA, CmdUpdateLeagueTableElementData, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_UPDATE_LEAGUE_TABLE_ELEMENT_SCORE, CmdUpdateLeagueTableElementScore, CMD_DEITY | CMD_STR_CTRL, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_REMOVE_LEAGUE_TABLE_ELEMENT, CmdRemoveLeagueTableElement, CMD_DEITY, CMDT_OTHER_MANAGEMENT) + +#endif /* LEAGUE_CMD_H */ diff --git a/src/league_gui.cpp b/src/league_gui.cpp new file mode 100644 index 0000000000000..a46cd2efa6bb6 --- /dev/null +++ b/src/league_gui.cpp @@ -0,0 +1,452 @@ +/* + * 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 league_gui.cpp GUI for league tables. */ + +#include "stdafx.h" +#include "league_gui.h" + +#include "company_base.h" +#include "company_gui.h" +#include "gui.h" +#include "industry.h" +#include "league_base.h" +#include "sortlist_type.h" +#include "story_base.h" +#include "strings_func.h" +#include "tile_map.h" +#include "town.h" +#include "viewport_func.h" +#include "window_gui.h" +#include "widgets/league_widget.h" +#include "table/strings.h" +#include "table/sprites.h" + +#include "safeguards.h" + + +static const StringID _performance_titles[] = { + STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ENGINEER, + STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ENGINEER, + STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRAFFIC_MANAGER, + STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRAFFIC_MANAGER, + STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRANSPORT_COORDINATOR, + STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRANSPORT_COORDINATOR, + STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ROUTE_SUPERVISOR, + STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ROUTE_SUPERVISOR, + STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_DIRECTOR, + STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_DIRECTOR, + STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_CHIEF_EXECUTIVE, + 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, +}; + +static inline StringID GetPerformanceTitleFromValue(uint value) +{ + return _performance_titles[std::min(value, 1000u) >> 6]; +} + +class PerformanceLeagueWindow : public Window { +private: + GUIList companies; + uint ordinal_width; ///< The width of the ordinal number + uint text_width; ///< The width of the actual text + int line_height; ///< Height of the text lines + Dimension icon; ///< Dimension of the company icon. + + /** + * (Re)Build the company league list + */ + void BuildCompanyList() + { + if (!this->companies.NeedRebuild()) return; + + this->companies.clear(); + + for (const Company *c : Company::Iterate()) { + this->companies.push_back(c); + } + + this->companies.shrink_to_fit(); + this->companies.RebuildDone(); + } + + /** Sort the company league by performance history */ + static bool PerformanceSorter(const Company * const &c1, const Company * const &c2) + { + return c2->old_economy[0].performance_history < c1->old_economy[0].performance_history; + } + +public: + PerformanceLeagueWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc) + { + this->InitNested(window_number); + this->companies.ForceRebuild(); + this->companies.NeedResort(); + } + + void OnPaint() override + { + this->BuildCompanyList(); + this->companies.Sort(&PerformanceSorter); + + this->DrawWidgets(); + } + + void DrawWidget(const Rect &r, int widget) const override + { + if (widget != WID_PLT_BACKGROUND) return; + + Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); + int icon_y_offset = (this->line_height - this->icon.height) / 2; + int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; + + bool rtl = _current_text_dir == TD_RTL; + Rect ordinal = ir.WithWidth(this->ordinal_width, rtl); + uint icon_left = ir.Indent(rtl ? this->text_width : this->ordinal_width, rtl).left; + Rect text = ir.WithWidth(this->text_width, !rtl); + + for (uint i = 0; i != this->companies.size(); i++) { + const Company *c = this->companies[i]; + DrawString(ordinal.left, ordinal.right, ir.top + text_y_offset, i + STR_ORDINAL_NUMBER_1ST, i == 0 ? TC_WHITE : TC_YELLOW); + + DrawCompanyIcon(c->index, icon_left, ir.top + icon_y_offset); + + SetDParam(0, c->index); + SetDParam(1, c->index); + SetDParam(2, GetPerformanceTitleFromValue(c->old_economy[0].performance_history)); + DrawString(text.left, text.right, ir.top + text_y_offset, STR_COMPANY_LEAGUE_COMPANY_NAME); + ir.top += this->line_height; + } + } + + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override + { + if (widget != WID_PLT_BACKGROUND) return; + + this->ordinal_width = 0; + for (uint i = 0; i < MAX_COMPANIES; i++) { + this->ordinal_width = std::max(this->ordinal_width, GetStringBoundingBox(STR_ORDINAL_NUMBER_1ST + i).width); + } + this->ordinal_width += WidgetDimensions::scaled.hsep_wide; // Keep some extra spacing + + uint widest_width = 0; + uint widest_title = 0; + for (uint i = 0; i < lengthof(_performance_titles); i++) { + uint width = GetStringBoundingBox(_performance_titles[i]).width; + if (width > widest_width) { + widest_title = i; + widest_width = width; + } + } + + this->icon = GetSpriteSize(SPR_COMPANY_ICON); + this->line_height = std::max(this->icon.height + WidgetDimensions::scaled.vsep_normal, FONT_HEIGHT_NORMAL); + + for (const Company *c : Company::Iterate()) { + SetDParam(0, c->index); + SetDParam(1, c->index); + SetDParam(2, _performance_titles[widest_title]); + widest_width = std::max(widest_width, GetStringBoundingBox(STR_COMPANY_LEAGUE_COMPANY_NAME).width); + } + + this->text_width = widest_width + WidgetDimensions::scaled.hsep_indent * 3; // Keep some extra spacing + + size->width = WidgetDimensions::scaled.framerect.Horizontal() + this->ordinal_width + this->icon.width + this->text_width + WidgetDimensions::scaled.hsep_wide; + size->height = this->line_height * MAX_COMPANIES + WidgetDimensions::scaled.framerect.Vertical(); + } + + void OnGameTick() override + { + if (this->companies.NeedResort()) { + this->SetDirty(); + } + } + + /** + * Some data on this window has become invalid. + * @param data Information about the changed data. + * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. + */ + void OnInvalidateData(int data = 0, bool gui_scope = true) override + { + if (data == 0) { + /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */ + this->companies.ForceRebuild(); + } else { + this->companies.ForceResort(); + } + } +}; + +static const NWidgetPart _nested_performance_league_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_BROWN), + NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_COMPANY_LEAGUE_TABLE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_SHADEBOX, COLOUR_BROWN), + NWidget(WWT_STICKYBOX, COLOUR_BROWN), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_BROWN, WID_PLT_BACKGROUND), SetMinimalSize(400, 0), SetMinimalTextLines(15, WidgetDimensions::unscaled.framerect.Vertical()), +}; + +static WindowDesc _performance_league_desc( + WDP_AUTO, "league", 0, 0, + WC_COMPANY_LEAGUE, WC_NONE, + 0, + _nested_performance_league_widgets, lengthof(_nested_performance_league_widgets) +); + +void ShowPerformanceLeagueTable() +{ + AllocateWindowDescFront(&_performance_league_desc, 0); +} + +static void HandleLinkClick(Link link) +{ + TileIndex xy; + switch (link.type) { + case LT_NONE: return; + + case LT_TILE: + if (!IsValidTile(link.target)) return; + xy = link.target; + break; + + case LT_INDUSTRY: + if (!Industry::IsValidID(link.target)) return; + xy = Industry::Get(link.target)->location.tile; + break; + + case LT_TOWN: + if (!Town::IsValidID(link.target)) return; + xy = Town::Get(link.target)->xy; + break; + + case LT_COMPANY: + ShowCompany((CompanyID)link.target); + return; + + case LT_STORY_PAGE: { + if (!StoryPage::IsValidID(link.target)) return; + CompanyID story_company = StoryPage::Get(link.target)->company; + ShowStoryBook(story_company, link.target); + return; + } + + default: NOT_REACHED(); + } + + if (_ctrl_pressed) { + ShowExtraViewportWindow(xy); + } else { + ScrollMainWindowToTile(xy); + } +} + + +class ScriptLeagueWindow : public Window { +private: + LeagueTableID table; + std::vector> rows; + uint rank_width; ///< The width of the rank ordinal + uint text_width; ///< The width of the actual text + uint score_width; ///< The width of the score text + uint header_height; ///< Height of the table header + int line_height; ///< Height of the text lines + Dimension icon_size; ///< Dimenion of the company icon. + std::string title; + + /** + * Rebuild the company league list + */ + void BuildTable() + { + this->rows.clear(); + this->title = std::string{}; + auto lt = LeagueTable::GetIfValid(this->table); + if (lt == nullptr) return; + + /* We store title in the window class so we can safely reference the string later */ + this->title = lt->title; + + std::vector elements; + for(LeagueTableElement *lte : LeagueTableElement::Iterate()) { + if (lte->table == this->table) { + elements.push_back(lte); + } + } + std::sort(elements.begin(), elements.end(), [](auto a, auto b) { return a->rating > b->rating; }); + + /* Calculate rank, companies with the same rating share the ranks */ + uint rank = 0; + for (uint i = 0; i != elements.size(); i++) { + auto *lte = elements[i]; + if (i > 0 && elements[i - 1]->rating != lte->rating) rank = i; + this->rows.emplace_back(std::make_pair(rank, lte)); + } + } + +public: + ScriptLeagueWindow(WindowDesc *desc, LeagueTableID table) : Window(desc) + { + this->table = table; + this->BuildTable(); + this->InitNested(table); + } + + void SetStringParameters(int widget) const override + { + if (widget != WID_SLT_CAPTION) return; + SetDParamStr(0, this->title); + } + + void OnPaint() override + { + this->DrawWidgets(); + } + + void DrawWidget(const Rect &r, int widget) const override + { + if (widget != WID_SLT_BACKGROUND) return; + + auto lt = LeagueTable::GetIfValid(this->table); + if (lt == nullptr) return; + + Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); + + if (!lt->header.empty()) { + SetDParamStr(0, lt->header); + ir.top = DrawStringMultiLine(ir.left, ir.right, ir.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK) + WidgetDimensions::scaled.vsep_wide; + } + + int icon_y_offset = (this->line_height - this->icon_size.height) / 2; + int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; + + /* Calculate positions.of the columns */ + bool rtl = _current_text_dir == TD_RTL; + int spacer = WidgetDimensions::scaled.hsep_wide; + Rect rank_rect = ir.WithWidth(this->rank_width, rtl); + Rect icon_rect = ir.Indent(this->rank_width + (rtl ? 0 : spacer), rtl).WithWidth(this->icon_size.width, rtl); + Rect text_rect = ir.Indent(this->rank_width + spacer + this->icon_size.width, rtl).WithWidth(this->text_width, rtl); + Rect score_rect = ir.Indent(this->rank_width + 2 * spacer + this->icon_size.width + this->text_width, rtl).WithWidth(this->score_width, rtl); + + for (auto [rank, lte] : this->rows) { + DrawString(rank_rect.left, rank_rect.right, ir.top + text_y_offset, rank + STR_ORDINAL_NUMBER_1ST, rank == 0 ? TC_WHITE : TC_YELLOW); + if (this->icon_size.width > 0 && lte->company != INVALID_COMPANY) DrawCompanyIcon(lte->company, icon_rect.left, ir.top + icon_y_offset); + SetDParamStr(0, lte->text); + DrawString(text_rect.left, text_rect.right, ir.top + text_y_offset, STR_JUST_RAW_STRING, TC_BLACK); + SetDParamStr(0, lte->score); + DrawString(score_rect.left, score_rect.right, ir.top + text_y_offset, STR_JUST_RAW_STRING, TC_BLACK, SA_RIGHT); + ir.top += this->line_height; + } + + if (!lt->footer.empty()) { + ir.top += WidgetDimensions::scaled.vsep_wide; + SetDParamStr(0, lt->footer); + ir.top = DrawStringMultiLine(ir.left, ir.right, ir.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); + } + } + + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override + { + if (widget != WID_SLT_BACKGROUND) return; + + auto lt = LeagueTable::GetIfValid(this->table); + if (lt == nullptr) return; + + this->icon_size = GetSpriteSize(SPR_COMPANY_ICON); + this->line_height = std::max(this->icon_size.height + WidgetDimensions::scaled.fullbevel.Vertical(), FONT_HEIGHT_NORMAL); + + /* Calculate maximum width of every column */ + this->rank_width = this->text_width = this->score_width = 0; + bool show_icon_column = false; + for (auto [rank, lte] : this->rows) { + this->rank_width = std::max(this->rank_width, GetStringBoundingBox(STR_ORDINAL_NUMBER_1ST + rank).width); + SetDParamStr(0, lte->text); + this->text_width = std::max(this->text_width, GetStringBoundingBox(STR_JUST_RAW_STRING).width); + SetDParamStr(0, lte->score); + this->score_width = std::max(this->score_width, GetStringBoundingBox(STR_JUST_RAW_STRING).width); + if (lte->company != INVALID_COMPANY) show_icon_column = true; + } + + if (!show_icon_column) this->icon_size.width = 0; + else this->icon_size.width += WidgetDimensions::scaled.hsep_wide; + + size->width = this->rank_width + this->icon_size.width + this->text_width + this->score_width + WidgetDimensions::scaled.framerect.Horizontal() + WidgetDimensions::scaled.hsep_wide * 2; + size->height = this->line_height * std::max(3u, (unsigned)this->rows.size()) + WidgetDimensions::scaled.framerect.Vertical(); + + if (!lt->header.empty()) { + SetDParamStr(0, lt->header); + this->header_height = GetStringHeight(STR_JUST_RAW_STRING, size->width - WidgetDimensions::scaled.framerect.Horizontal()) + WidgetDimensions::scaled.vsep_wide; + size->height += header_height; + } else this->header_height = 0; + + if (!lt->footer.empty()) { + SetDParamStr(0, lt->footer); + size->height += GetStringHeight(STR_JUST_RAW_STRING, size->width - WidgetDimensions::scaled.framerect.Horizontal()) + WidgetDimensions::scaled.vsep_wide; + } + } + + void OnClick(Point pt, int widget, int click_count) override + { + if (widget != WID_SLT_BACKGROUND) return; + + auto *wid = this->GetWidget(WID_SLT_BACKGROUND); + int index = (pt.y - WidgetDimensions::scaled.framerect.top - wid->pos_y - this->header_height) / this->line_height; + if (index >= 0 && (uint)index < this->rows.size()) { + auto lte = this->rows[index].second; + HandleLinkClick(lte->link); + } + } + + /** + * Some data on this window has become invalid. + * @param data Information about the changed data. + * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. + */ + void OnInvalidateData(int data = 0, bool gui_scope = true) override + { + this->BuildTable(); + this->ReInit(); + } +}; + +static const NWidgetPart _nested_script_league_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_BROWN), + NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SLT_CAPTION), SetDataTip(STR_BLACK_RAW_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_SHADEBOX, COLOUR_BROWN), + NWidget(WWT_STICKYBOX, COLOUR_BROWN), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_BROWN, WID_SLT_BACKGROUND), SetMinimalSize(400, 0), SetMinimalTextLines(15, WidgetDimensions::scaled.framerect.Vertical()), +}; + +static WindowDesc _script_league_desc( + WDP_AUTO, "league", 0, 0, + WC_COMPANY_LEAGUE, WC_NONE, + 0, + _nested_script_league_widgets, lengthof(_nested_script_league_widgets) +); + +void ShowScriptLeagueTable(LeagueTableID table) +{ + if (!LeagueTable::IsValidID(table)) return; + AllocateWindowDescFront(&_script_league_desc, table); +} + +void ShowFirstLeagueTable() +{ + auto it = LeagueTable::Iterate(); + if (!it.empty()) { + ShowScriptLeagueTable((*it.begin())->index); + } else { + ShowPerformanceLeagueTable(); + } +} diff --git a/src/league_gui.h b/src/league_gui.h new file mode 100644 index 0000000000000..602979f1f6022 --- /dev/null +++ b/src/league_gui.h @@ -0,0 +1,19 @@ +/* + * 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 league_gui.h League table GUI functions. */ + +#ifndef LEAGUE_GUI_H +#define LEAGUE_GUI_H + +#include "league_type.h" + +void ShowPerformanceLeagueTable(); +void ShowScriptLeagueTable(LeagueTableID table); +void ShowFirstLeagueTable(); + +#endif /* LEAGUE_GUI_H */ diff --git a/src/league_type.h b/src/league_type.h new file mode 100644 index 0000000000000..3344bc206e63a --- /dev/null +++ b/src/league_type.h @@ -0,0 +1,40 @@ +/* + * 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 league_type.h basic types related to league tables */ + +#ifndef LEAGUE_TYPE_H +#define LEAGUE_TYPE_H + +/** Types of the possible link targets. */ +enum LinkType : byte { + LT_NONE = 0, ///< No link + LT_TILE = 1, ///< Link a tile + LT_INDUSTRY = 2, ///< Link an industry + LT_TOWN = 3, ///< Link a town + LT_COMPANY = 4, ///< Link a company + LT_STORY_PAGE = 5, ///< Link a story page +}; + +typedef uint32 LinkTargetID; ///< Contains either tile, industry ID, town ID, story page ID or company ID + +struct Link { + LinkType type; + LinkTargetID target; + Link(LinkType type, LinkTargetID target): type{type}, target{target} {} + Link(): Link(LT_NONE, 0) {} +}; + +typedef uint8 LeagueTableID; ///< ID of a league table +struct LeagueTable; +static const LeagueTableID INVALID_LEAGUE_TABLE = 0xFF; ///< Invalid/unknown index of LeagueTable + +typedef uint16 LeagueTableElementID; ///< ID of a league table element +struct LeagueTableElement; +static const LeagueTableElementID INVALID_LEAGUE_TABLE_ELEMENT = 0xFFFF; ///< Invalid/unknown index of LeagueTableElement + +#endif /* LEAGUE_TYPE_H */ diff --git a/src/linkgraph/demands.cpp b/src/linkgraph/demands.cpp index c31e8896f6d35..7d7e182132dbb 100644 --- a/src/linkgraph/demands.cpp +++ b/src/linkgraph/demands.cpp @@ -36,7 +36,7 @@ class SymmetricScaler : public Scaler { */ inline void AddNode(const Node &node) { - this->supply_sum += node.Supply(); + this->supply_sum += node.base.supply; } /** @@ -57,7 +57,7 @@ class SymmetricScaler : public Scaler { */ inline uint EffectiveSupply(const Node &from, const Node &to) { - return std::max(from.Supply() * std::max(1U, to.Supply()) * this->mod_size / 100 / this->demand_per_node, 1U); + return std::max(from.base.supply * std::max(1U, to.base.supply) * this->mod_size / 100 / this->demand_per_node, 1U); } /** @@ -69,7 +69,7 @@ class SymmetricScaler : public Scaler { */ inline bool HasDemandLeft(const Node &to) { - return (to.Supply() == 0 || to.UndeliveredSupply() > 0) && to.Demand() > 0; + return (to.base.supply == 0 || to.undelivered_supply > 0) && to.base.demand > 0; } void SetDemands(LinkGraphJob &job, NodeID from, NodeID to, uint demand_forw); @@ -108,7 +108,7 @@ class AsymmetricScaler : public Scaler { */ inline uint EffectiveSupply(const Node &from, const Node &) { - return from.Supply(); + return from.base.supply; } /** @@ -116,7 +116,7 @@ class AsymmetricScaler : public Scaler { * nodes always accept as long as their demand > 0. * @param to The node to be checked. */ - inline bool HasDemandLeft(const Node &to) { return to.Demand() > 0; } + inline bool HasDemandLeft(const Node &to) { return to.base.demand > 0; } }; /** @@ -129,9 +129,9 @@ class AsymmetricScaler : public Scaler { */ void SymmetricScaler::SetDemands(LinkGraphJob &job, NodeID from_id, NodeID to_id, uint demand_forw) { - if (job[from_id].Demand() > 0) { + if (job[from_id].base.demand > 0) { uint demand_back = demand_forw * this->mod_size / 100; - uint undelivered = job[to_id].UndeliveredSupply(); + uint undelivered = job[to_id].undelivered_supply; if (demand_back > undelivered) { demand_back = undelivered; demand_forw = std::max(1U, demand_back * 100 / this->mod_size); @@ -170,11 +170,11 @@ void DemandCalculator::CalcDemand(LinkGraphJob &job, Tscaler scaler) for (NodeID node = 0; node < job.Size(); node++) { scaler.AddNode(job[node]); - if (job[node].Supply() > 0) { + if (job[node].base.supply > 0) { supplies.push(node); num_supplies++; } - if (job[node].Demand() > 0) { + if (job[node].base.demand > 0) { demands.push(node); num_demands++; } @@ -209,7 +209,7 @@ void DemandCalculator::CalcDemand(LinkGraphJob &job, Tscaler scaler) /* Scale the distance by mod_dist around max_distance */ int32 distance = this->max_distance - (this->max_distance - - (int32)DistanceMaxPlusManhattan(job[from_id].XY(), job[to_id].XY())) * + (int32)DistanceMaxPlusManhattan(job[from_id].base.xy, job[to_id].base.xy)) * this->mod_dist / 100; /* Scale the accuracy by distance around accuracy / 2 */ @@ -230,7 +230,7 @@ void DemandCalculator::CalcDemand(LinkGraphJob &job, Tscaler scaler) demand_forw = 1; } - demand_forw = std::min(demand_forw, job[from_id].UndeliveredSupply()); + demand_forw = std::min(demand_forw, job[from_id].undelivered_supply); scaler.SetDemands(job, from_id, to_id, demand_forw); @@ -240,10 +240,10 @@ void DemandCalculator::CalcDemand(LinkGraphJob &job, Tscaler scaler) num_demands--; } - if (job[from_id].UndeliveredSupply() == 0) break; + if (job[from_id].undelivered_supply == 0) break; } - if (job[from_id].UndeliveredSupply() != 0) { + if (job[from_id].undelivered_supply != 0) { supplies.push(from_id); } else { num_supplies--; @@ -256,7 +256,7 @@ void DemandCalculator::CalcDemand(LinkGraphJob &job, Tscaler scaler) * @param job Job to calculate the demands for. */ DemandCalculator::DemandCalculator(LinkGraphJob &job) : - max_distance(DistanceMaxPlusManhattan(TileXY(0,0), TileXY(MapMaxX(), MapMaxY()))) + max_distance(DistanceMaxPlusManhattan(TileXY(0,0), TileXY(Map::MaxX(), Map::MaxY()))) { const LinkGraphSettings &settings = job.Settings(); CargoID cargo = job.Cargo(); diff --git a/src/linkgraph/flowmapper.cpp b/src/linkgraph/flowmapper.cpp index 2e0257fc1bc1a..eb86d5e32e663 100644 --- a/src/linkgraph/flowmapper.cpp +++ b/src/linkgraph/flowmapper.cpp @@ -19,35 +19,33 @@ void FlowMapper::Run(LinkGraphJob &job) const { for (NodeID node_id = 0; node_id < job.Size(); ++node_id) { - Node prev_node = job[node_id]; - StationID prev = prev_node.Station(); - PathList &paths = prev_node.Paths(); - for (PathList::iterator i = paths.begin(); i != paths.end(); ++i) { - Path *path = *i; + Node &prev_node = job[node_id]; + StationID prev = prev_node.base.station; + for (const Path *path : prev_node.paths) { uint flow = path->GetFlow(); if (flow == 0) break; - Node node = job[path->GetNode()]; - StationID via = node.Station(); - StationID origin = job[path->GetOrigin()].Station(); + Node &node = job[path->GetNode()]; + StationID via = node.base.station; + StationID origin = job[path->GetOrigin()].base.station; assert(prev != via && via != origin); /* Mark all of the flow for local consumption at "first". */ - node.Flows().AddFlow(origin, via, flow); + node.flows.AddFlow(origin, via, flow); if (prev != origin) { /* Pass some of the flow marked for local consumption at "prev" on * to this node. */ - prev_node.Flows().PassOnFlow(origin, via, flow); + prev_node.flows.PassOnFlow(origin, via, flow); } else { /* Prev node is origin. Simply add flow. */ - prev_node.Flows().AddFlow(origin, via, flow); + prev_node.flows.AddFlow(origin, via, flow); } } } for (NodeID node_id = 0; node_id < job.Size(); ++node_id) { /* Remove local consumption shares marked as invalid. */ - Node node = job[node_id]; - FlowStatMap &flows = node.Flows(); - flows.FinalizeLocalConsumption(node.Station()); + Node &node = job[node_id]; + FlowStatMap &flows = node.flows; + flows.FinalizeLocalConsumption(node.base.station); if (this->scale) { /* Scale by time the graph has been running without being compressed. Add 1 to avoid * division by 0 if spawn date == last compression date. This matches @@ -58,10 +56,7 @@ void FlowMapper::Run(LinkGraphJob &job) const } } /* Clear paths. */ - PathList &paths = node.Paths(); - for (PathList::iterator i = paths.begin(); i != paths.end(); ++i) { - delete *i; - } - paths.clear(); + for (Path *i : node.paths) delete i; + node.paths.clear(); } } diff --git a/src/linkgraph/linkgraph.cpp b/src/linkgraph/linkgraph.cpp index 2efbe19d15715..c84c62b7e673b 100644 --- a/src/linkgraph/linkgraph.cpp +++ b/src/linkgraph/linkgraph.cpp @@ -23,7 +23,7 @@ INSTANTIATE_POOL_METHODS(LinkGraph) * @param st ID of the associated station. * @param demand Demand for cargo at the station. */ -inline void LinkGraph::BaseNode::Init(TileIndex xy, StationID st, uint demand) +LinkGraph::BaseNode::BaseNode(TileIndex xy, StationID st, uint demand) { this->xy = xy; this->supply = 0; @@ -35,14 +35,14 @@ inline void LinkGraph::BaseNode::Init(TileIndex xy, StationID st, uint demand) /** * Create an edge. */ -inline void LinkGraph::BaseEdge::Init() +LinkGraph::BaseEdge::BaseEdge(NodeID dest_node) { this->capacity = 0; this->usage = 0; this->travel_time_sum = 0; this->last_unrestricted_update = INVALID_DATE; this->last_restricted_update = INVALID_DATE; - this->next_edge = INVALID_NODE; + this->dest_node = dest_node; } /** @@ -56,8 +56,7 @@ void LinkGraph::ShiftDates(int interval) for (NodeID node1 = 0; node1 < this->Size(); ++node1) { BaseNode &source = this->nodes[node1]; if (source.last_update != INVALID_DATE) source.last_update += interval; - for (NodeID node2 = 0; node2 < this->Size(); ++node2) { - BaseEdge &edge = this->edges[node1][node2]; + for (BaseEdge &edge : this->nodes[node1].edges) { if (edge.last_unrestricted_update != INVALID_DATE) edge.last_unrestricted_update += interval; if (edge.last_restricted_update != INVALID_DATE) edge.last_restricted_update += interval; } @@ -69,15 +68,17 @@ void LinkGraph::Compress() this->last_compression = (_date + this->last_compression) / 2; for (NodeID node1 = 0; node1 < this->Size(); ++node1) { this->nodes[node1].supply /= 2; - for (NodeID node2 = 0; node2 < this->Size(); ++node2) { - BaseEdge &edge = this->edges[node1][node2]; + for (BaseEdge &edge : this->nodes[node1].edges) { if (edge.capacity > 0) { - edge.capacity = std::max(1U, edge.capacity / 2); + uint new_capacity = std::max(1U, edge.capacity / 2); + if (edge.capacity < (1 << 16)) { + edge.travel_time_sum = edge.travel_time_sum * new_capacity / edge.capacity; + } else if (edge.travel_time_sum != 0) { + edge.travel_time_sum = std::max(1ULL, edge.travel_time_sum / 2); + } + edge.capacity = new_capacity; edge.usage /= 2; } - if (edge.travel_time_sum > 0) { - edge.travel_time_sum = std::max(1ULL, edge.travel_time_sum / 2); - } } } } @@ -97,23 +98,13 @@ void LinkGraph::Merge(LinkGraph *other) this->nodes[new_node].supply = LinkGraph::Scale(other->nodes[node1].supply, age, other_age); st->goods[this->cargo].link_graph = this->index; st->goods[this->cargo].node = new_node; - for (NodeID node2 = 0; node2 < node1; ++node2) { - BaseEdge &forward = this->edges[new_node][first + node2]; - BaseEdge &backward = this->edges[first + node2][new_node]; - forward = other->edges[node1][node2]; - backward = other->edges[node2][node1]; - forward.capacity = LinkGraph::Scale(forward.capacity, age, other_age); - forward.usage = LinkGraph::Scale(forward.usage, age, other_age); - forward.travel_time_sum = LinkGraph::Scale(forward.travel_time_sum, age, other_age); - if (forward.next_edge != INVALID_NODE) forward.next_edge += first; - backward.capacity = LinkGraph::Scale(backward.capacity, age, other_age); - backward.usage = LinkGraph::Scale(backward.usage, age, other_age); - backward.travel_time_sum = LinkGraph::Scale(backward.travel_time_sum, age, other_age); - if (backward.next_edge != INVALID_NODE) backward.next_edge += first; + + for (BaseEdge &e : other->nodes[node1].edges) { + BaseEdge &new_edge = this->nodes[new_node].edges.emplace_back(first + e.dest_node); + new_edge.capacity = LinkGraph::Scale(e.capacity, age, other_age); + new_edge.usage = LinkGraph::Scale(e.usage, age, other_age); + new_edge.travel_time_sum = LinkGraph::Scale(e.travel_time_sum, age, other_age); } - BaseEdge &new_start = this->edges[new_node][new_node]; - new_start = other->edges[node1][node1]; - if (new_start.next_edge != INVALID_NODE) new_start.next_edge += first; } delete other; } @@ -127,30 +118,24 @@ void LinkGraph::RemoveNode(NodeID id) assert(id < this->Size()); NodeID last_node = this->Size() - 1; - for (NodeID i = 0; i <= last_node; ++i) { - (*this)[i].RemoveEdge(id); - BaseEdge *node_edges = this->edges[i]; - NodeID prev = i; - NodeID next = node_edges[i].next_edge; - while (next != INVALID_NODE) { - if (next == last_node) { - node_edges[prev].next_edge = id; - break; - } - prev = next; - next = node_edges[prev].next_edge; - } - node_edges[id] = node_edges[last_node]; - } Station::Get(this->nodes[last_node].station)->goods[this->cargo].node = id; /* Erase node by swapping with the last element. Node index is referenced * directly from station goods entries so the order and position must remain. */ this->nodes[id] = this->nodes.back(); this->nodes.pop_back(); - this->edges.EraseColumn(id); - /* Not doing EraseRow here, as having the extra invalid row doesn't hurt - * and removing it would trigger a lot of memmove. The data has already - * been copied around in the loop above. */ + for (auto &n : this->nodes) { + /* Find iterator position where an edge to id would be. */ + auto [first, last] = std::equal_range(n.edges.begin(), n.edges.end(), id); + /* Remove potential node (erasing an empty range is safe). */ + auto insert = n.edges.erase(first, last); + /* As the edge list is sorted, a potential edge to last_node will always be the last edge. */ + if (!n.edges.empty() && n.edges.back().dest_node == last_node) { + /* Change dest ID and move into the spot of the deleted edge. */ + n.edges.back().dest_node = id; + n.edges.insert(insert, n.edges.back()); + n.edges.pop_back(); + } + } } /** @@ -166,23 +151,8 @@ NodeID LinkGraph::AddNode(const Station *st) const GoodsEntry &good = st->goods[this->cargo]; NodeID new_node = this->Size(); - this->nodes.emplace_back(); - /* Avoid reducing the height of the matrix as that is expensive and we - * most likely will increase it again later which is again expensive. */ - this->edges.Resize(new_node + 1U, std::max(new_node + 1U, this->edges.Height())); - - this->nodes[new_node].Init(st->xy, st->index, - HasBit(good.status, GoodsEntry::GES_ACCEPTANCE)); - - BaseEdge *new_edges = this->edges[new_node]; + this->nodes.emplace_back(st->xy, st->index, HasBit(good.status, GoodsEntry::GES_ACCEPTANCE)); - /* Reset the first edge starting at the new node */ - new_edges[new_node].next_edge = INVALID_NODE; - - for (NodeID i = 0; i <= new_node; ++i) { - new_edges[i].Init(); - this->edges[i][new_node].Init(); - } return new_node; } @@ -194,16 +164,14 @@ NodeID LinkGraph::AddNode(const Station *st) * @param usage Usage to be added. * @param mode Update mode to be used. */ -void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) +void LinkGraph::BaseNode::AddEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) { - assert(this->index != to); - BaseEdge &edge = this->edges[to]; - BaseEdge &first = this->edges[this->index]; + assert(!this->HasEdgeTo(to)); + + BaseEdge &edge = *this->edges.emplace(std::upper_bound(this->edges.begin(), this->edges.end(), to), to); edge.capacity = capacity; edge.usage = usage; - edge.travel_time_sum = travel_time * capacity; - edge.next_edge = first.next_edge; - first.next_edge = to; + edge.travel_time_sum = static_cast(travel_time) * capacity; if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = _date; if (mode & EUM_RESTRICTED) edge.last_restricted_update = _date; } @@ -215,14 +183,14 @@ void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, uint32 trave * @param usage Usage to be added. * @param mode Update mode to be used. */ -void LinkGraph::Node::UpdateEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) +void LinkGraph::BaseNode::UpdateEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) { assert(capacity > 0); assert(usage <= capacity); - if (this->edges[to].capacity == 0) { + if (!this->HasEdgeTo(to)) { this->AddEdge(to, capacity, usage, travel_time, mode); } else { - (*this)[to].Update(capacity, usage, travel_time, mode); + this->GetEdge(to)->Update(capacity, usage, travel_time, mode); } } @@ -230,29 +198,10 @@ void LinkGraph::Node::UpdateEdge(NodeID to, uint capacity, uint usage, uint32 tr * Remove an outgoing edge from this node. * @param to ID of destination node. */ -void LinkGraph::Node::RemoveEdge(NodeID to) +void LinkGraph::BaseNode::RemoveEdge(NodeID to) { - if (this->index == to) return; - BaseEdge &edge = this->edges[to]; - edge.capacity = 0; - edge.last_unrestricted_update = INVALID_DATE; - edge.last_restricted_update = INVALID_DATE; - edge.usage = 0; - edge.travel_time_sum = 0; - - NodeID prev = this->index; - NodeID next = this->edges[this->index].next_edge; - while (next != INVALID_NODE) { - if (next == to) { - /* Will be removed, skip it. */ - this->edges[prev].next_edge = edge.next_edge; - edge.next_edge = INVALID_NODE; - break; - } else { - prev = next; - next = this->edges[next].next_edge; - } - } + auto [first, last] = std::equal_range(this->edges.begin(), this->edges.end(), to); + this->edges.erase(first, last); } /** @@ -265,33 +214,33 @@ void LinkGraph::Node::RemoveEdge(NodeID to) * @param travel_time Travel time to be added, in ticks. * @param mode Update mode to be applied. */ -void LinkGraph::Edge::Update(uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) +void LinkGraph::BaseEdge::Update(uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode) { - assert(this->edge.capacity > 0); + assert(this->capacity > 0); assert(capacity >= usage); if (mode & EUM_INCREASE) { - if (this->edge.travel_time_sum == 0) { - this->edge.travel_time_sum = (this->edge.capacity + capacity) * travel_time; + if (this->travel_time_sum == 0) { + this->travel_time_sum = static_cast(this->capacity + capacity) * travel_time; } else if (travel_time == 0) { - this->edge.travel_time_sum += this->edge.travel_time_sum / this->edge.capacity * capacity; + this->travel_time_sum += this->travel_time_sum / this->capacity * capacity; } else { - this->edge.travel_time_sum += travel_time * capacity; + this->travel_time_sum += static_cast(travel_time) * capacity; } - this->edge.capacity += capacity; - this->edge.usage += usage; + this->capacity += capacity; + this->usage += usage; } else if (mode & EUM_REFRESH) { - if (this->edge.travel_time_sum == 0) { - this->edge.capacity = std::max(this->edge.capacity, capacity); - this->edge.travel_time_sum = travel_time * this->edge.capacity; - } else if (capacity > this->edge.capacity) { - this->edge.travel_time_sum = this->edge.travel_time_sum / this->edge.capacity * capacity; - this->edge.capacity = capacity; + if (this->travel_time_sum == 0) { + this->capacity = std::max(this->capacity, capacity); + this->travel_time_sum = static_cast(travel_time) * this->capacity; + } else if (capacity > this->capacity) { + this->travel_time_sum = this->travel_time_sum / this->capacity * capacity; + this->capacity = capacity; } - this->edge.usage = std::max(this->edge.usage, usage); + this->usage = std::max(this->usage, usage); } - if (mode & EUM_UNRESTRICTED) this->edge.last_unrestricted_update = _date; - if (mode & EUM_RESTRICTED) this->edge.last_restricted_update = _date; + if (mode & EUM_UNRESTRICTED) this->last_unrestricted_update = _date; + if (mode & EUM_RESTRICTED) this->last_restricted_update = _date; } /** @@ -302,12 +251,5 @@ void LinkGraph::Edge::Update(uint capacity, uint usage, uint32 travel_time, Edge void LinkGraph::Init(uint size) { assert(this->Size() == 0); - this->edges.Resize(size, size); this->nodes.resize(size); - - for (uint i = 0; i < size; ++i) { - this->nodes[i].Init(); - BaseEdge *column = this->edges[i]; - for (uint j = 0; j < size; ++j) column[j].Init(); - } } diff --git a/src/linkgraph/linkgraph.h b/src/linkgraph/linkgraph.h index 3c5aee8720196..d9f8f9d9a794c 100644 --- a/src/linkgraph/linkgraph.h +++ b/src/linkgraph/linkgraph.h @@ -12,7 +12,6 @@ #include "../core/pool_type.hpp" #include "../core/smallmap_type.hpp" -#include "../core/smallmatrix_type.hpp" #include "../station_base.h" #include "../cargotype.h" #include "../date_func.h" @@ -38,26 +37,8 @@ extern LinkGraphPool _link_graph_pool; */ class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> { public: - - /** - * Node of the link graph. contains all relevant information from the associated - * station. It's copied so that the link graph job can work on its own data set - * in a separate thread. - */ - struct BaseNode { - uint supply; ///< Supply at the station. - uint demand; ///< Acceptance at the station. - StationID station; ///< Station ID. - TileIndex xy; ///< Location of the station referred to by the node. - Date last_update; ///< When the supply was last updated. - void Init(TileIndex xy = INVALID_TILE, StationID st = INVALID_STATION, uint demand = 0); - }; - /** - * An edge in the link graph. Corresponds to a link between two stations or at - * least the distance between them. Edges from one node to itself contain the - * ID of the opposite Node of the first active edge (i.e. not just distance) in - * the column as next_edge. + * An edge in the link graph. Corresponds to a link between two stations. */ struct BaseEdge { uint capacity; ///< Capacity of the link. @@ -65,348 +46,58 @@ class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> { uint64 travel_time_sum; ///< Sum of the travel times of the link, in ticks. Date last_unrestricted_update; ///< When the unrestricted part of the link was last updated. Date last_restricted_update; ///< When the restricted part of the link was last updated. - NodeID next_edge; ///< Destination of next valid edge starting at the same source node. - void Init(); - }; - - /** - * Wrapper for an edge (const or not) allowing retrieval, but no modification. - * @tparam Tedge Actual edge class, may be "const BaseEdge" or just "BaseEdge". - */ - template - class EdgeWrapper { - protected: - Tedge &edge; ///< Actual edge to be used. - - public: - - /** - * Wrap a an edge. - * @param edge Edge to be wrapped. - */ - EdgeWrapper (Tedge &edge) : edge(edge) {} - - /** - * Get edge's capacity. - * @return Capacity. - */ - uint Capacity() const { return this->edge.capacity; } + NodeID dest_node; ///< Destination of the edge. - /** - * Get edge's usage. - * @return Usage. - */ - uint Usage() const { return this->edge.usage; } + BaseEdge(NodeID dest_node = INVALID_NODE); /** * Get edge's average travel time. * @return Travel time, in ticks. */ - uint32 TravelTime() const { return this->edge.travel_time_sum / this->edge.capacity; } - - /** - * Get the date of the last update to the edge's unrestricted capacity. - * @return Last update. - */ - Date LastUnrestrictedUpdate() const { return this->edge.last_unrestricted_update; } - - /** - * Get the date of the last update to the edge's restricted capacity. - * @return Last update. - */ - Date LastRestrictedUpdate() const { return this->edge.last_restricted_update; } + uint32 TravelTime() const { return this->travel_time_sum / this->capacity; } /** * Get the date of the last update to any part of the edge's capacity. * @return Last update. */ - Date LastUpdate() const { return std::max(this->edge.last_unrestricted_update, this->edge.last_restricted_update); } - }; - - /** - * Wrapper for a node (const or not) allowing retrieval, but no modification. - * @tparam Tedge Actual node class, may be "const BaseNode" or just "BaseNode". - * @tparam Tedge Actual edge class, may be "const BaseEdge" or just "BaseEdge". - */ - template - class NodeWrapper { - protected: - Tnode &node; ///< Node being wrapped. - Tedge *edges; ///< Outgoing edges for wrapped node. - NodeID index; ///< ID of wrapped node. - - public: - - /** - * Wrap a node. - * @param node Node to be wrapped. - * @param edges Outgoing edges for node to be wrapped. - * @param index ID of node to be wrapped. - */ - NodeWrapper(Tnode &node, Tedge *edges, NodeID index) : node(node), - edges(edges), index(index) {} - - /** - * Get supply of wrapped node. - * @return Supply. - */ - uint Supply() const { return this->node.supply; } - - /** - * Get demand of wrapped node. - * @return Demand. - */ - uint Demand() const { return this->node.demand; } - - /** - * Get ID of station belonging to wrapped node. - * @return ID of node's station. - */ - StationID Station() const { return this->node.station; } - - /** - * Get node's last update. - * @return Last update. - */ - Date LastUpdate() const { return this->node.last_update; } - - /** - * Get the location of the station associated with the node. - * @return Location of the station. - */ - TileIndex XY() const { return this->node.xy; } - }; - - /** - * Base class for iterating across outgoing edges of a node. Only the real - * edges (those with capacity) are iterated. The ones with only distance - * information are skipped. - * @tparam Tedge Actual edge class. May be "BaseEdge" or "const BaseEdge". - * @tparam Titer Actual iterator class. - */ - template - class BaseEdgeIterator { - protected: - Tedge *base; ///< Array of edges being iterated. - NodeID current; ///< Current offset in edges array. - - /** - * A "fake" pointer to enable operator-> on temporaries. As the objects - * returned from operator* aren't references but real objects, we have - * to return something that implements operator->, but isn't a pointer - * from operator->. A fake pointer. - */ - class FakePointer : public std::pair { - public: - - /** - * Construct a fake pointer from a pair of NodeID and edge. - * @param pair Pair to be "pointed" to (in fact shallow-copied). - */ - FakePointer(const std::pair &pair) : std::pair(pair) {} - - /** - * Retrieve the pair by operator->. - * @return Pair being "pointed" to. - */ - std::pair *operator->() { return this; } - }; - - public: - /** - * Constructor. - * @param base Array of edges to be iterated. - * @param current ID of current node (to locate the first edge). - */ - BaseEdgeIterator (Tedge *base, NodeID current) : - base(base), - current(current == INVALID_NODE ? current : base[current].next_edge) - {} - - /** - * Prefix-increment. - * @return This. - */ - Titer &operator++() - { - this->current = this->base[this->current].next_edge; - return static_cast(*this); - } + Date LastUpdate() const { return std::max(this->last_unrestricted_update, this->last_restricted_update); } - /** - * Postfix-increment. - * @return Version of this before increment. - */ - Titer operator++(int) - { - Titer ret(static_cast(*this)); - this->current = this->base[this->current].next_edge; - return ret; - } + void Update(uint capacity, uint usage, uint32 time, EdgeUpdateMode mode); + void Restrict() { this->last_unrestricted_update = INVALID_DATE; } + void Release() { this->last_restricted_update = INVALID_DATE; } - /** - * Compare with some other edge iterator. The other one may be of a - * child class. - * @tparam Tother Class of other iterator. - * @param other Instance of other iterator. - * @return If the iterators have the same edge array and current node. - */ - template - bool operator==(const Tother &other) + /** Comparison operator based on \c dest_node. */ + bool operator <(const BaseEdge &rhs) const { - return this->base == other.base && this->current == other.current; + return this->dest_node < rhs.dest_node; } - /** - * Compare for inequality with some other edge iterator. The other one - * may be of a child class. - * @tparam Tother Class of other iterator. - * @param other Instance of other iterator. - * @return If either the edge arrays or the current nodes differ. - */ - template - bool operator!=(const Tother &other) + bool operator <(NodeID rhs) const { - return this->base != other.base || this->current != other.current; + return this->dest_node < rhs; } - /** - * Dereference with operator*. - * @return Pair of current target NodeID and edge object. - */ - std::pair operator*() const + friend inline bool operator <(NodeID lhs, const LinkGraph::BaseEdge &rhs) { - return std::pair(this->current, Tedge_wrapper(this->base[this->current])); - } - - /** - * Dereference with operator->. - * @return Fake pointer to Pair of current target NodeID and edge object. - */ - FakePointer operator->() const { - return FakePointer(this->operator*()); + return lhs < rhs.dest_node; } }; /** - * A constant edge class. - */ - typedef EdgeWrapper ConstEdge; - - /** - * An updatable edge class. - */ - class Edge : public EdgeWrapper { - public: - /** - * Constructor - * @param edge Edge to be wrapped. - */ - Edge(BaseEdge &edge) : EdgeWrapper(edge) {} - void Update(uint capacity, uint usage, uint32 time, EdgeUpdateMode mode); - void Restrict() { this->edge.last_unrestricted_update = INVALID_DATE; } - void Release() { this->edge.last_restricted_update = INVALID_DATE; } - }; - - /** - * An iterator for const edges. Cannot be typedef'ed because of - * template-reference to ConstEdgeIterator itself. - */ - class ConstEdgeIterator : public BaseEdgeIterator { - public: - /** - * Constructor. - * @param edges Array of edges to be iterated over. - * @param current ID of current edge's end node. - */ - ConstEdgeIterator(const BaseEdge *edges, NodeID current) : - BaseEdgeIterator(edges, current) {} - }; - - /** - * An iterator for non-const edges. Cannot be typedef'ed because of - * template-reference to EdgeIterator itself. - */ - class EdgeIterator : public BaseEdgeIterator { - public: - /** - * Constructor. - * @param edges Array of edges to be iterated over. - * @param current ID of current edge's end node. - */ - EdgeIterator(BaseEdge *edges, NodeID current) : - BaseEdgeIterator(edges, current) {} - }; - - /** - * Constant node class. Only retrieval operations are allowed on both the - * node itself and its edges. - */ - class ConstNode : public NodeWrapper { - public: - /** - * Constructor. - * @param lg LinkGraph to get the node from. - * @param node ID of the node. - */ - ConstNode(const LinkGraph *lg, NodeID node) : - NodeWrapper(lg->nodes[node], lg->edges[node], node) - {} - - /** - * Get a ConstEdge. This is not a reference as the wrapper objects are - * not actually persistent. - * @param to ID of end node of edge. - * @return Constant edge wrapper. - */ - ConstEdge operator[](NodeID to) const { return ConstEdge(this->edges[to]); } - - /** - * Get an iterator pointing to the start of the edges array. - * @return Constant edge iterator. - */ - ConstEdgeIterator Begin() const { return ConstEdgeIterator(this->edges, this->index); } - - /** - * Get an iterator pointing beyond the end of the edges array. - * @return Constant edge iterator. - */ - ConstEdgeIterator End() const { return ConstEdgeIterator(this->edges, INVALID_NODE); } - }; - - /** - * Updatable node class. The node itself as well as its edges can be modified. + * Node of the link graph. contains all relevant information from the associated + * station. It's copied so that the link graph job can work on its own data set + * in a separate thread. */ - class Node : public NodeWrapper { - public: - /** - * Constructor. - * @param lg LinkGraph to get the node from. - * @param node ID of the node. - */ - Node(LinkGraph *lg, NodeID node) : - NodeWrapper(lg->nodes[node], lg->edges[node], node) - {} - - /** - * Get an Edge. This is not a reference as the wrapper objects are not - * actually persistent. - * @param to ID of end node of edge. - * @return Edge wrapper. - */ - Edge operator[](NodeID to) { return Edge(this->edges[to]); } + struct BaseNode { + uint supply; ///< Supply at the station. + uint demand; ///< Acceptance at the station. + StationID station; ///< Station ID. + TileIndex xy; ///< Location of the station referred to by the node. + Date last_update; ///< When the supply was last updated. - /** - * Get an iterator pointing to the start of the edges array. - * @return Edge iterator. - */ - EdgeIterator Begin() { return EdgeIterator(this->edges, this->index); } + std::vector edges; ///< Sorted list of outgoing edges from this node. - /** - * Get an iterator pointing beyond the end of the edges array. - * @return Constant edge iterator. - */ - EdgeIterator End() { return EdgeIterator(this->edges, INVALID_NODE); } + BaseNode(TileIndex xy = INVALID_TILE, StationID st = INVALID_STATION, uint demand = 0); /** * Update the node's supply and set last_update to the current date. @@ -414,8 +105,8 @@ class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> { */ void UpdateSupply(uint supply) { - this->node.supply += supply; - this->node.last_update = _date; + this->supply += supply; + this->last_update = _date; } /** @@ -424,7 +115,7 @@ class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> { */ void UpdateLocation(TileIndex xy) { - this->node.xy = xy; + this->xy = xy; } /** @@ -433,16 +124,48 @@ class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> { */ void SetDemand(uint demand) { - this->node.demand = demand; + this->demand = demand; } void AddEdge(NodeID to, uint capacity, uint usage, uint32 time, EdgeUpdateMode mode); void UpdateEdge(NodeID to, uint capacity, uint usage, uint32 time, EdgeUpdateMode mode); void RemoveEdge(NodeID to); + + /** + * Check if an edge to a destination is present. + * @param dest Wanted edge destination. + * @return True if an edge is present. + */ + bool HasEdgeTo(NodeID dest) const + { + return std::binary_search(this->edges.begin(), this->edges.end(), dest); + } + + BaseEdge &operator[](NodeID to) + { + assert(this->HasEdgeTo(to)); + return *GetEdge(to); + } + + const BaseEdge &operator[](NodeID to) const + { + assert(this->HasEdgeTo(to)); + return *GetEdge(to); + } + + private: + std::vector::iterator GetEdge(NodeID dest) + { + return std::lower_bound(this->edges.begin(), this->edges.end(), dest); + } + + std::vector::const_iterator GetEdge(NodeID dest) const + { + return std::lower_bound(this->edges.begin(), this->edges.end(), dest); + } }; typedef std::vector NodeVector; - typedef SmallMatrix EdgeMatrix; /** Minimum effective distance for timeout calculation. */ static const uint MIN_TIMEOUT_DISTANCE = 32; @@ -492,14 +215,14 @@ class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> { * @param num ID of the node. * @return the Requested node. */ - inline Node operator[](NodeID num) { return Node(this, num); } + inline BaseNode &operator[](NodeID num) { return this->nodes[num]; } /** * Get a const reference to a node with the specified id. * @param num ID of the node. * @return the Requested node. */ - inline ConstNode operator[](NodeID num) const { return ConstNode(this, num); } + inline const BaseNode &operator[](NodeID num) const { return this->nodes[num]; } /** * Get the current size of the component. @@ -533,17 +256,15 @@ class LinkGraph : public LinkGraphPool::PoolItem<&_link_graph_pool> { void RemoveNode(NodeID id); protected: - friend class LinkGraph::ConstNode; - friend class LinkGraph::Node; friend SaveLoadTable GetLinkGraphDesc(); friend SaveLoadTable GetLinkGraphJobDesc(); friend class SlLinkgraphNode; friend class SlLinkgraphEdge; + friend class LinkGraphJob; CargoID cargo; ///< Cargo of this component's link graph. Date last_compression; ///< Last time the capacities and supplies were compressed. NodeVector nodes; ///< Nodes in the component. - EdgeMatrix edges; ///< Edges in the component. }; #endif /* LINKGRAPH_H */ diff --git a/src/linkgraph/linkgraph_base.h b/src/linkgraph/linkgraph_base.h index eb86c0c64e156..0eed6063af6ff 100644 --- a/src/linkgraph/linkgraph_base.h +++ b/src/linkgraph/linkgraph_base.h @@ -13,13 +13,11 @@ #include "linkgraph.h" #include "linkgraphschedule.h" -typedef LinkGraph::Node Node; -typedef LinkGraph::Edge Edge; -typedef LinkGraph::EdgeIterator EdgeIterator; +typedef LinkGraph::BaseNode Node; +typedef LinkGraph::BaseEdge Edge; -typedef LinkGraph::ConstNode ConstNode; -typedef LinkGraph::ConstEdge ConstEdge; -typedef LinkGraph::ConstEdgeIterator ConstEdgeIterator; +typedef const LinkGraph::BaseNode ConstNode; +typedef const LinkGraph::BaseEdge ConstEdge; #endif /* LINKGRAPH_BASE_H */ diff --git a/src/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index baeb2438cc57e..026f85b8532ba 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.cpp @@ -14,6 +14,7 @@ #include "../company_gui.h" #include "../date_func.h" #include "../viewport_func.h" +#include "../zoom_func.h" #include "../smallmap_gui.h" #include "../core/geometry_func.hpp" #include "../widgets/link_graph_legend_widget.h" @@ -87,10 +88,10 @@ void LinkGraphOverlay::RebuildCache() if (!LinkGraph::IsValidID(sta->goods[c].link_graph)) continue; const LinkGraph &lg = *LinkGraph::Get(sta->goods[c].link_graph); - ConstNode from_node = lg[sta->goods[c].node]; - supply += lg.Monthly(from_node.Supply()); - for (ConstEdgeIterator i = from_node.Begin(); i != from_node.End(); ++i) { - StationID to = lg[i->first].Station(); + ConstNode &from_node = lg[sta->goods[c].node]; + supply += lg.Monthly(from_node.supply); + for (const Edge &edge : from_node.edges) { + StationID to = lg[edge.dest_node].station; assert(from != to); if (!Station::IsValidID(to) || seen_links.find(to) != seen_links.end()) { continue; @@ -216,10 +217,12 @@ void LinkGraphOverlay::AddLinks(const Station *from, const Station *to) continue; } const LinkGraph &lg = *LinkGraph::Get(ge.link_graph); - ConstEdge edge = lg[ge.node][to->goods[c].node]; - if (edge.Capacity() > 0) { - this->AddStats(lg.Monthly(edge.Capacity()), lg.Monthly(edge.Usage()), - ge.flows.GetFlowVia(to->index), from->owner == OWNER_NONE || to->owner == OWNER_NONE, + if (lg[ge.node].HasEdgeTo(to->goods[c].node)) { + ConstEdge &edge = lg[ge.node][to->goods[c].node]; + this->AddStats(c, lg.Monthly(edge.capacity), lg.Monthly(edge.usage), + ge.flows.GetFlowVia(to->index), + edge.TravelTime() / DAY_TICKS, + from->owner == OWNER_NONE || to->owner == OWNER_NONE, this->cached_links[from->index][to->index]); } } @@ -235,14 +238,16 @@ void LinkGraphOverlay::AddLinks(const Station *from, const Station *to) * @param new_shared If the new link is shared. * @param cargo LinkProperties to write the information to. */ -/* static */ void LinkGraphOverlay::AddStats(uint new_cap, uint new_usg, uint new_plan, bool new_shared, LinkProperties &cargo) +/* static */ void LinkGraphOverlay::AddStats(CargoID new_cargo, uint new_cap, uint new_usg, uint new_plan, uint32 time, bool new_shared, LinkProperties &cargo) { /* multiply the numbers by 32 in order to avoid comparing to 0 too often. */ if (cargo.capacity == 0 || - std::max(cargo.usage, cargo.planned) * 32 / (cargo.capacity + 1) < std::max(new_usg, new_plan) * 32 / (new_cap + 1)) { + cargo.Usage() * 32 / (cargo.capacity + 1) < std::max(new_usg, new_plan) * 32 / (new_cap + 1)) { + cargo.cargo = new_cargo; cargo.capacity = new_cap; cargo.usage = new_usg; cargo.planned = new_plan; + cargo.time = time; } if (new_shared) cargo.shared = true; } @@ -267,13 +272,14 @@ void LinkGraphOverlay::Draw(const DrawPixelInfo *dpi) */ void LinkGraphOverlay::DrawLinks(const DrawPixelInfo *dpi) const { + int width = ScaleGUITrad(this->scale); for (LinkMap::const_iterator i(this->cached_links.begin()); i != this->cached_links.end(); ++i) { if (!Station::IsValidID(i->first)) continue; Point pta = this->GetStationMiddle(Station::Get(i->first)); for (StationLinkMap::const_iterator j(i->second.begin()); j != i->second.end(); ++j) { if (!Station::IsValidID(j->first)) continue; Point ptb = this->GetStationMiddle(Station::Get(j->first)); - if (!this->IsLinkVisible(pta, ptb, dpi, this->scale + 2)) continue; + if (!this->IsLinkVisible(pta, ptb, dpi, width + 2)) continue; this->DrawContent(pta, ptb, j->second); } } @@ -287,22 +293,23 @@ void LinkGraphOverlay::DrawLinks(const DrawPixelInfo *dpi) const */ void LinkGraphOverlay::DrawContent(Point pta, Point ptb, const LinkProperties &cargo) const { - uint usage_or_plan = std::min(cargo.capacity * 2 + 1, std::max(cargo.usage, cargo.planned)); + uint usage_or_plan = std::min(cargo.capacity * 2 + 1, cargo.Usage()); int colour = LinkGraphOverlay::LINK_COLOURS[_settings_client.gui.linkgraph_colours][usage_or_plan * lengthof(LinkGraphOverlay::LINK_COLOURS[0]) / (cargo.capacity * 2 + 2)]; - int dash = cargo.shared ? this->scale * 4 : 0; + int width = ScaleGUITrad(this->scale); + int dash = cargo.shared ? width * 4 : 0; /* Move line a bit 90° against its dominant direction to prevent it from * being hidden below the grey line. */ int side = _settings_game.vehicle.road_side ? 1 : -1; if (abs(pta.x - ptb.x) < abs(pta.y - ptb.y)) { - int offset_x = (pta.y > ptb.y ? 1 : -1) * side * this->scale; - GfxDrawLine(pta.x + offset_x, pta.y, ptb.x + offset_x, ptb.y, colour, this->scale, dash); + int offset_x = (pta.y > ptb.y ? 1 : -1) * side * width; + GfxDrawLine(pta.x + offset_x, pta.y, ptb.x + offset_x, ptb.y, colour, width, dash); } else { - int offset_y = (pta.x < ptb.x ? 1 : -1) * side * this->scale; - GfxDrawLine(pta.x, pta.y + offset_y, ptb.x, ptb.y + offset_y, colour, this->scale, dash); + int offset_y = (pta.x < ptb.x ? 1 : -1) * side * width; + GfxDrawLine(pta.x, pta.y + offset_y, ptb.x, ptb.y + offset_y, colour, width, dash); } - GfxDrawLine(pta.x, pta.y, ptb.x, ptb.y, _colour_gradient[COLOUR_GREY][1], this->scale); + GfxDrawLine(pta.x, pta.y, ptb.x, ptb.y, _colour_gradient[COLOUR_GREY][1], width); } /** @@ -311,13 +318,14 @@ void LinkGraphOverlay::DrawContent(Point pta, Point ptb, const LinkProperties &c */ void LinkGraphOverlay::DrawStationDots(const DrawPixelInfo *dpi) const { + int width = ScaleGUITrad(this->scale); for (StationSupplyList::const_iterator i(this->cached_stations.begin()); i != this->cached_stations.end(); ++i) { const Station *st = Station::GetIfValid(i->first); if (st == nullptr) continue; Point pt = this->GetStationMiddle(st); - if (!this->IsPointVisible(pt, dpi, 3 * this->scale)) continue; + if (!this->IsPointVisible(pt, dpi, 3 * width)) continue; - uint r = this->scale * 2 + this->scale * 2 * std::min(200U, i->second) / 200; + uint r = width * 2 + width * 2 * std::min(200U, i->second) / 200; LinkGraphOverlay::DrawVertex(pt.x, pt.y, r, _colour_gradient[st->owner != OWNER_NONE ? @@ -350,6 +358,62 @@ void LinkGraphOverlay::DrawStationDots(const DrawPixelInfo *dpi) const GfxDrawLine(x + w2, y - w1, x + w2, y + w2, border_colour); } +bool LinkGraphOverlay::ShowTooltip(Point pt, TooltipCloseCondition close_cond) +{ + for (auto i(this->cached_links.crbegin()); i != this->cached_links.crend(); ++i) { + if (!Station::IsValidID(i->first)) continue; + Point pta = this->GetStationMiddle(Station::Get(i->first)); + for (auto j(i->second.crbegin()); j != i->second.crend(); ++j) { + if (!Station::IsValidID(j->first)) continue; + if (i->first == j->first) continue; + + /* Check the distance from the cursor to the line defined by the two stations. */ + Point ptb = this->GetStationMiddle(Station::Get(j->first)); + float dist = std::abs((ptb.x - pta.x) * (pta.y - pt.y) - (pta.x - pt.x) * (ptb.y - pta.y)) / + std::sqrt((ptb.x - pta.x) * (ptb.x - pta.x) + (ptb.y - pta.y) * (ptb.y - pta.y)); + const auto &link = j->second; + if (dist <= 4 && link.Usage() > 0 && + pt.x + 2 >= std::min(pta.x, ptb.x) && + pt.x - 2 <= std::max(pta.x, ptb.x) && + pt.y + 2 >= std::min(pta.y, ptb.y) && + pt.y - 2 <= std::max(pta.y, ptb.y)) { + static char buf[1024]; + char *buf_end = buf; + buf[0] = 0; + /* Fill buf with more information if this is a bidirectional link. */ + uint32 back_time = 0; + auto k = this->cached_links[j->first].find(i->first); + if (k != this->cached_links[j->first].end()) { + const auto &back = k->second; + back_time = back.time; + if (back.Usage() > 0) { + SetDParam(0, back.cargo); + SetDParam(1, back.Usage()); + SetDParam(2, back.Usage() * 100 / (back.capacity + 1)); + buf_end = GetString(buf, STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION, lastof(buf)); + } + } + /* Add information about the travel time if known. */ + const auto time = link.time ? back_time ? ((link.time + back_time) / 2) : link.time : back_time; + if (time > 0) { + SetDParam(0, time); + buf_end = GetString(buf_end, STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION, lastof(buf)); + } + SetDParam(0, link.cargo); + SetDParam(1, link.Usage()); + SetDParam(2, i->first); + SetDParam(3, j->first); + SetDParam(4, link.Usage() * 100 / (link.capacity + 1)); + SetDParamStr(5, buf); + GuiShowTooltips(this->window, STR_LINKGRAPH_STATS_TOOLTIP, 7, nullptr, close_cond); + return true; + } + } + } + GuiShowTooltips(this->window, STR_NULL, 0, nullptr, close_cond); + return false; +} + /** * Determine the middle of a station in the current window. * @param st The station we're looking for. @@ -447,13 +511,11 @@ static const NWidgetPart _nested_linkgraph_legend_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), - NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect), SetPIP(0, WidgetDimensions::unscaled.framerect.Horizontal(), 0), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_LGL_SATURATION), - SetPadding(WD_FRAMERECT_TOP, 0, WD_FRAMERECT_BOTTOM, WD_CAPTIONTEXT_LEFT), NWidgetFunction(MakeSaturationLegendLinkGraphGUI), EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_LGL_COMPANIES), - SetPadding(WD_FRAMERECT_TOP, 0, WD_FRAMERECT_BOTTOM, WD_CAPTIONTEXT_LEFT), NWidget(NWID_VERTICAL, NC_EQUALSIZE), NWidgetFunction(MakeCompanyButtonRowsLinkGraphGUI), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_LGL_COMPANIES_ALL), SetDataTip(STR_LINKGRAPH_LEGEND_ALL, STR_NULL), @@ -461,7 +523,6 @@ static const NWidgetPart _nested_linkgraph_legend_widgets[] = { EndContainer(), EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_LGL_CARGOES), - SetPadding(WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM, WD_CAPTIONTEXT_LEFT), NWidget(NWID_VERTICAL, NC_EQUALSIZE), NWidgetFunction(MakeCargoesLegendLinkGraphGUI), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_LGL_CARGOES_ALL), SetDataTip(STR_LINKGRAPH_LEGEND_ALL, STR_NULL), @@ -494,7 +555,7 @@ LinkGraphLegendWindow::LinkGraphLegendWindow(WindowDesc *desc, int window_number { this->InitNested(window_number); this->InvalidateData(0); - this->SetOverlay(FindWindowById(WC_MAIN_WINDOW, 0)->viewport->overlay); + this->SetOverlay(GetMainWindow()->viewport->overlay); } /** @@ -530,8 +591,8 @@ void LinkGraphLegendWindow::UpdateWidgetSize(int widget, Dimension *size, const } if (str != STR_NULL) { Dimension dim = GetStringBoundingBox(str); - dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + dim.width += padding.width; + dim.height += padding.height; *size = maxdim(*size, dim); } } @@ -539,8 +600,8 @@ void LinkGraphLegendWindow::UpdateWidgetSize(int widget, Dimension *size, const CargoSpec *cargo = CargoSpec::Get(widget - WID_LGL_CARGO_FIRST); if (cargo->IsValid()) { Dimension dim = GetStringBoundingBox(cargo->abbrev); - dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + dim.width += padding.width; + dim.height += padding.height; *size = maxdim(*size, dim); } } @@ -548,15 +609,17 @@ void LinkGraphLegendWindow::UpdateWidgetSize(int widget, Dimension *size, const void LinkGraphLegendWindow::DrawWidget(const Rect &r, int widget) const { + Rect br = r.Shrink(WidgetDimensions::scaled.bevel); + if (this->IsWidgetLowered(widget)) br = br.Translate(WidgetDimensions::scaled.pressed, WidgetDimensions::scaled.pressed); if (IsInsideMM(widget, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST + 1)) { if (this->IsWidgetDisabled(widget)) return; CompanyID cid = (CompanyID)(widget - WID_LGL_COMPANY_FIRST); Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON); - DrawCompanyIcon(cid, (r.left + r.right + 1 - sprite_size.width) / 2, (r.top + r.bottom + 1 - sprite_size.height) / 2); + DrawCompanyIcon(cid, CenterBounds(br.left, br.right, sprite_size.width), CenterBounds(br.top, br.bottom, sprite_size.height)); } if (IsInsideMM(widget, WID_LGL_SATURATION_FIRST, WID_LGL_SATURATION_LAST + 1)) { uint8 colour = LinkGraphOverlay::LINK_COLOURS[_settings_client.gui.linkgraph_colours][widget - WID_LGL_SATURATION_FIRST]; - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, colour); + GfxFillRect(br, colour); StringID str = STR_NULL; if (widget == WID_LGL_SATURATION_FIRST) { str = STR_LINKGRAPH_LEGEND_UNUSED; @@ -566,14 +629,14 @@ void LinkGraphLegendWindow::DrawWidget(const Rect &r, int widget) const str = STR_LINKGRAPH_LEGEND_SATURATED; } if (str != STR_NULL) { - DrawString(r.left, r.right, (r.top + r.bottom + 1 - FONT_HEIGHT_SMALL) / 2, str, GetContrastColour(colour) | TC_FORCED, SA_HOR_CENTER); + DrawString(br.left, br.right, CenterBounds(br.top, br.bottom, FONT_HEIGHT_SMALL), str, GetContrastColour(colour) | TC_FORCED, SA_HOR_CENTER); } } if (IsInsideMM(widget, WID_LGL_CARGO_FIRST, WID_LGL_CARGO_LAST + 1)) { if (this->IsWidgetDisabled(widget)) return; CargoSpec *cargo = CargoSpec::Get(widget - WID_LGL_CARGO_FIRST); - GfxFillRect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2, cargo->legend_colour); - DrawString(r.left, r.right, (r.top + r.bottom + 1 - FONT_HEIGHT_SMALL) / 2, cargo->abbrev, GetContrastColour(cargo->legend_colour, 73), SA_HOR_CENTER); + GfxFillRect(br, cargo->legend_colour); + DrawString(br.left, br.right, CenterBounds(br.top, br.bottom, FONT_HEIGHT_SMALL), cargo->abbrev, GetContrastColour(cargo->legend_colour, 73), SA_HOR_CENTER); } } diff --git a/src/linkgraph/linkgraph_gui.h b/src/linkgraph/linkgraph_gui.h index e6b1114008068..ef249b9bfd67f 100644 --- a/src/linkgraph/linkgraph_gui.h +++ b/src/linkgraph/linkgraph_gui.h @@ -19,14 +19,20 @@ #include /** - * Properties of a link between two stations. + * Monthly statistics for a link between two stations. + * Only the cargo type of the most saturated linkgraph is taken into account. */ struct LinkProperties { - LinkProperties() : capacity(0), usage(0), planned(0), shared(false) {} + LinkProperties() : cargo(CT_INVALID), capacity(0), usage(0), planned(0), shared(false) {} + /** Return the usage of the link to display. */ + uint Usage() const { return std::max(this->usage, this->planned); } + + CargoID cargo; ///< Cargo type of the link. uint capacity; ///< Capacity of the link. uint usage; ///< Actual usage of the link. uint planned; ///< Planned usage of the link. + uint32 time; ///< Travel time of the link. bool shared; ///< If this is a shared link to be drawn dashed. }; @@ -50,7 +56,7 @@ class LinkGraphOverlay { * @param company_mask Bitmask of companies to be shown. * @param scale Desired thickness of lines and size of station dots. */ - LinkGraphOverlay(const Window *w, uint wid, CargoTypes cargo_mask, uint32 company_mask, uint scale) : + LinkGraphOverlay(Window *w, uint wid, CargoTypes cargo_mask, uint32 company_mask, uint scale) : window(w), widget_id(wid), cargo_mask(cargo_mask), company_mask(company_mask), scale(scale) {} @@ -58,6 +64,8 @@ class LinkGraphOverlay { void SetCargoMask(CargoTypes cargo_mask); void SetCompanyMask(uint32 company_mask); + bool ShowTooltip(Point pt, TooltipCloseCondition close_cond); + /** Mark the linkgraph dirty to be rebuilt next time Draw() is called. */ void SetDirty() { this->dirty = true; } @@ -68,7 +76,7 @@ class LinkGraphOverlay { uint32 GetCompanyMask() { return this->company_mask; } protected: - const Window *window; ///< Window to be drawn into. + Window *window; ///< Window to be drawn into. const uint widget_id; ///< ID of Widget in Window to be drawn to. CargoTypes cargo_mask; ///< Bitmask of cargos to be displayed. uint32 company_mask; ///< Bitmask of companies to be displayed. @@ -88,7 +96,7 @@ class LinkGraphOverlay { void GetWidgetDpi(DrawPixelInfo *dpi) const; void RebuildCache(); - static void AddStats(uint new_cap, uint new_usg, uint new_flow, bool new_shared, LinkProperties &cargo); + static void AddStats(CargoID new_cargo, uint new_cap, uint new_usg, uint new_flow, uint32 time, bool new_shared, LinkProperties &cargo); static void DrawVertex(int x, int y, int size, int colour, int border_colour); }; diff --git a/src/linkgraph/linkgraph_type.h b/src/linkgraph/linkgraph_type.h index a2618ae84f194..1839633bf6472 100644 --- a/src/linkgraph/linkgraph_type.h +++ b/src/linkgraph/linkgraph_type.h @@ -14,7 +14,7 @@ typedef uint16 LinkGraphID; static const LinkGraphID INVALID_LINK_GRAPH = UINT16_MAX; typedef uint16 LinkGraphJobID; -static const LinkGraphID INVALID_LINK_GRAPH_JOB = UINT16_MAX; +static const LinkGraphJobID INVALID_LINK_GRAPH_JOB = UINT16_MAX; typedef uint16 NodeID; static const NodeID INVALID_NODE = UINT16_MAX; diff --git a/src/linkgraph/linkgraphjob.cpp b/src/linkgraph/linkgraphjob.cpp index 8e5ec32838101..5902e01e7385d 100644 --- a/src/linkgraph/linkgraphjob.cpp +++ b/src/linkgraph/linkgraphjob.cpp @@ -50,7 +50,7 @@ LinkGraphJob::LinkGraphJob(const LinkGraph &orig) : void LinkGraphJob::EraseFlows(NodeID from) { for (NodeID node_id = 0; node_id < this->Size(); ++node_id) { - (*this)[node_id].Flows().erase(from); + (*this)[node_id].flows.erase(from); } } @@ -103,10 +103,10 @@ LinkGraphJob::~LinkGraphJob() uint16 size = this->Size(); for (NodeID node_id = 0; node_id < size; ++node_id) { - Node from = (*this)[node_id]; + NodeAnnotation &from = this->nodes[node_id]; /* The station can have been deleted. Remove all flows originating from it then. */ - Station *st = Station::GetIfValid(from.Station()); + Station *st = Station::GetIfValid(from.base.station); if (st == nullptr) { this->EraseFlows(node_id); continue; @@ -121,22 +121,24 @@ LinkGraphJob::~LinkGraphJob() } LinkGraph *lg = LinkGraph::Get(ge.link_graph); - FlowStatMap &flows = from.Flows(); + FlowStatMap &flows = from.flows; - for (EdgeIterator it(from.Begin()); it != from.End(); ++it) { - if (from[it->first].Flow() == 0) continue; - StationID to = (*this)[it->first].Station(); + for (const auto &edge : from.edges) { + if (edge.Flow() == 0) continue; + NodeID dest_id = edge.base.dest_node; + StationID to = this->nodes[dest_id].base.station; Station *st2 = Station::GetIfValid(to); if (st2 == nullptr || st2->goods[this->Cargo()].link_graph != this->link_graph.index || - st2->goods[this->Cargo()].node != it->first || - (*lg)[node_id][it->first].LastUpdate() == INVALID_DATE) { + st2->goods[this->Cargo()].node != dest_id || + !(*lg)[node_id].HasEdgeTo(dest_id) || + (*lg)[node_id][dest_id].LastUpdate() == INVALID_DATE) { /* Edge has been removed. Delete flows. */ StationIDStack erased = flows.DeleteFlows(to); /* Delete old flows for source stations which have been deleted * from the new flows. This avoids flow cycles between old and * new flows. */ while (!erased.IsEmpty()) ge.flows.erase(erased.Pop()); - } else if ((*lg)[node_id][it->first].LastUnrestrictedUpdate() == INVALID_DATE) { + } else if ((*lg)[node_id][dest_id].last_restricted_update == INVALID_DATE) { /* Edge is fully restricted. */ flows.RestrictFlows(to); } @@ -180,39 +182,12 @@ LinkGraphJob::~LinkGraphJob() void LinkGraphJob::Init() { uint size = this->Size(); - this->nodes.resize(size); - this->edges.Resize(size, size); + this->nodes.reserve(size); for (uint i = 0; i < size; ++i) { - this->nodes[i].Init(this->link_graph[i].Supply()); - EdgeAnnotation *node_edges = this->edges[i]; - for (uint j = 0; j < size; ++j) { - node_edges[j].Init(); - } + this->nodes.emplace_back(this->link_graph.nodes[i], this->link_graph.Size()); } } -/** - * Initialize a linkgraph job edge. - */ -void LinkGraphJob::EdgeAnnotation::Init() -{ - this->demand = 0; - this->flow = 0; - this->unsatisfied_demand = 0; -} - -/** - * Initialize a Linkgraph job node. The underlying memory is expected to be - * freshly allocated, without any constructors having been called. - * @param supply Initial undelivered supply. - */ -void LinkGraphJob::NodeAnnotation::Init(uint supply) -{ - this->undelivered_supply = supply; - new (&this->flows) FlowStatMap; - new (&this->paths) PathList; -} - /** * Add this path as a new child to the given base path, thus making this path * a "fork" of the base path. @@ -246,9 +221,9 @@ void Path::Fork(Path *base, uint cap, int free_cap, uint dist) uint Path::AddFlow(uint new_flow, LinkGraphJob &job, uint max_saturation) { if (this->parent != nullptr) { - LinkGraphJob::Edge edge = job[this->parent->node][this->node]; + LinkGraphJob::EdgeAnnotation edge = job[this->parent->node][this->node]; if (max_saturation != UINT_MAX) { - uint usable_cap = edge.Capacity() * max_saturation / 100; + uint usable_cap = edge.base.capacity * max_saturation / 100; if (usable_cap > edge.Flow()) { new_flow = std::min(new_flow, usable_cap - edge.Flow()); } else { @@ -257,7 +232,7 @@ uint Path::AddFlow(uint new_flow, LinkGraphJob &job, uint max_saturation) } new_flow = this->parent->AddFlow(new_flow, job, max_saturation); if (this->flow == 0 && new_flow > 0) { - job[this->parent->node].Paths().push_front(this); + job[this->parent->node].paths.push_front(this); } edge.AddFlow(new_flow); } diff --git a/src/linkgraph/linkgraphjob.h b/src/linkgraph/linkgraphjob.h index 812afd1f71fac..5a25664ad271c 100644 --- a/src/linkgraph/linkgraphjob.h +++ b/src/linkgraph/linkgraphjob.h @@ -28,88 +28,36 @@ extern LinkGraphJobPool _link_graph_job_pool; * Class for calculation jobs to be run on link graphs. */ class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{ -private: +public: /** - * Annotation for a link graph edge. + * Demand between two nodes. */ - struct EdgeAnnotation { + struct DemandAnnotation { uint demand; ///< Transport demand between the nodes. uint unsatisfied_demand; ///< Demand over this edge that hasn't been satisfied yet. - uint flow; ///< Planned flow over this edge. - void Init(); }; /** - * Annotation for a link graph node. - */ - struct NodeAnnotation { - uint undelivered_supply; ///< Amount of supply that hasn't been distributed yet. - PathList paths; ///< Paths through this node, sorted so that those with flow == 0 are in the back. - FlowStatMap flows; ///< Planned flows to other nodes. - void Init(uint supply); - }; - - typedef std::vector NodeAnnotationVector; - typedef SmallMatrix EdgeAnnotationMatrix; - - friend SaveLoadTable GetLinkGraphJobDesc(); - friend class LinkGraphSchedule; - -protected: - const LinkGraph link_graph; ///< Link graph to by analyzed. Is copied when job is started and mustn't be modified later. - const LinkGraphSettings settings; ///< Copy of _settings_game.linkgraph at spawn time. - std::thread thread; ///< Thread the job is running in or a default-constructed thread if it's running in the main thread. - Date join_date; ///< Date when the job is to be joined. - NodeAnnotationVector nodes; ///< Extra node data necessary for link graph calculation. - EdgeAnnotationMatrix edges; ///< Extra edge data necessary for link graph calculation. - std::atomic job_completed; ///< Is the job still running. This is accessed by multiple threads and reads may be stale. - std::atomic job_aborted; ///< Has the job been aborted. This is accessed by multiple threads and reads may be stale. - - void EraseFlows(NodeID from); - void JoinThread(); - void SpawnThread(); - -public: - - /** - * A job edge. Wraps a link graph edge and an edge annotation. The - * annotation can be modified, the edge is constant. + * Annotation for a link graph edge. */ - class Edge : public LinkGraph::ConstEdge { - private: - EdgeAnnotation &anno; ///< Annotation being wrapped. - public: - /** - * Constructor. - * @param edge Link graph edge to be wrapped. - * @param anno Annotation to be wrapped. - */ - Edge(const LinkGraph::BaseEdge &edge, EdgeAnnotation &anno) : - LinkGraph::ConstEdge(edge), anno(anno) {} + struct EdgeAnnotation { + const LinkGraph::BaseEdge &base; ///< Reference to the edge that is annotated. - /** - * Get the transport demand between end the points of the edge. - * @return Demand. - */ - uint Demand() const { return this->anno.demand; } + uint flow; ///< Planned flow over this edge. - /** - * Get the transport demand that hasn't been satisfied by flows, yet. - * @return Unsatisfied demand. - */ - uint UnsatisfiedDemand() const { return this->anno.unsatisfied_demand; } + EdgeAnnotation(const LinkGraph::BaseEdge &base) : base(base), flow(0) {} /** * Get the total flow on the edge. * @return Flow. */ - uint Flow() const { return this->anno.flow; } + uint Flow() const { return this->flow; } /** * Add some flow. * @param flow Flow to be added. */ - void AddFlow(uint flow) { this->anno.flow += flow; } + void AddFlow(uint flow) { this->flow += flow; } /** * Remove some flow. @@ -117,139 +65,81 @@ class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{ */ void RemoveFlow(uint flow) { - assert(flow <= this->anno.flow); - this->anno.flow -= flow; + assert(flow <= this->flow); + this->flow -= flow; } - /** - * Add some (not yet satisfied) demand. - * @param demand Demand to be added. - */ - void AddDemand(uint demand) + friend inline bool operator <(NodeID dest, const EdgeAnnotation &rhs) { - this->anno.demand += demand; - this->anno.unsatisfied_demand += demand; - } - - /** - * Satisfy some demand. - * @param demand Demand to be satisfied. - */ - void SatisfyDemand(uint demand) - { - assert(demand <= this->anno.unsatisfied_demand); - this->anno.unsatisfied_demand -= demand; + return dest < rhs.base.dest_node; } }; /** - * Iterator for job edges. + * Annotation for a link graph node. */ - class EdgeIterator : public LinkGraph::BaseEdgeIterator { - EdgeAnnotation *base_anno; ///< Array of annotations to be (indirectly) iterated. - public: - /** - * Constructor. - * @param base Array of edges to be iterated. - * @param base_anno Array of annotations to be iterated. - * @param current Start offset of iteration. - */ - EdgeIterator(const LinkGraph::BaseEdge *base, EdgeAnnotation *base_anno, NodeID current) : - LinkGraph::BaseEdgeIterator(base, current), - base_anno(base_anno) {} + struct NodeAnnotation { + const LinkGraph::BaseNode &base; ///< Reference to the node that is annotated. - /** - * Dereference. - * @return Pair of the edge currently pointed to and the ID of its - * other end. - */ - std::pair operator*() const + uint undelivered_supply; ///< Amount of supply that hasn't been distributed yet. + PathList paths; ///< Paths through this node, sorted so that those with flow == 0 are in the back. + FlowStatMap flows; ///< Planned flows to other nodes. + + std::vector edges; ///< Annotations for all edges originating at this node. + std::vector demands; ///< Annotations for the demand to all other nodes. + + NodeAnnotation(const LinkGraph::BaseNode &node, size_t size) : base(node), undelivered_supply(node.supply), paths(), flows() { - return std::pair(this->current, Edge(this->base[this->current], this->base_anno[this->current])); + this->edges.reserve(node.edges.size()); + for (auto &e : node.edges) this->edges.emplace_back(e); + this->demands.resize(size); } /** - * Dereference. Has to be repeated here as operator* is different than - * in LinkGraph::EdgeWrapper. - * @return Fake pointer to pair of NodeID/Edge. + * Retrieve an edge starting at this node. + * @param to Remote end of the edge. + * @return Edge between this node and "to". */ - FakePointer operator->() const { - return FakePointer(this->operator*()); + EdgeAnnotation &operator[](NodeID to) + { + auto it = std::find_if(this->edges.begin(), this->edges.end(), [=] (const EdgeAnnotation &e) { return e.base.dest_node == to; }); + assert(it != this->edges.end()); + return *it; } - }; - - /** - * Link graph job node. Wraps a constant link graph node and a modifiable - * node annotation. - */ - class Node : public LinkGraph::ConstNode { - private: - NodeAnnotation &node_anno; ///< Annotation being wrapped. - EdgeAnnotation *edge_annos; ///< Edge annotations belonging to this node. - public: - - /** - * Constructor. - * @param lgj Job to take the node from. - * @param node ID of the node. - */ - Node (LinkGraphJob *lgj, NodeID node) : - LinkGraph::ConstNode(&lgj->link_graph, node), - node_anno(lgj->nodes[node]), edge_annos(lgj->edges[node]) - {} /** - * Retrieve an edge starting at this node. Mind that this returns an - * object, not a reference. + * Retrieve an edge starting at this node. * @param to Remote end of the edge. * @return Edge between this node and "to". */ - Edge operator[](NodeID to) const { return Edge(this->edges[to], this->edge_annos[to]); } - - /** - * Iterator for the "begin" of the edge array. Only edges with capacity - * are iterated. The others are skipped. - * @return Iterator pointing to the first edge. - */ - EdgeIterator Begin() const { return EdgeIterator(this->edges, this->edge_annos, index); } - - /** - * Iterator for the "end" of the edge array. Only edges with capacity - * are iterated. The others are skipped. - * @return Iterator pointing beyond the last edge. - */ - EdgeIterator End() const { return EdgeIterator(this->edges, this->edge_annos, INVALID_NODE); } - - /** - * Get amount of supply that hasn't been delivered, yet. - * @return Undelivered supply. - */ - uint UndeliveredSupply() const { return this->node_anno.undelivered_supply; } - - /** - * Get the flows running through this node. - * @return Flows. - */ - FlowStatMap &Flows() { return this->node_anno.flows; } + const EdgeAnnotation &operator[](NodeID to) const + { + auto it = std::find_if(this->edges.begin(), this->edges.end(), [=] (const EdgeAnnotation &e) { return e.base.dest_node == to; }); + assert(it != this->edges.end()); + return *it; + } /** - * Get a constant version of the flows running through this node. - * @return Flows. + * Get the transport demand between end the points of the edge. + * @return Demand. */ - const FlowStatMap &Flows() const { return this->node_anno.flows; } + uint DemandTo(NodeID to) const { return this->demands[to].demand; } /** - * Get the paths this node is part of. Paths are always expected to be - * sorted so that those with flow == 0 are in the back of the list. - * @return Paths. + * Get the transport demand that hasn't been satisfied by flows, yet. + * @return Unsatisfied demand. */ - PathList &Paths() { return this->node_anno.paths; } + uint UnsatisfiedDemandTo(NodeID to) const { return this->demands[to].unsatisfied_demand; } /** - * Get a constant version of the paths this node is part of. - * @return Paths. + * Satisfy some demand. + * @param demand Demand to be satisfied. */ - const PathList &Paths() const { return this->node_anno.paths; } + void SatisfyDemandTo(NodeID to, uint demand) + { + assert(demand <= this->demands[to].unsatisfied_demand); + this->demands[to].unsatisfied_demand -= demand; + } /** * Deliver some supply, adding demand to the respective edge. @@ -258,11 +148,32 @@ class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{ */ void DeliverSupply(NodeID to, uint amount) { - this->node_anno.undelivered_supply -= amount; - (*this)[to].AddDemand(amount); + this->undelivered_supply -= amount; + this->demands[to].demand += amount; + this->demands[to].unsatisfied_demand += amount; } }; +private: + typedef std::vector NodeAnnotationVector; + + friend SaveLoadTable GetLinkGraphJobDesc(); + friend class LinkGraphSchedule; + +protected: + const LinkGraph link_graph; ///< Link graph to by analyzed. Is copied when job is started and mustn't be modified later. + const LinkGraphSettings settings; ///< Copy of _settings_game.linkgraph at spawn time. + std::thread thread; ///< Thread the job is running in or a default-constructed thread if it's running in the main thread. + Date join_date; ///< Date when the job is to be joined. + NodeAnnotationVector nodes; ///< Extra node data necessary for link graph calculation. + std::atomic job_completed; ///< Is the job still running. This is accessed by multiple threads and reads may be stale. + std::atomic job_aborted; ///< Has the job been aborted. This is accessed by multiple threads and reads may be stale. + + void EraseFlows(NodeID from); + void JoinThread(); + void SpawnThread(); + +public: /** * Bare constructor, only for save/load. link_graph, join_date and actually * settings have to be brutally const-casted in order to populate them. @@ -326,7 +237,7 @@ class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{ * @param num ID of the node. * @return the Requested node. */ - inline Node operator[](NodeID num) { return Node(this, num); } + inline NodeAnnotation &operator[](NodeID num) { return this->nodes[num]; } /** * Get the size of the underlying link graph. diff --git a/src/linkgraph/linkgraphjob_base.h b/src/linkgraph/linkgraphjob_base.h index a05d6ef8d68b2..1a0c3667b2600 100644 --- a/src/linkgraph/linkgraphjob_base.h +++ b/src/linkgraph/linkgraphjob_base.h @@ -14,8 +14,7 @@ #include "linkgraphjob.h" #include "linkgraphschedule.h" -typedef LinkGraphJob::Node Node; -typedef LinkGraphJob::Edge Edge; -typedef LinkGraphJob::EdgeIterator EdgeIterator; +typedef LinkGraphJob::NodeAnnotation Node; +typedef LinkGraphJob::EdgeAnnotation Edge; #endif /* LINKGRAPHJOB_BASE_H */ diff --git a/src/linkgraph/mcf.cpp b/src/linkgraph/mcf.cpp index 8cd73cb916c6a..c7b5d6d075eba 100644 --- a/src/linkgraph/mcf.cpp +++ b/src/linkgraph/mcf.cpp @@ -94,8 +94,9 @@ class CapacityAnnotation : public Path { class GraphEdgeIterator { private: LinkGraphJob &job; ///< Job being executed - EdgeIterator i; ///< Iterator pointing to current edge. - EdgeIterator end; ///< Iterator pointing beyond last edge. + + std::vector::const_iterator i; ///< Iterator pointing to current edge. + std::vector::const_iterator end; ///< Iterator pointing beyond last edge. public: @@ -103,9 +104,7 @@ class GraphEdgeIterator { * Construct a GraphEdgeIterator. * @param job Job to iterate on. */ - GraphEdgeIterator(LinkGraphJob &job) : job(job), - i(nullptr, nullptr, INVALID_NODE), end(nullptr, nullptr, INVALID_NODE) - {} + GraphEdgeIterator(LinkGraphJob &job) : job(job), i(), end() {} /** * Setup the node to start iterating at. @@ -114,8 +113,8 @@ class GraphEdgeIterator { */ void SetNode(NodeID source, NodeID node) { - this->i = this->job[node].Begin(); - this->end = this->job[node].End(); + this->i = this->job[node].edges.cbegin(); + this->end = this->job[node].edges.cend(); } /** @@ -124,7 +123,7 @@ class GraphEdgeIterator { */ NodeID Next() { - return this->i != this->end ? (this->i++)->first : INVALID_NODE; + return this->i != this->end ? (this->i++)->base.dest_node : INVALID_NODE; } }; @@ -152,7 +151,7 @@ class FlowEdgeIterator { FlowEdgeIterator(LinkGraphJob &job) : job(job) { for (NodeID i = 0; i < job.Size(); ++i) { - StationID st = job[i].Station(); + StationID st = job[i].base.station; if (st >= this->station_to_node.size()) { this->station_to_node.resize(st + 1); } @@ -167,8 +166,8 @@ class FlowEdgeIterator { */ void SetNode(NodeID source, NodeID node) { - const FlowStatMap &flows = this->job[node].Flows(); - FlowStatMap::const_iterator it = flows.find(this->job[source].Station()); + const FlowStatMap &flows = this->job[node].flows; + FlowStatMap::const_iterator it = flows.find(this->job[source].base.station); if (it != flows.end()) { this->it = it->second.GetShares()->begin(); this->end = it->second.GetShares()->end(); @@ -277,8 +276,8 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths) iter.SetNode(source_node, from); for (NodeID to = iter.Next(); to != INVALID_NODE; to = iter.Next()) { if (to == from) continue; // Not a real edge but a consumption sign. - Edge edge = this->job[from][to]; - uint capacity = edge.Capacity(); + const Edge &edge = this->job[from][to]; + uint capacity = edge.base.capacity; if (this->max_saturation != UINT_MAX) { capacity *= this->max_saturation; capacity /= 100; @@ -290,9 +289,9 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths) bool express = IsCargoInClass(this->job.Cargo(), CC_PASSENGERS) || IsCargoInClass(this->job.Cargo(), CC_MAIL) || IsCargoInClass(this->job.Cargo(), CC_EXPRESS); - uint distance = DistanceMaxPlusManhattan(this->job[from].XY(), this->job[to].XY()) + 1; + uint distance = DistanceMaxPlusManhattan(this->job[from].base.xy, this->job[to].base.xy) + 1; /* Compute a default travel time from the distance and an average speed of 1 tile/day. */ - uint time = (edge.TravelTime() != 0) ? edge.TravelTime() + DAY_TICKS : distance * DAY_TICKS; + uint time = (edge.base.TravelTime() != 0) ? edge.base.TravelTime() + DAY_TICKS : distance * DAY_TICKS; uint distance_anno = express ? time : distance; Tannotation *dest = static_cast(paths[to]); @@ -336,19 +335,20 @@ void MultiCommodityFlow::CleanupPaths(NodeID source_id, PathVector &paths) /** * Push flow along a path and update the unsatisfied_demand of the associated * edge. - * @param edge Edge whose ends the path connects. + * @param node Node where the path starts. + * @param to Node where the path ends. * @param path End of the path the flow should be pushed on. * @param accuracy Accuracy of the calculation. * @param max_saturation If < UINT_MAX only push flow up to the given * saturation, otherwise the path can be "overloaded". */ -uint MultiCommodityFlow::PushFlow(Edge &edge, Path *path, uint accuracy, +uint MultiCommodityFlow::PushFlow(Node &node, NodeID to, Path *path, uint accuracy, uint max_saturation) { - assert(edge.UnsatisfiedDemand() > 0); - uint flow = Clamp(edge.Demand() / accuracy, 1, edge.UnsatisfiedDemand()); + assert(node.UnsatisfiedDemandTo(to) > 0); + uint flow = Clamp(node.DemandTo(to) / accuracy, 1, node.UnsatisfiedDemandTo(to)); flow = path->AddFlow(flow, this->job, max_saturation); - edge.SatisfyDemand(flow); + node.SatisfyDemandTo(to, flow); return flow; } @@ -382,7 +382,7 @@ void MCF1stPass::EliminateCycle(PathVector &path, Path *cycle_begin, uint flow) NodeID prev = cycle_begin->GetNode(); cycle_begin->ReduceFlow(flow); if (cycle_begin->GetFlow() == 0) { - PathList &node_paths = this->job[cycle_begin->GetParent()->GetNode()].Paths(); + PathList &node_paths = this->job[cycle_begin->GetParent()->GetNode()].paths; for (PathList::iterator i = node_paths.begin(); i != node_paths.end(); ++i) { if (*i == cycle_begin) { node_paths.erase(i); @@ -392,7 +392,7 @@ void MCF1stPass::EliminateCycle(PathVector &path, Path *cycle_begin, uint flow) } } cycle_begin = path[prev]; - Edge edge = this->job[prev][cycle_begin->GetNode()]; + Edge &edge = this->job[prev][cycle_begin->GetNode()]; edge.RemoveFlow(flow); } while (cycle_begin != cycle_end); } @@ -416,7 +416,7 @@ bool MCF1stPass::EliminateCycles(PathVector &path, NodeID origin_id, NodeID next if (at_next_pos == nullptr) { /* Summarize paths; add up the paths with the same source and next hop * in one path each. */ - PathList &paths = this->job[next_id].Paths(); + PathList &paths = this->job[next_id].paths; PathViaMap next_hops; for (PathList::iterator i = paths.begin(); i != paths.end();) { Path *new_child = *i; @@ -513,25 +513,25 @@ MCF1stPass::MCF1stPass(LinkGraphJob &job) : MultiCommodityFlow(job) /* First saturate the shortest paths. */ this->Dijkstra(source, paths); + Node &src_node = job[source]; bool source_demand_left = false; for (NodeID dest = 0; dest < size; ++dest) { - Edge edge = job[source][dest]; - if (edge.UnsatisfiedDemand() > 0) { + if (src_node.UnsatisfiedDemandTo(dest) > 0) { Path *path = paths[dest]; assert(path != nullptr); /* Generally only allow paths that don't exceed the * available capacity. But if no demand has been assigned * yet, make an exception and allow any valid path *once*. */ - if (path->GetFreeCapacity() > 0 && this->PushFlow(edge, path, + if (path->GetFreeCapacity() > 0 && this->PushFlow(src_node, dest, path, accuracy, this->max_saturation) > 0) { /* If a path has been found there is a chance we can * find more. */ - more_loops = more_loops || (edge.UnsatisfiedDemand() > 0); - } else if (edge.UnsatisfiedDemand() == edge.Demand() && + more_loops = more_loops || (src_node.UnsatisfiedDemandTo(dest) > 0); + } else if (src_node.UnsatisfiedDemandTo(dest) == src_node.DemandTo(dest) && path->GetFreeCapacity() > INT_MIN) { - this->PushFlow(edge, path, accuracy, UINT_MAX); + this->PushFlow(src_node, dest, path, accuracy, UINT_MAX); } - if (edge.UnsatisfiedDemand() > 0) source_demand_left = true; + if (src_node.UnsatisfiedDemandTo(dest) > 0) source_demand_left = true; } } finished_sources[source] = !source_demand_left; @@ -560,13 +560,13 @@ MCF2ndPass::MCF2ndPass(LinkGraphJob &job) : MultiCommodityFlow(job) this->Dijkstra(source, paths); + Node &src_node = job[source]; bool source_demand_left = false; for (NodeID dest = 0; dest < size; ++dest) { - Edge edge = this->job[source][dest]; Path *path = paths[dest]; - if (edge.UnsatisfiedDemand() > 0 && path->GetFreeCapacity() > INT_MIN) { - this->PushFlow(edge, path, accuracy, UINT_MAX); - if (edge.UnsatisfiedDemand() > 0) { + if (src_node.UnsatisfiedDemandTo(dest) > 0 && path->GetFreeCapacity() > INT_MIN) { + this->PushFlow(src_node, dest, path, accuracy, UINT_MAX); + if (src_node.UnsatisfiedDemandTo(dest) > 0) { demand_left = true; source_demand_left = true; } diff --git a/src/linkgraph/mcf.h b/src/linkgraph/mcf.h index 4ad598c574edb..e1e83e389802c 100644 --- a/src/linkgraph/mcf.h +++ b/src/linkgraph/mcf.h @@ -24,7 +24,7 @@ class MultiCommodityFlow { template void Dijkstra(NodeID from, PathVector &paths); - uint PushFlow(Edge &edge, Path *path, uint accuracy, uint max_saturation); + uint PushFlow(Node &node, NodeID to, Path *path, uint accuracy, uint max_saturation); void CleanupPaths(NodeID source, PathVector &paths); diff --git a/src/linkgraph/refresh.cpp b/src/linkgraph/refresh.cpp index 2665f92a9fb79..f62a4347d369b 100644 --- a/src/linkgraph/refresh.cpp +++ b/src/linkgraph/refresh.cpp @@ -203,27 +203,28 @@ void LinkRefresher::RefreshStats(const Order *cur, const Order *next) StationID next_station = next->GetDestination(); Station *st = Station::GetIfValid(cur->GetDestination()); if (st != nullptr && next_station != INVALID_STATION && next_station != st->index) { + Station *st_to = Station::Get(next_station); for (CargoID c = 0; c < NUM_CARGO; c++) { /* Refresh the link and give it a minimum capacity. */ uint cargo_quantity = this->capacities[c]; if (cargo_quantity == 0) continue; + if (this->vehicle->GetDisplayMaxSpeed() == 0) continue; + /* If not allowed to merge link graphs, make sure the stations are * already in the same link graph. */ - if (!this->allow_merge && st->goods[c].link_graph != Station::Get(next_station)->goods[c].link_graph) { + if (!this->allow_merge && st->goods[c].link_graph != st_to->goods[c].link_graph) { continue; } /* A link is at least partly restricted if a vehicle can't load at its source. */ EdgeUpdateMode restricted_mode = (cur->GetLoadType() & OLFB_NO_LOAD) == 0 ? EUM_UNRESTRICTED : EUM_RESTRICTED; - Station *st_to = Station::GetIfValid(next_station); /* This estimates the travel time of the link as the time needed * to travel between the stations at half the max speed of the consist. * The result is in tiles/tick (= 2048 km-ish/h). */ - uint32 time_estimate = (st_to != nullptr) ? - DistanceManhattan(st->xy, st_to->xy) * 4096U / this->vehicle->GetDisplayMaxSpeed() : 0; + uint32 time_estimate = DistanceManhattan(st->xy, st_to->xy) * 4096U / this->vehicle->GetDisplayMaxSpeed(); /* If the vehicle is currently full loading, increase the capacities at the station * where it is loading by an estimate of what it would have transported if it wasn't diff --git a/src/main_gui.cpp b/src/main_gui.cpp index b2c4bfee482b0..05ee75d2f3919 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -157,7 +157,7 @@ void FixTitleGameZoom(int zoom_adjust) { if (_game_mode != GM_MENU) return; - Viewport *vp = FindWindowByClass(WC_MAIN_WINDOW)->viewport; + Viewport *vp = GetMainWindow()->viewport; /* Adjust the zoom in/out. * Can't simply add, since operator+ is not defined on the ZoomLevel type. */ @@ -222,9 +222,9 @@ struct MainWindow : Window ResizeWindow(this, _screen.width, _screen.height); NWidgetViewport *nvp = this->GetWidget(WID_M_VIEWPORT); - nvp->InitializeViewport(this, TileXY(32, 32), ZOOM_LVL_VIEWPORT); + nvp->InitializeViewport(this, TileXY(32, 32), ScaleZoomGUI(ZOOM_LVL_VIEWPORT)); - this->viewport->overlay = new LinkGraphOverlay(this, WID_M_VIEWPORT, 0, 0, 3); + this->viewport->overlay = new LinkGraphOverlay(this, WID_M_VIEWPORT, 0, 0, 2); this->refresh.SetInterval(LINKGRAPH_DELAY); } @@ -248,8 +248,8 @@ struct MainWindow : Window this->DrawWidgets(); if (_game_mode == GM_MENU) { static const SpriteID title_sprites[] = {SPR_OTTD_O, SPR_OTTD_P, SPR_OTTD_E, SPR_OTTD_N, SPR_OTTD_T, SPR_OTTD_T, SPR_OTTD_D}; - static const uint LETTER_SPACING = 10; - int name_width = (lengthof(title_sprites) - 1) * LETTER_SPACING; + uint letter_spacing = ScaleGUITrad(10); + int name_width = (lengthof(title_sprites) - 1) * letter_spacing; for (uint i = 0; i < lengthof(title_sprites); i++) { name_width += GetSpriteSize(title_sprites[i]).width; @@ -257,8 +257,8 @@ struct MainWindow : Window int off_x = (this->width - name_width) / 2; for (uint i = 0; i < lengthof(title_sprites); i++) { - DrawSprite(title_sprites[i], PAL_NONE, off_x, 50); - off_x += GetSpriteSize(title_sprites[i]).width + LETTER_SPACING; + DrawSprite(title_sprites[i], PAL_NONE, off_x, ScaleGUITrad(50)); + off_x += GetSpriteSize(title_sprites[i]).width + letter_spacing; } } } @@ -435,6 +435,12 @@ struct MainWindow : Window } } + bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond) override + { + if (widget != WID_M_VIEWPORT) return false; + return this->viewport->overlay->ShowTooltip(pt, close_cond); + } + /** * Some data on this window has become invalid. * @param data Information about the changed data. diff --git a/src/map.cpp b/src/map.cpp index 2a08d656e6ba1..e5bbfac250e51 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -20,15 +20,15 @@ extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned); #endif -uint _map_log_x; ///< 2^_map_log_x == _map_size_x -uint _map_log_y; ///< 2^_map_log_y == _map_size_y -uint _map_size_x; ///< Size of the map along the X -uint _map_size_y; ///< Size of the map along the Y -uint _map_size; ///< The number of tiles on the map -uint _map_tile_mask; ///< _map_size - 1 (to mask the mapsize) +/* static */ uint Map::log_x; ///< 2^_map_log_x == _map_size_x +/* static */ uint Map::log_y; ///< 2^_map_log_y == _map_size_y +/* static */ uint Map::size_x; ///< Size of the map along the X +/* static */ uint Map::size_y; ///< Size of the map along the Y +/* static */ uint Map::size; ///< The number of tiles on the map +/* static */ uint Map::tile_mask; ///< _map_size - 1 (to mask the mapsize) -Tile *_m = nullptr; ///< Tiles of the map -TileExtended *_me = nullptr; ///< Extended Tiles of the map +/* static */ Tile::TileBase *Tile::base_tiles = nullptr; ///< Base tiles of the map +/* static */ Tile::TileExtended *Tile::extended_tiles = nullptr; ///< Extended tiles of the map /** @@ -36,7 +36,7 @@ TileExtended *_me = nullptr; ///< Extended Tiles of the map * @param size_x the width of the map along the NE/SW edge * @param size_y the 'height' of the map along the SE/NW edge */ -void AllocateMap(uint size_x, uint size_y) +/* static */ void Map::Allocate(uint size_x, uint size_y) { /* Make sure that the map size is within the limits and that * size of both axes is a power of 2. */ @@ -49,18 +49,18 @@ void AllocateMap(uint size_x, uint size_y) Debug(map, 1, "Allocating map of size {}x{}", size_x, size_y); - _map_log_x = FindFirstBit(size_x); - _map_log_y = FindFirstBit(size_y); - _map_size_x = size_x; - _map_size_y = size_y; - _map_size = size_x * size_y; - _map_tile_mask = _map_size - 1; + Map::log_x = FindFirstBit(size_x); + Map::log_y = FindFirstBit(size_y); + Map::size_x = size_x; + Map::size_y = size_y; + Map::size = size_x * size_y; + Map::tile_mask = Map::size - 1; - free(_m); - free(_me); + free(Tile::base_tiles); + free(Tile::extended_tiles); - _m = CallocT(_map_size); - _me = CallocT(_map_size); + Tile::base_tiles = CallocT(Map::size); + Tile::extended_tiles = CallocT(Map::size); } @@ -73,14 +73,14 @@ TileIndex TileAdd(TileIndex tile, TileIndexDiff add, uint x; uint y; - dx = add & MapMaxX(); - if (dx >= (int)MapSizeX() / 2) dx -= MapSizeX(); - dy = (add - dx) / (int)MapSizeX(); + dx = add & Map::MaxX(); + if (dx >= (int)Map::SizeX() / 2) dx -= Map::SizeX(); + dy = (add - dx) / (int)Map::SizeX(); x = TileX(tile) + dx; y = TileY(tile) + dy; - if (x >= MapSizeX() || y >= MapSizeY()) { + if (x >= Map::SizeX() || y >= Map::SizeY()) { char buf[512]; seprintf(buf, lastof(buf), "TILE_ADD(%s) when adding 0x%.4X and 0x%.4X failed", @@ -92,7 +92,7 @@ TileIndex TileAdd(TileIndex tile, TileIndexDiff add, #endif } - assert(TileXY(x, y) == TILE_MASK(tile + add)); + assert(TileXY(x, y) == Map::WrapToMap(tile + add)); return TileXY(x, y); } @@ -120,7 +120,7 @@ TileIndex TileAddWrap(TileIndex tile, int addx, int addy) if ((x == 0 || y == 0) && _settings_game.construction.freeform_edges) return INVALID_TILE; /* Are we about to wrap? */ - if (x >= MapMaxX() || y >= MapMaxY()) return INVALID_TILE; + if (x >= Map::MaxX() || y >= Map::MaxY()) return INVALID_TILE; return TileXY(x, y); } @@ -218,8 +218,8 @@ uint DistanceFromEdge(TileIndex tile) { const uint xl = TileX(tile); const uint yl = TileY(tile); - const uint xh = MapSizeX() - 1 - xl; - const uint yh = MapSizeY() - 1 - yl; + const uint xh = Map::SizeX() - 1 - xl; + const uint yh = Map::SizeY() - 1 - yl; const uint minl = std::min(xl, yl); const uint minh = std::min(xh, yh); return std::min(minl, minh); @@ -236,8 +236,8 @@ uint DistanceFromEdgeDir(TileIndex tile, DiagDirection dir) switch (dir) { case DIAGDIR_NE: return TileX(tile) - (_settings_game.construction.freeform_edges ? 1 : 0); case DIAGDIR_NW: return TileY(tile) - (_settings_game.construction.freeform_edges ? 1 : 0); - case DIAGDIR_SW: return MapMaxX() - TileX(tile) - 1; - case DIAGDIR_SE: return MapMaxY() - TileY(tile) - 1; + case DIAGDIR_SW: return Map::MaxX() - TileX(tile) - 1; + case DIAGDIR_SE: return Map::MaxY() - TileY(tile) - 1; default: NOT_REACHED(); } } @@ -307,7 +307,7 @@ bool CircularTileSearch(TileIndex *tile, uint radius, uint w, uint h, TestTileOn for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { /* Is the tile within the map? */ for (uint j = extent[dir] + n * 2 + 1; j != 0; j--) { - if (x < MapSizeX() && y < MapSizeY()) { + if (x < Map::SizeX() && y < Map::SizeY()) { TileIndex t = TileXY(x, y); /* Is the callback successful? */ if (proc(t, user_data)) { @@ -346,8 +346,8 @@ uint GetClosestWaterDistance(TileIndex tile, bool water) int x = TileX(tile); int y = TileY(tile); - uint max_x = MapMaxX(); - uint max_y = MapMaxY(); + uint max_x = Map::MaxX(); + uint max_y = Map::MaxY(); uint min_xy = _settings_game.construction.freeform_edges ? 1 : 0; /* go in a 'spiral' with increasing manhattan distance in each iteration */ @@ -378,7 +378,7 @@ uint GetClosestWaterDistance(TileIndex tile, bool water) if (!water) { /* no land found - is this a water-only map? */ - for (TileIndex t = 0; t < MapSize(); t++) { + for (TileIndex t = 0; t < Map::Size(); t++) { if (!IsTileType(t, MP_VOID) && !IsTileType(t, MP_WATER)) return 0x1FF; } } diff --git a/src/map_func.h b/src/map_func.h index c780bd28ec2cf..c04796ff8b331 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -15,131 +15,353 @@ #include "map_type.h" #include "direction_func.h" -extern uint _map_tile_mask; - /** - * 'Wraps' the given tile to it is within the map. It does - * this by masking the 'high' bits of. - * @param x the tile to 'wrap' + * Wrapper class to abstract away the way the tiles are stored. It is + * intended to be used to access the "map" data of a single tile. + * + * The wrapper is expected to be fully optimized away by the compiler, even + * with low optimization levels except when completely disabling it. */ +class Tile { +private: + friend struct Map; + /** + * Data that is stored per tile. Also used TileExtended for this. + * Look at docs/landscape.html for the exact meaning of the members. + */ + struct TileBase { + byte type; ///< The type (bits 4..7), bridges (2..3), rainforest/desert (0..1) + byte height; ///< The height of the northern corner. + uint16 m2; ///< Primarily used for indices to towns, industries and stations + byte m1; ///< Primarily used for ownership information + byte m3; ///< General purpose + byte m4; ///< General purpose + byte m5; ///< General purpose + }; + + static_assert(sizeof(TileBase) == 8); -#define TILE_MASK(x) ((x) & _map_tile_mask) + /** + * Data that is stored per tile. Also used TileBase for this. + * Look at docs/landscape.html for the exact meaning of the members. + */ + struct TileExtended { + byte m6; ///< General purpose + byte m7; ///< Primarily used for newgrf support + uint16 m8; ///< General purpose + }; -/** - * Pointer to the tile-array. - * - * This variable points to the tile-array which contains the tiles of - * the map. - */ -extern Tile *_m; + static TileBase *base_tiles; ///< Pointer to the tile-array. + static TileExtended *extended_tiles; ///< Pointer to the extended tile-array. -/** - * Pointer to the extended tile-array. - * - * This variable points to the extended tile-array which contains the tiles - * of the map. - */ -extern TileExtended *_me; + TileIndex tile; ///< The tile to access the map data for. -void AllocateMap(uint size_x, uint size_y); +public: + /** + * Create the tile wrapper for the given tile. + * @param tile The tile to access the map for. + */ + debug_inline Tile(TileIndex tile) : tile(tile) {} -/** - * Logarithm of the map size along the X side. - * @note try to avoid using this one - * @return 2^"return value" == MapSizeX() - */ -static inline uint MapLogX() -{ - extern uint _map_log_x; - return _map_log_x; -} + /** + * Create the tile wrapper for the given tile. + * @param tile The tile to access the map for. + */ + Tile(uint tile) : tile(tile) {} -/** - * Logarithm of the map size along the y side. - * @note try to avoid using this one - * @return 2^"return value" == MapSizeY() - */ -static inline uint MapLogY() -{ - extern uint _map_log_y; - return _map_log_y; -} + /** + * Implicit conversion to the TileIndex. + */ + debug_inline constexpr operator TileIndex() const { return tile; } -/** - * Get the size of the map along the X - * @return the number of tiles along the X of the map - */ -static inline uint MapSizeX() -{ - extern uint _map_size_x; - return _map_size_x; -} + /** + * Implicit conversion to the uint for bounds checking. + */ + debug_inline constexpr operator uint() const { return tile; } -/** - * Get the size of the map along the Y - * @return the number of tiles along the Y of the map - */ -static inline uint MapSizeY() -{ - extern uint _map_size_y; - return _map_size_y; -} + /** + * The type (bits 4..7), bridges (2..3), rainforest/desert (0..1) + * + * Look at docs/landscape.html for the exact meaning of the data. + * @param tile The tile to get the data for. + * @return reference to the byte holding the data. + */ + debug_inline byte &type() + { + return base_tiles[tile].type; + } -/** - * Get the size of the map - * @return the number of tiles of the map - */ -static inline uint MapSize() -{ - extern uint _map_size; - return _map_size; -} + /** + * The height of the northern corner + * + * Look at docs/landscape.html for the exact meaning of the data. + * @param tile The tile to get the height for. + * @return reference to the byte holding the height. + */ + debug_inline byte &height() + { + return base_tiles[tile].height; + } -/** - * Gets the maximum X coordinate within the map, including MP_VOID - * @return the maximum X coordinate - */ -static inline uint MapMaxX() -{ - return MapSizeX() - 1; -} + /** + * Primarily used for ownership information + * + * Look at docs/landscape.html for the exact meaning of the data. + * @param tile The tile to get the data for. + * @return reference to the byte holding the data. + */ + debug_inline byte &m1() + { + return base_tiles[tile].m1; + } -/** - * Gets the maximum Y coordinate within the map, including MP_VOID - * @return the maximum Y coordinate - */ -static inline uint MapMaxY() -{ - return MapSizeY() - 1; -} + /** + * Primarily used for indices to towns, industries and stations + * + * Look at docs/landscape.html for the exact meaning of the data. + * @param tile The tile to get the data for. + * @return reference to the uint16 holding the data. + */ + debug_inline uint16 &m2() + { + return base_tiles[tile].m2; + } -/** - * Scales the given value by the map size, where the given value is - * for a 256 by 256 map. - * @param n the value to scale - * @return the scaled size - */ -static inline uint ScaleByMapSize(uint n) -{ - /* Subtract 12 from shift in order to prevent integer overflow - * for large values of n. It's safe since the min mapsize is 64x64. */ - return CeilDiv(n << (MapLogX() + MapLogY() - 12), 1 << 4); -} + /** + * General purpose + * + * Look at docs/landscape.html for the exact meaning of the data. + * @param tile The tile to get the data for. + * @return reference to the byte holding the data. + */ + debug_inline byte &m3() + { + return base_tiles[tile].m3; + } + /** + * General purpose + * + * Look at docs/landscape.html for the exact meaning of the data. + * @param tile The tile to get the data for. + * @return reference to the byte holding the data. + */ + debug_inline byte &m4() + { + return base_tiles[tile].m4; + } + + /** + * General purpose + * + * Look at docs/landscape.html for the exact meaning of the data. + * @param tile The tile to get the data for. + * @return reference to the byte holding the data. + */ + debug_inline byte &m5() + { + return base_tiles[tile].m5; + } + + /** + * General purpose + * + * Look at docs/landscape.html for the exact meaning of the data. + * @param tile The tile to get the data for. + * @return reference to the byte holding the data. + */ + debug_inline byte &m6() + { + return extended_tiles[tile].m6; + } + + /** + * Primarily used for newgrf support + * + * Look at docs/landscape.html for the exact meaning of the data. + * @param tile The tile to get the data for. + * @return reference to the byte holding the data. + */ + debug_inline byte &m7() + { + return extended_tiles[tile].m7; + } + + /** + * General purpose + * + * Look at docs/landscape.html for the exact meaning of the data. + * @param tile The tile to get the data for. + * @return reference to the uint16 holding the data. + */ + debug_inline uint16 &m8() + { + return extended_tiles[tile].m8; + } +}; /** - * Scales the given value by the maps circumference, where the given - * value is for a 256 by 256 map - * @param n the value to scale - * @return the scaled size + * Size related data of the map. */ -static inline uint ScaleByMapSize1D(uint n) -{ - /* Normal circumference for the X+Y is 256+256 = 1<<9 - * Note, not actually taking the full circumference into account, - * just half of it. */ - return CeilDiv((n << MapLogX()) + (n << MapLogY()), 1 << 9); -} +struct Map { +private: + /** + * Iterator to iterate all Tiles + */ + struct Iterator { + typedef Tile value_type; + typedef Tile *pointer; + typedef Tile &reference; + typedef size_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + explicit Iterator(TileIndex index) : index(index) {} + bool operator==(const Iterator &other) const { return this->index == other.index; } + bool operator!=(const Iterator &other) const { return !(*this == other); } + Tile operator*() const { return this->index; } + Iterator & operator++() { this->index++; return *this; } + private: + TileIndex index; + }; + + /* + * Iterable ensemble of all Tiles + */ + struct IterateWrapper { + Iterator begin() { return Iterator(0); } + Iterator end() { return Iterator(Map::Size()); } + bool empty() { return false; } + }; + + static uint log_x; ///< 2^_map_log_x == _map_size_x + static uint log_y; ///< 2^_map_log_y == _map_size_y + static uint size_x; ///< Size of the map along the X + static uint size_y; ///< Size of the map along the Y + static uint size; ///< The number of tiles on the map + static uint tile_mask; ///< _map_size - 1 (to mask the mapsize) + +public: + static void Allocate(uint size_x, uint size_y); + + /** + * Logarithm of the map size along the X side. + * @note try to avoid using this one + * @return 2^"return value" == Map::SizeX() + */ + debug_inline static uint LogX() + { + return Map::log_x; + } + + /** + * Logarithm of the map size along the y side. + * @note try to avoid using this one + * @return 2^"return value" == Map::SizeY() + */ + static inline uint LogY() + { + return Map::log_y; + } + + /** + * Get the size of the map along the X + * @return the number of tiles along the X of the map + */ + debug_inline static uint SizeX() + { + return Map::size_x; + } + + /** + * Get the size of the map along the Y + * @return the number of tiles along the Y of the map + */ + static inline uint SizeY() + { + return Map::size_y; + } + + /** + * Get the size of the map + * @return the number of tiles of the map + */ + debug_inline static uint Size() + { + return Map::size; + } + + /** + * Gets the maximum X coordinate within the map, including MP_VOID + * @return the maximum X coordinate + */ + debug_inline static uint MaxX() + { + return Map::SizeX() - 1; + } + + /** + * Gets the maximum Y coordinate within the map, including MP_VOID + * @return the maximum Y coordinate + */ + static inline uint MaxY() + { + return Map::SizeY() - 1; + } + + + /** + * 'Wraps' the given "tile" so it is within the map. + * It does this by masking the 'high' bits of. + * @param tile the tile to 'wrap' + */ + static inline TileIndex WrapToMap(uint tile) + { + return tile & Map::tile_mask; + } + + /** + * Scales the given value by the map size, where the given value is + * for a 256 by 256 map. + * @param n the value to scale + * @return the scaled size + */ + static inline uint ScaleBySize(uint n) + { + /* Subtract 12 from shift in order to prevent integer overflow + * for large values of n. It's safe since the min mapsize is 64x64. */ + return CeilDiv(n << (Map::LogX() + Map::LogY() - 12), 1 << 4); + } + + /** + * Scales the given value by the maps circumference, where the given + * value is for a 256 by 256 map + * @param n the value to scale + * @return the scaled size + */ + static inline uint ScaleBySize1D(uint n) + { + /* Normal circumference for the X+Y is 256+256 = 1<<9 + * Note, not actually taking the full circumference into account, + * just half of it. */ + return CeilDiv((n << Map::LogX()) + (n << Map::LogY()), 1 << 9); + } + + /** + * Check whether the map has been initialized, as to not try to save the map + * during crashlog when the map is not there yet. + * @return true when the map has been allocated/initialized. + */ + static bool IsInitialized() + { + return Tile::base_tiles != nullptr; + } + + /** + * Returns an iterable ensemble of all Tiles + * @return an iterable ensemble of all Tiles + */ + static IterateWrapper Iterate() { return IterateWrapper(); } +}; /** * An offset value between two tiles. @@ -160,9 +382,9 @@ typedef int32 TileIndexDiff; * @param y The y coordinate of the tile * @return The TileIndex calculated by the coordinate */ -static inline TileIndex TileXY(uint x, uint y) +debug_inline static TileIndex TileXY(uint x, uint y) { - return (y << MapLogX()) + x; + return (y << Map::LogX()) + x; } /** @@ -182,7 +404,7 @@ static inline TileIndexDiff TileDiffXY(int x, int y) * 0 << shift isn't optimized to 0 properly. * Typically x and y are constants, and then this doesn't result * in any actual multiplication in the assembly code.. */ - return (y * MapSizeX()) + x; + return (y * Map::SizeX()) + x; } /** @@ -191,9 +413,9 @@ static inline TileIndexDiff TileDiffXY(int x, int y) * @param y The virtual y coordinate of the tile. * @return The TileIndex calculated by the coordinate. */ -static inline TileIndex TileVirtXY(uint x, uint y) +debug_inline static TileIndex TileVirtXY(uint x, uint y) { - return (y >> 4 << MapLogX()) + (x >> 4); + return (y >> 4 << Map::LogX()) + (x >> 4); } @@ -202,9 +424,9 @@ static inline TileIndex TileVirtXY(uint x, uint y) * @param tile the tile to get the X component of * @return the X component */ -static inline uint TileX(TileIndex tile) +debug_inline static uint TileX(TileIndex tile) { - return tile.value & MapMaxX(); + return tile.value & Map::MaxX(); } /** @@ -212,9 +434,9 @@ static inline uint TileX(TileIndex tile) * @param tile the tile to get the Y component of * @return the Y component */ -static inline uint TileY(TileIndex tile) +debug_inline static uint TileY(TileIndex tile) { - return tile.value >> MapLogX(); + return tile.value >> Map::LogX(); } /** @@ -229,7 +451,7 @@ static inline uint TileY(TileIndex tile) */ static inline TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc) { - return (tidc.y << MapLogX()) + tidc.x; + return (tidc.y << Map::LogX()) + tidc.x; } @@ -302,7 +524,7 @@ static inline TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC dif int x = TileX(tile) + diff.x; int y = TileY(tile) + diff.y; /* Negative value will become big positive value after cast */ - if ((uint)x >= MapSizeX() || (uint)y >= MapSizeY()) return INVALID_TILE; + if ((uint)x >= Map::SizeX() || (uint)y >= Map::SizeY()) return INVALID_TILE; return TileXY(x, y); } @@ -423,7 +645,7 @@ bool CircularTileSearch(TileIndex *tile, uint radius, uint w, uint h, TestTileOn */ static inline TileIndex RandomTileSeed(uint32 r) { - return TILE_MASK(r); + return Map::WrapToMap(r); } /** diff --git a/src/map_type.h b/src/map_type.h index ba5af450a49a0..1b5c0fc975d8a 100644 --- a/src/map_type.h +++ b/src/map_type.h @@ -10,32 +10,6 @@ #ifndef MAP_TYPE_H #define MAP_TYPE_H -/** - * Data that is stored per tile. Also used TileExtended for this. - * Look at docs/landscape.html for the exact meaning of the members. - */ -struct Tile { - byte type; ///< The type (bits 4..7), bridges (2..3), rainforest/desert (0..1) - byte height; ///< The height of the northern corner. - uint16 m2; ///< Primarily used for indices to towns, industries and stations - byte m1; ///< Primarily used for ownership information - byte m3; ///< General purpose - byte m4; ///< General purpose - byte m5; ///< General purpose -}; - -static_assert(sizeof(Tile) == 8); - -/** - * Data that is stored per tile. Also used Tile for this. - * Look at docs/landscape.html for the exact meaning of the members. - */ -struct TileExtended { - byte m6; ///< General purpose - byte m7; ///< Primarily used for newgrf support - uint16 m8; ///< General purpose -}; - /** * An offset value between two tiles. * @@ -60,10 +34,10 @@ struct TileIndexDiffC { }; /** Minimal and maximal map width and height */ -static const uint MIN_MAP_SIZE_BITS = 6; ///< Minimal size of map is equal to 2 ^ MIN_MAP_SIZE_BITS -static const uint MAX_MAP_SIZE_BITS = 12; ///< Maximal size of map is equal to 2 ^ MAX_MAP_SIZE_BITS -static const uint MIN_MAP_SIZE = 1 << MIN_MAP_SIZE_BITS; ///< Minimal map size = 64 -static const uint MAX_MAP_SIZE = 1 << MAX_MAP_SIZE_BITS; ///< Maximal map size = 4096 +static const uint MIN_MAP_SIZE_BITS = 6; ///< Minimal size of map is equal to 2 ^ MIN_MAP_SIZE_BITS +static const uint MAX_MAP_SIZE_BITS = 12; ///< Maximal size of map is equal to 2 ^ MAX_MAP_SIZE_BITS +static const uint MIN_MAP_SIZE = 1U << MIN_MAP_SIZE_BITS; ///< Minimal map size = 64 +static const uint MAX_MAP_SIZE = 1U << MAX_MAP_SIZE_BITS; ///< Maximal map size = 4096 /** * Approximation of the length of a straight track, relative to a diagonal diff --git a/src/misc.cpp b/src/misc.cpp index c46a1c11d4369..a9b3e197597b3 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -11,7 +11,7 @@ #include "landscape.h" #include "news_func.h" #include "ai/ai.hpp" -#include "ai/ai_gui.hpp" +#include "script/script_gui.h" #include "newgrf.h" #include "newgrf_house.h" #include "economy_func.h" @@ -61,7 +61,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin * related to the new game we're about to start/load. */ UnInitWindowSystem(); - AllocateMap(size_x, size_y); + Map::Allocate(size_x, size_y); _pause_mode = PM_UNPAUSED; _game_speed = 100; @@ -100,7 +100,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin InitializeGraphGui(); InitializeObjectGui(); InitializeTownGui(); - InitializeAIGui(); + InitializeScriptGui(); InitializeTrees(); InitializeIndustries(); InitializeObjects(); diff --git a/src/misc/countedptr.hpp b/src/misc/countedptr.hpp index 8ced8d48e1b4e..ee0edea67c606 100644 --- a/src/misc/countedptr.hpp +++ b/src/misc/countedptr.hpp @@ -125,12 +125,6 @@ class CCountedPtr { return m_pT == nullptr; } - /** another way how to test for nullptr value */ - //inline bool operator == (const CCountedPtr &sp) const {return m_pT == sp.m_pT;} - - /** yet another way how to test for nullptr value */ - //inline bool operator != (const CCountedPtr &sp) const {return m_pT != sp.m_pT;} - /** assign pointer w/o incrementing ref count */ inline void Attach(Tcls *pT) { diff --git a/src/misc/lrucache.hpp b/src/misc/lrucache.hpp index f6cac49bfa27a..b0e950b2fc3af 100644 --- a/src/misc/lrucache.hpp +++ b/src/misc/lrucache.hpp @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * 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. diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index d1648e785d933..dc324cb1b14e0 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -43,8 +43,8 @@ CommandCost CmdIncreaseLoan(DoCommandFlag flags, LoanCommand cmd, Money amount) { Company *c = Company::Get(_current_company); - if (c->current_loan >= _economy.max_loan) { - SetDParam(0, _economy.max_loan); + if (c->current_loan >= _economy.max_loan * GetPaceFactor()) { + SetDParam(0, _economy.max_loan * GetPaceFactor()); return_cmd_error(STR_ERROR_MAXIMUM_PERMITTED_LOAN); } @@ -55,16 +55,18 @@ CommandCost CmdIncreaseLoan(DoCommandFlag flags, LoanCommand cmd, Money amount) loan = LOAN_INTERVAL; break; case LoanCommand::Max: // Take a loan as big as possible - loan = _economy.max_loan - c->current_loan; + loan = _economy.max_loan * GetPaceFactor() - c->current_loan; break; case LoanCommand::Amount: // Take the given amount of loan loan = amount; - if (loan < LOAN_INTERVAL || c->current_loan + loan > _economy.max_loan || loan % LOAN_INTERVAL != 0) return CMD_ERROR; + if (loan < LOAN_INTERVAL || c->current_loan + loan > _economy.max_loan * GetPaceFactor() || loan % LOAN_INTERVAL != 0) return CMD_ERROR; break; } - /* Overflow protection */ - if (c->money + c->current_loan + loan < c->money) return CMD_ERROR; + /* In case adding the loan triggers the overflow protection of Money, + * we would essentially be losing money as taking and repaying the loan + * immediately would not get us back to the same bank balance anymore. */ + if (c->money > Money::max() - loan) return CMD_ERROR; if (flags & DC_EXEC) { c->money += loan; @@ -223,6 +225,6 @@ CommandCost CmdChangeBankBalance(DoCommandFlag flags, TileIndex tile, Money delt } /* This command doesn't cost anything for deity. */ - CommandCost zero_cost(expenses_type, 0); + CommandCost zero_cost(expenses_type, (Money)0); return zero_cost; } diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 281a4179bf74a..b7616db390311 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -75,16 +75,15 @@ class LandInfoWindow : public Window { { if (widget != WID_LI_BACKGROUND) return; - uint y = r.top + WD_TEXTPANEL_TOP; + Rect ir = r.Shrink(WidgetDimensions::scaled.frametext); for (size_t i = 0; i < this->landinfo_data.size(); i++) { - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, this->landinfo_data[i], i == 0 ? TC_LIGHT_BLUE : TC_FROMSTRING, SA_HOR_CENTER); - y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; - if (i == 0) y += 4; + DrawString(ir, this->landinfo_data[i], i == 0 ? TC_LIGHT_BLUE : TC_FROMSTRING, SA_HOR_CENTER); + ir.top += FONT_HEIGHT_NORMAL + (i == 0 ? WidgetDimensions::scaled.vsep_wide : WidgetDimensions::scaled.vsep_normal); } if (!this->cargo_acceptance.empty()) { SetDParamStr(0, this->cargo_acceptance); - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, r.bottom - WD_TEXTPANEL_BOTTOM, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(ir, STR_JUST_RAW_STRING, TC_FROMSTRING, SA_CENTER); } } @@ -92,24 +91,23 @@ class LandInfoWindow : public Window { { if (widget != WID_LI_BACKGROUND) return; - size->height = WD_TEXTPANEL_TOP + WD_TEXTPANEL_BOTTOM; + size->height = WidgetDimensions::scaled.frametext.Vertical(); for (size_t i = 0; i < this->landinfo_data.size(); i++) { - uint width = GetStringBoundingBox(this->landinfo_data[i]).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; + uint width = GetStringBoundingBox(this->landinfo_data[i]).width + WidgetDimensions::scaled.frametext.Horizontal(); size->width = std::max(size->width, width); - size->height += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; - if (i == 0) size->height += 4; + size->height += FONT_HEIGHT_NORMAL + (i == 0 ? WidgetDimensions::scaled.vsep_wide : WidgetDimensions::scaled.vsep_normal); } if (!this->cargo_acceptance.empty()) { - uint width = GetStringBoundingBox(this->cargo_acceptance).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; + uint width = GetStringBoundingBox(this->cargo_acceptance).width + WidgetDimensions::scaled.frametext.Horizontal(); size->width = std::max(size->width, std::min(300u, width)); SetDParamStr(0, cargo_acceptance); - size->height += GetStringHeight(STR_JUST_RAW_STRING, size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT); + size->height += GetStringHeight(STR_JUST_RAW_STRING, size->width - WidgetDimensions::scaled.frametext.Horizontal()); } } - LandInfoWindow(TileIndex tile) : Window(&_land_info_desc), tile(tile) + LandInfoWindow(Tile tile) : Window(&_land_info_desc), tile(tile) { this->InitNested(); @@ -119,16 +117,16 @@ class LandInfoWindow : public Window { # define LANDINFOD_LEVEL 1 #endif Debug(misc, LANDINFOD_LEVEL, "TILE: {:#x} ({},{})", tile, TileX(tile), TileY(tile)); - Debug(misc, LANDINFOD_LEVEL, "type = {:#x}", _m[tile].type); - Debug(misc, LANDINFOD_LEVEL, "height = {:#x}", _m[tile].height); - Debug(misc, LANDINFOD_LEVEL, "m1 = {:#x}", _m[tile].m1); - Debug(misc, LANDINFOD_LEVEL, "m2 = {:#x}", _m[tile].m2); - Debug(misc, LANDINFOD_LEVEL, "m3 = {:#x}", _m[tile].m3); - Debug(misc, LANDINFOD_LEVEL, "m4 = {:#x}", _m[tile].m4); - Debug(misc, LANDINFOD_LEVEL, "m5 = {:#x}", _m[tile].m5); - Debug(misc, LANDINFOD_LEVEL, "m6 = {:#x}", _me[tile].m6); - Debug(misc, LANDINFOD_LEVEL, "m7 = {:#x}", _me[tile].m7); - Debug(misc, LANDINFOD_LEVEL, "m8 = {:#x}", _me[tile].m8); + Debug(misc, LANDINFOD_LEVEL, "type = {:#x}", tile.type()); + Debug(misc, LANDINFOD_LEVEL, "height = {:#x}", tile.height()); + Debug(misc, LANDINFOD_LEVEL, "m1 = {:#x}", tile.m1()); + Debug(misc, LANDINFOD_LEVEL, "m2 = {:#x}", tile.m2()); + Debug(misc, LANDINFOD_LEVEL, "m3 = {:#x}", tile.m3()); + Debug(misc, LANDINFOD_LEVEL, "m4 = {:#x}", tile.m4()); + Debug(misc, LANDINFOD_LEVEL, "m5 = {:#x}", tile.m5()); + Debug(misc, LANDINFOD_LEVEL, "m6 = {:#x}", tile.m6()); + Debug(misc, LANDINFOD_LEVEL, "m7 = {:#x}", tile.m7()); + Debug(misc, LANDINFOD_LEVEL, "m8 = {:#x}", tile.m8()); #undef LANDINFOD_LEVEL } @@ -409,10 +407,7 @@ static const char * const _credits[] = { u8"Original graphics by Simon Foster", u8"", u8"The OpenTTD team (in alphabetical order):", - u8" Grzegorz Duczy\u0144ski (adf88) - General coding (since 1.7.2)", - u8" Albert Hofkamp (Alberth) - GUI expert (since 0.7)", u8" Matthijs Kooijman (blathijs) - Pathfinder-guru, Debian port (since 0.3)", - u8" Ulf Hermann (fonsinchen) - Cargo Distribution (since 1.3)", u8" Christoph Elsenhans (frosch) - General coding (since 0.6)", u8" Lo\u00efc Guilloux (glx) - General / Windows Expert (since 0.4.5)", u8" Charles Pigott (LordAro) - General / Correctness police (since 1.9)", @@ -420,20 +415,24 @@ static const char * const _credits[] = { u8" Niels Martin Hansen (nielsm) - Music system, general coding (since 1.9)", u8" Owen Rudge (orudge) - Forum host, OS/2 port (since 0.1)", u8" Peter Nelson (peter1138) - Spiritual descendant from NewGRF gods (since 0.4.5)", - u8" Ingo von Borstel (planetmaker) - General, Support (since 1.1)", - u8" Remko Bijker (Rubidium) - Lead coder and way more (since 0.4.5)", - u8" Jos\u00e9 Soler (Terkhen) - General coding (since 1.0)", + u8" Remko Bijker (Rubidium) - Coder and way more (since 0.4.5)", + u8" Patric Stout (TrueBrain) - NoProgrammer (since 0.3), sys op", + u8" Tyler Trahan (2TallTyler) - General coding (since 13)", u8"", u8"Inactive Developers:", + u8" Grzegorz Duczy\u0144ski (adf88) - General coding (1.7 - 1.8)", + u8" Albert Hofkamp (Alberth) - GUI expert (0.7 - 1.9)", u8" Jean-Fran\u00e7ois Claeys (Belugas) - GUI, NewGRF and more (0.4.5 - 1.0)", u8" Bjarni Corfitzen (Bjarni) - MacOSX port, coder and vehicles (0.3 - 0.7)", u8" Victor Fischer (Celestar) - Programming everywhere you need him to (0.3 - 0.6)", + u8" Ulf Hermann (fonsinchen) - Cargo Distribution (1.3 - 1.6)", u8" Jaroslav Mazanec (KUDr) - YAPG (Yet Another Pathfinder God) ;) (0.4.5 - 0.6)", u8" Jonathan Coome (Maedhros) - High priest of the NewGRF Temple (0.5 - 0.6)", u8" Attila B\u00e1n (MiHaMiX) - Developer WebTranslator 1 and 2 (0.3 - 0.5)", + u8" Ingo von Borstel (planetmaker) - General coding, Support (1.1 - 1.9)", u8" Zden\u011bk Sojka (SmatZ) - Bug finder and fixer (0.6 - 1.3)", + u8" Jos\u00e9 Soler (Terkhen) - General coding (1.0 - 1.4)", u8" Christoph Mallon (Tron) - Programmer, code correctness police (0.3 - 0.5)", - u8" Patric Stout (TrueBrain) - NoAI, NoGo, Network (0.3 - 1.2), sys op (active)", u8" Thijs Marinussen (Yexo) - AI Framework, General (0.6 - 1.3)", u8" Leif Linse (Zuu) - AI/Game Script (1.2 - 1.6)", u8"", @@ -455,7 +454,6 @@ static const char * const _credits[] = { u8" Mike Ragsdale - OpenTTD installer", u8" Christian Rosentreter (tokai) - MorphOS / AmigaOS port", u8" Richard Kempton (richK) - additional airports, initial TGP implementation", - u8"", u8" Alberto Demichelis - Squirrel scripting language \u00a9 2003-2008", u8" L. Peter Deutsch - MD5 implementation \u00a9 1999, 2000, 2002", u8" Michael Blunck - Pre-signals and semaphores \u00a9 2003", @@ -658,7 +656,7 @@ void HideFillingPercent(TextEffectID *te_id) } static const NWidgetPart _nested_tooltips_widgets[] = { - NWidget(WWT_PANEL, COLOUR_GREY, WID_TT_BACKGROUND), SetMinimalSize(200, 32), EndContainer(), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_TT_BACKGROUND), EndContainer(), }; static WindowDesc _tool_tips_desc( @@ -673,7 +671,7 @@ struct TooltipsWindow : public Window { StringID string_id; ///< String to display as tooltip. byte paramcount; ///< Number of string parameters in #string_id. - uint64 params[5]; ///< The string parameters. + uint64 params[8]; ///< The string parameters. TooltipCloseCondition close_cond; ///< Condition for closing the window. TooltipsWindow(Window *parent, StringID str, uint paramcount, const uint64 params[], TooltipCloseCondition close_tooltip) : Window(&_tool_tips_desc) @@ -682,6 +680,10 @@ struct TooltipsWindow : public Window this->string_id = str; static_assert(sizeof(this->params[0]) == sizeof(params[0])); assert(paramcount <= lengthof(this->params)); + if (params == nullptr) { + _global_string_params.offset = 0; + params = _global_string_params.GetDataPointer(); + } if (paramcount > 0) memcpy(this->params, params, sizeof(this->params[0]) * paramcount); this->paramcount = paramcount; this->close_cond = close_tooltip; @@ -720,20 +722,20 @@ struct TooltipsWindow : public Window size->height = GetStringHeight(this->string_id, size->width); /* Increase slightly to have some space around the box. */ - size->width += 2 + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - size->height += 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + size->width += WidgetDimensions::scaled.framerect.Horizontal() + WidgetDimensions::scaled.fullbevel.Horizontal(); + size->height += WidgetDimensions::scaled.framerect.Vertical() + WidgetDimensions::scaled.fullbevel.Vertical(); } void DrawWidget(const Rect &r, int widget) const override { /* There is only one widget. */ - GfxFillRect(r.left, r.top, r.right, r.bottom, PC_BLACK); - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_LIGHT_YELLOW); + GfxFillRect(r, PC_BLACK); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), PC_LIGHT_YELLOW); for (uint arg = 0; arg < this->paramcount; arg++) { SetDParam(arg, this->params[arg]); } - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, this->string_id, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect).Shrink(WidgetDimensions::scaled.fullbevel), this->string_id, TC_FROMSTRING, SA_CENTER); } void OnMouseLoop() override @@ -787,6 +789,11 @@ void QueryString::HandleEditBox(Window *w, int wid) } } +static int GetCaretWidth() +{ + return GetCharacterWidth(FS_NORMAL, '_'); +} + void QueryString::DrawEditBox(const Window *w, int wid) const { const NWidgetLeaf *wi = w->GetWidget(wid); @@ -795,39 +802,35 @@ void QueryString::DrawEditBox(const Window *w, int wid) const bool rtl = _current_text_dir == TD_RTL; Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); - int clearbtn_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; + int clearbtn_width = sprite_size.width + WidgetDimensions::scaled.imgbtn.Horizontal(); - int clearbtn_left = wi->pos_x + (rtl ? 0 : wi->current_x - clearbtn_width); - int clearbtn_right = wi->pos_x + (rtl ? clearbtn_width : wi->current_x) - 1; - int left = wi->pos_x + (rtl ? clearbtn_width : 0); - int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1; + Rect r = wi->GetCurrentRect(); + Rect cr = r.WithWidth(clearbtn_width, !rtl); + Rect fr = r.Indent(clearbtn_width, !rtl); - int top = wi->pos_y; - int bottom = wi->pos_y + wi->current_y - 1; + DrawFrameRect(cr, wi->colour, wi->IsLowered() ? FR_LOWERED : FR_NONE); + DrawSprite(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT, PAL_NONE, cr.left + WidgetDimensions::scaled.imgbtn.left + (wi->IsLowered() ? 1 : 0), CenterBounds(r.top, r.bottom, sprite_size.height) + (wi->IsLowered() ? 1 : 0)); + if (this->text.bytes == 1) GfxFillRect(cr.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[wi->colour & 0xF][2], FILLRECT_CHECKER); - DrawFrameRect(clearbtn_left, top, clearbtn_right, bottom, wi->colour, wi->IsLowered() ? FR_LOWERED : FR_NONE); - DrawSprite(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT, PAL_NONE, clearbtn_left + WD_IMGBTN_LEFT + (wi->IsLowered() ? 1 : 0), (top + bottom - sprite_size.height) / 2 + (wi->IsLowered() ? 1 : 0)); - if (this->text.bytes == 1) GfxFillRect(clearbtn_left + 1, top + 1, clearbtn_right - 1, bottom - 1, _colour_gradient[wi->colour & 0xF][2], FILLRECT_CHECKER); - - DrawFrameRect(left, top, right, bottom, wi->colour, FR_LOWERED | FR_DARKENED); - GfxFillRect(left + 1, top + 1, right - 1, bottom - 1, PC_BLACK); + DrawFrameRect(fr, wi->colour, FR_LOWERED | FR_DARKENED); + GfxFillRect(fr.Shrink(WidgetDimensions::scaled.bevel), PC_BLACK); + fr = fr.Shrink(WidgetDimensions::scaled.framerect); /* Limit the drawing of the string inside the widget boundaries */ DrawPixelInfo dpi; - if (!FillDrawPixelInfo(&dpi, left + WD_FRAMERECT_LEFT, top + WD_FRAMERECT_TOP, right - left - WD_FRAMERECT_RIGHT, bottom - top - WD_FRAMERECT_BOTTOM)) return; + if (!FillDrawPixelInfo(&dpi, fr.left, fr.top, fr.Width(), fr.Height())) return; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &dpi); /* We will take the current widget length as maximum width, with a small * space reserved at the end for the caret to show */ const Textbuf *tb = &this->text; - int delta = std::min(0, (right - left) - tb->pixels - 10); + int delta = std::min(0, (fr.right - fr.left) - tb->pixels - GetCaretWidth()); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; /* If we have a marked area, draw a background highlight. */ - if (tb->marklength != 0) GfxFillRect(delta + tb->markxoffs, 0, delta + tb->markxoffs + tb->marklength - 1, bottom - top, PC_GREY); + if (tb->marklength != 0) GfxFillRect(delta + tb->markxoffs, 0, delta + tb->markxoffs + tb->marklength - 1, fr.bottom - fr.top, PC_GREY); DrawString(delta, tb->pixels, 0, tb->buf, TC_YELLOW); bool focussed = w->IsWidgetGloballyFocused(wid) || IsOSKOpenedFor(w, wid); @@ -835,8 +838,6 @@ void QueryString::DrawEditBox(const Window *w, int wid) const int caret_width = GetStringBoundingBox("_").width; DrawString(tb->caretxoffs + delta, tb->caretxoffs + delta + caret_width, 0, "_", TC_WHITE); } - - _cur_dpi = old_dpi; } /** @@ -853,17 +854,16 @@ Point QueryString::GetCaretPosition(const Window *w, int wid) const bool rtl = _current_text_dir == TD_RTL; Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); - int clearbtn_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; + int clearbtn_width = sprite_size.width + WidgetDimensions::scaled.imgbtn.Horizontal(); - int left = wi->pos_x + (rtl ? clearbtn_width : 0); - int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1; + Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WidgetDimensions::scaled.framerect); /* Clamp caret position to be inside out current width. */ const Textbuf *tb = &this->text; - int delta = std::min(0, (right - left) - tb->pixels - 10); + int delta = std::min(0, (r.right - r.left) - tb->pixels - GetCaretWidth()); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; - Point pt = {left + WD_FRAMERECT_LEFT + tb->caretxoffs + delta, (int)wi->pos_y + WD_FRAMERECT_TOP}; + Point pt = {r.left + tb->caretxoffs + delta, r.top}; return pt; } @@ -883,26 +883,20 @@ Rect QueryString::GetBoundingRect(const Window *w, int wid, const char *from, co bool rtl = _current_text_dir == TD_RTL; Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); - int clearbtn_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; - - int left = wi->pos_x + (rtl ? clearbtn_width : 0); - int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1; + int clearbtn_width = sprite_size.width + WidgetDimensions::scaled.imgbtn.Horizontal(); - int top = wi->pos_y + WD_FRAMERECT_TOP; - int bottom = wi->pos_y + wi->current_y - 1 - WD_FRAMERECT_BOTTOM; + Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WidgetDimensions::scaled.framerect); /* Clamp caret position to be inside our current width. */ const Textbuf *tb = &this->text; - int delta = std::min(0, (right - left) - tb->pixels - 10); + int delta = std::min(0, r.Width() - tb->pixels - GetCaretWidth()); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; /* Get location of first and last character. */ Point p1 = GetCharPosInString(tb->buf, from, FS_NORMAL); Point p2 = from != to ? GetCharPosInString(tb->buf, to, FS_NORMAL) : p1; - Rect r = { Clamp(left + p1.x + delta + WD_FRAMERECT_LEFT, left, right), top, Clamp(left + p2.x + delta + WD_FRAMERECT_LEFT, left, right - WD_FRAMERECT_RIGHT), bottom }; - - return r; + return { Clamp(r.left + p1.x + delta, r.left, r.right), r.top, Clamp(r.left + p2.x + delta, r.left, r.right), r.bottom }; } /** @@ -920,22 +914,18 @@ const char *QueryString::GetCharAtPosition(const Window *w, int wid, const Point bool rtl = _current_text_dir == TD_RTL; Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); - int clearbtn_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; - - int left = wi->pos_x + (rtl ? clearbtn_width : 0); - int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1; + int clearbtn_width = sprite_size.width + WidgetDimensions::scaled.imgbtn.Horizontal(); - int top = wi->pos_y + WD_FRAMERECT_TOP; - int bottom = wi->pos_y + wi->current_y - 1 - WD_FRAMERECT_BOTTOM; + Rect r = wi->GetCurrentRect().Indent(clearbtn_width, !rtl).Shrink(WidgetDimensions::scaled.framerect); - if (!IsInsideMM(pt.y, top, bottom)) return nullptr; + if (!IsInsideMM(pt.y, r.top, r.bottom)) return nullptr; /* Clamp caret position to be inside our current width. */ const Textbuf *tb = &this->text; - int delta = std::min(0, (right - left) - tb->pixels - 10); + int delta = std::min(0, r.Width() - tb->pixels - GetCaretWidth()); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; - return ::GetCharAtPosition(tb->buf, pt.x - delta - left); + return ::GetCharAtPosition(tb->buf, pt.x - delta - r.left); } void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bool focus_changed) @@ -947,9 +937,9 @@ void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bo bool rtl = _current_text_dir == TD_RTL; int clearbtn_width = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT).width; - int clearbtn_left = wi->pos_x + (rtl ? 0 : wi->current_x - clearbtn_width); + Rect cr = wi->GetCurrentRect().WithWidth(clearbtn_width, !rtl); - if (IsInsideBS(pt.x, clearbtn_left, clearbtn_width)) { + if (IsInsideMM(pt.x, cr.left, cr.right)) { if (this->text.bytes > 1) { this->text.DeleteAll(); w->HandleButtonClick(wid); @@ -1009,9 +999,9 @@ struct QueryStringWindow : public Window { if (this->flags & QSF_PASSWORD) { assert(this->nested_root->smallest_x > 0); - this->warning_size.width = this->nested_root->current_x - (WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT); + this->warning_size.width = this->nested_root->current_x - WidgetDimensions::scaled.frametext.Horizontal() - WidgetDimensions::scaled.framerect.Horizontal(); this->warning_size.height = GetStringHeight(STR_WARNING_PASSWORD_SECURITY, this->warning_size.width); - this->warning_size.height += WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + this->warning_size.height += WidgetDimensions::scaled.frametext.Vertical() + WidgetDimensions::scaled.framerect.Vertical(); } else { this->warning_size = Dimension{ 0, 0 }; } @@ -1038,8 +1028,7 @@ struct QueryStringWindow : public Window if (widget != WID_QS_WARNING) return; if (this->flags & QSF_PASSWORD) { - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT - WD_FRAMERECT_RIGHT, - r.top + WD_FRAMERECT_TOP + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMERECT_BOTTOM - WD_FRAMETEXT_BOTTOM, + DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect).Shrink(WidgetDimensions::scaled.frametext), STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER); } } @@ -1182,8 +1171,8 @@ struct QueryWindow : public Window { if (widget != WID_Q_TEXT) return; Dimension d = GetStringMultiLineBoundingBox(this->message, *size); - d.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; - d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += WidgetDimensions::scaled.frametext.Horizontal(); + d.height += WidgetDimensions::scaled.framerect.Vertical(); *size = d; } @@ -1191,7 +1180,7 @@ struct QueryWindow : public Window { { if (widget != WID_Q_TEXT) return; - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, + DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect), this->message, TC_FROMSTRING, SA_CENTER); } @@ -1243,11 +1232,13 @@ static const NWidgetPart _nested_query_widgets[] = { NWidget(WWT_CLOSEBOX, COLOUR_RED), NWidget(WWT_CAPTION, COLOUR_RED, WID_Q_CAPTION), SetDataTip(STR_JUST_STRING, STR_NULL), EndContainer(), - NWidget(WWT_PANEL, COLOUR_RED), SetPIP(8, 15, 8), - NWidget(WWT_TEXT, COLOUR_RED, WID_Q_TEXT), SetMinimalSize(200, 12), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(20, 29, 20), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_Q_NO), SetMinimalSize(71, 12), SetFill(1, 1), SetDataTip(STR_QUIT_NO, STR_NULL), - NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_Q_YES), SetMinimalSize(71, 12), SetFill(1, 1), SetDataTip(STR_QUIT_YES, STR_NULL), + NWidget(WWT_PANEL, COLOUR_RED), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup), + NWidget(WWT_TEXT, COLOUR_RED, WID_Q_TEXT), SetMinimalSize(200, 12), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(WidgetDimensions::unscaled.hsep_indent, WidgetDimensions::unscaled.hsep_indent, WidgetDimensions::unscaled.hsep_indent), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_Q_NO), SetMinimalSize(71, 12), SetFill(1, 1), SetDataTip(STR_QUIT_NO, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_Q_YES), SetMinimalSize(71, 12), SetFill(1, 1), SetDataTip(STR_QUIT_YES, STR_NULL), + EndContainer(), EndContainer(), EndContainer(), }; @@ -1270,7 +1261,7 @@ static WindowDesc _query_desc( */ void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallbackProc *callback) { - if (parent == nullptr) parent = FindWindowById(WC_MAIN_WINDOW, 0); + if (parent == nullptr) parent = GetMainWindow(); for (Window *w : Window::Iterate()) { if (w->window_class != WC_CONFIRM_POPUP_QUERY) continue; diff --git a/src/mixer.cpp b/src/mixer.cpp index b9b20fccfd947..b8623533837b6 100644 --- a/src/mixer.cpp +++ b/src/mixer.cpp @@ -10,6 +10,7 @@ #include "stdafx.h" #include #include +#include #include "core/math_func.hpp" #include "framerate_type.h" #include "settings_type.h" @@ -18,8 +19,6 @@ #include "mixer.h" struct MixerChannel { - bool active; - /* pointer to allocated buffer memory */ int8 *memory; @@ -36,11 +35,13 @@ struct MixerChannel { bool is16bit; }; +static std::atomic _active_channels; static MixerChannel _channels[8]; static uint32 _play_rate = 11025; static uint32 _max_size = UINT_MAX; static MxStreamCallback _music_stream = nullptr; static std::mutex _music_stream_mutex; +static std::atomic _effect_vol; /** * The theoretical maximum volume for a single sound sample. Multiple sound @@ -135,9 +136,9 @@ static void mix_int8_to_int16(MixerChannel *sc, int16 *buffer, uint samples, uin sc->pos = b - sc->memory; } -static void MxCloseChannel(MixerChannel *mc) +static void MxCloseChannel(uint8 channel_index) { - mc->active = false; + _active_channels.fetch_and(~(1 << channel_index), std::memory_order_release); } void MxMixSamples(void *buffer, uint samples) @@ -149,8 +150,6 @@ void MxMixSamples(void *buffer, uint samples) last_samples = samples; } - MixerChannel *mc; - /* Clear the buffer */ memset(buffer, 0, sizeof(int16) * 2 * samples); @@ -164,34 +163,36 @@ void MxMixSamples(void *buffer, uint samples) * perceived difference in loudness to better match expectations. effect_vol * is expected to be in the range 0-127 hence the division by 127 * 127 to * get back into range. */ - uint8 effect_vol = (_settings_client.music.effect_vol * - _settings_client.music.effect_vol * - _settings_client.music.effect_vol) / (127 * 127); + uint8 effect_vol_setting = _effect_vol.load(std::memory_order_relaxed); + uint8 effect_vol = (effect_vol_setting * + effect_vol_setting * + effect_vol_setting) / (127 * 127); /* Mix each channel */ - for (mc = _channels; mc != endof(_channels); mc++) { - if (mc->active) { - if (mc->is16bit) { - mix_int16(mc, (int16*)buffer, samples, effect_vol); - } else { - mix_int8_to_int16(mc, (int16*)buffer, samples, effect_vol); - } - if (mc->samples_left == 0) MxCloseChannel(mc); + uint8 active = _active_channels.load(std::memory_order_acquire); + for (uint8 idx : SetBitIterator(active)) { + MixerChannel *mc = &_channels[idx]; + if (mc->is16bit) { + mix_int16(mc, (int16*)buffer, samples, effect_vol); + } else { + mix_int8_to_int16(mc, (int16*)buffer, samples, effect_vol); } + if (mc->samples_left == 0) MxCloseChannel(idx); } } MixerChannel *MxAllocateChannel() { - MixerChannel *mc; - for (mc = _channels; mc != endof(_channels); mc++) { - if (!mc->active) { - free(mc->memory); - mc->memory = nullptr; - return mc; - } - } - return nullptr; + uint8 currently_active = _active_channels.load(std::memory_order_acquire); + uint8 available = ~currently_active; + if (available == 0) return nullptr; + + uint8 channel_index = FindFirstBit(available); + + MixerChannel *mc = &_channels[channel_index]; + free(mc->memory); + mc->memory = nullptr; + return mc; } void MxSetChannelRawSrc(MixerChannel *mc, int8 *mem, size_t size, uint rate, bool is16bit) @@ -231,7 +232,8 @@ void MxSetChannelVolume(MixerChannel *mc, uint volume, float pan) void MxActivateChannel(MixerChannel *mc) { - mc->active = true; + uint8 channel_index = mc - _channels; + _active_channels.fetch_or((1 << channel_index), std::memory_order_release); } /** @@ -255,3 +257,8 @@ bool MxInitialize(uint rate) _music_stream = nullptr; /* rate may have changed, any music source is now invalid */ return true; } + +void SetEffectVolume(uint8 volume) +{ + _effect_vol.store(volume, std::memory_order_relaxed); +} diff --git a/src/mixer.h b/src/mixer.h index bd7b18a44ab73..51669da71c2bb 100644 --- a/src/mixer.h +++ b/src/mixer.h @@ -30,4 +30,6 @@ void MxActivateChannel(MixerChannel*); uint32 MxSetMusicSource(MxStreamCallback music_callback); +void SetEffectVolume(uint8 volume); + #endif /* MIXER_H */ diff --git a/src/music.cpp b/src/music.cpp index fdeb2d3df8697..d7fbd4b6b073e 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -128,7 +128,6 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f for (uint i = 0; i < lengthof(this->songinfo); i++) { const char *filename = this->files[i].filename; if (names == nullptr || StrEmpty(filename) || this->files[i].check_result == MD5File::CR_NO_FILE) { - this->songinfo[i].songname[0] = '\0'; continue; } @@ -142,10 +141,9 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f char *songname = GetMusicCatEntryName(filename, this->songinfo[i].cat_index); if (songname == nullptr) { Debug(grf, 0, "Base music set song missing from CAT file: {}/{}", filename, this->songinfo[i].cat_index); - this->songinfo[i].songname[0] = '\0'; continue; } - strecpy(this->songinfo[i].songname, songname, lastof(this->songinfo[i].songname)); + this->songinfo[i].songname = songname; free(songname); } else { this->songinfo[i].filetype = MTT_STANDARDMIDI; @@ -166,7 +164,7 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f if (this->songinfo[i].filetype == MTT_STANDARDMIDI) { if (item != nullptr && item->value.has_value() && !item->value->empty()) { - strecpy(this->songinfo[i].songname, item->value->c_str(), lastof(this->songinfo[i].songname)); + this->songinfo[i].songname = item->value.value(); } else { Debug(grf, 0, "Base music set song name missing: {}", filename); return false; diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 80d55eb4ba48c..7841bbf0d20eb 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -27,6 +27,7 @@ #include "widgets/dropdown_func.h" #include "widgets/dropdown_type.h" #include "widgets/slider_func.h" +#include "mixer.h" #include "widgets/music_widget.h" @@ -42,7 +43,7 @@ struct MusicSystem { uint set_index; ///< index of song in set PlaylistEntry(const MusicSet *set, uint set_index) : MusicSongInfo(set->songinfo[set_index]), set(set), set_index(set_index) { } - bool IsValid() const { return !StrEmpty(this->songname); } + bool IsValid() const { return !this->songname.empty(); } }; typedef std::vector Playlist; @@ -127,11 +128,11 @@ void MusicSystem::BuildPlaylists() /* Load custom playlists * Song index offsets are 1-based, zero indicates invalid/end-of-list value */ for (uint i = 0; i < NUM_SONGS_PLAYLIST; i++) { - if (_settings_client.music.custom_1[i] > 0) { + if (_settings_client.music.custom_1[i] > 0 && _settings_client.music.custom_1[i] <= NUM_SONGS_AVAILABLE) { PlaylistEntry entry(set, _settings_client.music.custom_1[i] - 1); if (entry.IsValid()) this->standard_playlists[PLCH_CUSTOM1].push_back(entry); } - if (_settings_client.music.custom_2[i] > 0) { + if (_settings_client.music.custom_2[i] > 0 && _settings_client.music.custom_2[i] <= NUM_SONGS_AVAILABLE) { PlaylistEntry entry(set, _settings_client.music.custom_2[i] - 1); if (entry.IsValid()) this->standard_playlists[PLCH_CUSTOM2].push_back(entry); } @@ -146,18 +147,20 @@ void MusicSystem::ChangePlaylist(PlaylistChoices pl) { assert(pl < PLCH_MAX && pl >= PLCH_ALLMUSIC); - this->displayed_playlist = this->standard_playlists[pl]; - this->active_playlist = this->displayed_playlist; - this->selected_playlist = pl; - this->playlist_position = 0; + if (pl != PLCH_THEMEONLY) _settings_client.music.playlist = pl; - if (this->selected_playlist != PLCH_THEMEONLY) _settings_client.music.playlist = this->selected_playlist; + if (_game_mode != GM_MENU || pl == PLCH_THEMEONLY) { + this->displayed_playlist = this->standard_playlists[pl]; + this->active_playlist = this->displayed_playlist; + this->selected_playlist = pl; + this->playlist_position = 0; - if (_settings_client.music.shuffle) { - this->Shuffle(); - /* Shuffle() will also Play() if necessary, only start once */ - } else if (_settings_client.music.playing) { - this->Play(); + if (_settings_client.music.shuffle) { + this->Shuffle(); + /* Shuffle() will also Play() if necessary, only start once */ + } else if (_settings_client.music.playing) { + this->Play(); + } } InvalidateWindowData(WC_MUSIC_TRACK_SELECTION, 0); @@ -177,6 +180,8 @@ void MusicSystem::ChangeMusicSet(const std::string &set_name) this->ChangePlaylist(this->selected_playlist); InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_GAME_OPTIONS, 0, true); + InvalidateWindowData(WC_MUSIC_TRACK_SELECTION, 0, 1, true); + InvalidateWindowData(WC_MUSIC_WINDOW, 0, 1, true); } /** Enable shuffle mode and restart playback */ @@ -479,7 +484,12 @@ struct MusicTrackSelectionWindow : public Window { this->SetWidgetLoweredState(WID_MTS_ALL + i, i == _settings_client.music.playlist); } this->SetWidgetDisabledState(WID_MTS_CLEAR, _settings_client.music.playlist <= 3); - this->SetDirty(); + + if (data == 1) { + this->ReInit(); + } else { + this->SetDirty(); + } } void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override @@ -521,29 +531,29 @@ struct MusicTrackSelectionWindow : public Window { { switch (widget) { case WID_MTS_LIST_LEFT: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), PC_BLACK); - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); for (MusicSystem::Playlist::const_iterator song = _music.music_set.begin(); song != _music.music_set.end(); ++song) { SetDParam(0, song->tracknr); SetDParam(1, 2); SetDParamStr(2, song->songname); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME); - y += FONT_HEIGHT_SMALL; + DrawString(tr, STR_PLAYLIST_TRACK_NAME); + tr.top += FONT_HEIGHT_SMALL; } break; } case WID_MTS_LIST_RIGHT: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), PC_BLACK); - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); for (MusicSystem::Playlist::const_iterator song = _music.active_playlist.begin(); song != _music.active_playlist.end(); ++song) { SetDParam(0, song->tracknr); SetDParam(1, 2); SetDParamStr(2, song->songname); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_PLAYLIST_TRACK_NAME); - y += FONT_HEIGHT_SMALL; + DrawString(tr, STR_PLAYLIST_TRACK_NAME); + tr.top += FONT_HEIGHT_SMALL; } break; } @@ -604,9 +614,9 @@ static const NWidgetPart _nested_music_track_selection_widgets[] = { NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2), /* Left panel. */ NWidget(NWID_VERTICAL), - NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_PLAYLIST_TRACK_INDEX, STR_NULL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_MTS_LIST_LEFT), SetMinimalSize(180, 194), SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), + NWidget(WWT_LABEL, COLOUR_GREY), SetFill(1, 0), SetDataTip(STR_PLAYLIST_TRACK_INDEX, STR_NULL), + NWidget(WWT_PANEL, COLOUR_GREY, WID_MTS_LIST_LEFT), SetFill(1, 1), SetMinimalSize(180, 194), SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK), EndContainer(), + NWidget(NWID_SPACER), SetFill(1, 0), SetMinimalSize(0, 2), EndContainer(), /* Middle buttons. */ NWidget(NWID_VERTICAL), @@ -623,9 +633,9 @@ static const NWidgetPart _nested_music_track_selection_widgets[] = { EndContainer(), /* Right panel. */ NWidget(NWID_VERTICAL), - NWidget(WWT_LABEL, COLOUR_GREY, WID_MTS_PLAYLIST), SetDataTip(STR_PLAYLIST_PROGRAM, STR_NULL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_MTS_LIST_RIGHT), SetMinimalSize(180, 194), SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), + NWidget(WWT_LABEL, COLOUR_GREY, WID_MTS_PLAYLIST), SetFill(1, 0), SetDataTip(STR_PLAYLIST_PROGRAM, STR_NULL), + NWidget(WWT_PANEL, COLOUR_GREY, WID_MTS_LIST_RIGHT), SetFill(1, 1), SetMinimalSize(180, 194), SetDataTip(0x0, STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK), EndContainer(), + NWidget(NWID_SPACER), SetFill(1, 0), SetMinimalSize(0, 2), EndContainer(), EndContainer(), EndContainer(), @@ -681,8 +691,8 @@ struct MusicWindow : public Window { case WID_M_TRACK_NR: { Dimension d = GetStringBoundingBox(STR_MUSIC_TRACK_NONE); - d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += padding.width; + d.height += padding.height; *size = maxdim(*size, d); break; } @@ -693,8 +703,8 @@ struct MusicWindow : public Window { SetDParamStr(0, song->songname); d = maxdim(d, GetStringBoundingBox(STR_MUSIC_TITLE_NAME)); } - d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += padding.width; + d.height += padding.height; *size = maxdim(*size, d); break; } @@ -711,7 +721,7 @@ struct MusicWindow : public Window { { switch (widget) { case WID_M_TRACK_NR: { - GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, PC_BLACK); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel.left, WidgetDimensions::scaled.bevel.top, 0, WidgetDimensions::scaled.bevel.bottom), PC_BLACK); if (BaseMusic::GetUsedSet()->num_available == 0) { break; } @@ -721,12 +731,12 @@ struct MusicWindow : public Window { SetDParam(1, 2); str = STR_MUSIC_TRACK_DIGIT; } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str); + DrawString(r.Shrink(WidgetDimensions::scaled.framerect), str); break; } case WID_M_TRACK_NAME: { - GfxFillRect(r.left, r.top + 1, r.right - 1, r.bottom, PC_BLACK); + GfxFillRect(r.Shrink(0, WidgetDimensions::scaled.bevel.top, WidgetDimensions::scaled.bevel.right, WidgetDimensions::scaled.bevel.bottom), PC_BLACK); StringID str = STR_MUSIC_TITLE_NONE; MusicSystem::PlaylistEntry entry(_music.GetCurrentSong()); if (BaseMusic::GetUsedSet()->num_available == 0) { @@ -735,16 +745,16 @@ struct MusicWindow : public Window { str = STR_MUSIC_TITLE_NAME; SetDParamStr(0, entry.songname); } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(r.Shrink(WidgetDimensions::scaled.framerect), str, TC_FROMSTRING, SA_HOR_CENTER); break; } case WID_M_MUSIC_VOL: - DrawVolumeSliderWidget(r, _settings_client.music.music_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol, {}); break; case WID_M_EFFECT_VOL: - DrawVolumeSliderWidget(r, _settings_client.music.effect_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol, {}); break; } } @@ -763,7 +773,11 @@ struct MusicWindow : public Window { UpdateDisabledButtons(); - this->SetDirty(); + if (data == 1) { + this->ReInit(); + } else { + this->SetDirty(); + } } void OnClick(Point pt, int widget, int click_count) override @@ -787,8 +801,12 @@ struct MusicWindow : public Window { case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: { // volume sliders byte &vol = (widget == WID_M_MUSIC_VOL) ? _settings_client.music.music_vol : _settings_client.music.effect_vol; - if (ClickVolumeSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, vol)) { - if (widget == WID_M_MUSIC_VOL) MusicDriver::GetInstance()->SetVolume(vol); + if (ClickSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, 0, INT8_MAX, vol)) { + if (widget == WID_M_MUSIC_VOL) { + MusicDriver::GetInstance()->SetVolume(vol); + } else { + SetEffectVolume(vol); + } this->SetWidgetDirty(widget); SetWindowClassesDirty(WC_GAME_OPTIONS); } diff --git a/src/network/core/CMakeLists.txt b/src/network/core/CMakeLists.txt index 756fa9e8f32a8..9e7a2ed50617c 100644 --- a/src/network/core/CMakeLists.txt +++ b/src/network/core/CMakeLists.txt @@ -9,6 +9,7 @@ add_files( game_info.h host.cpp host.h + http.h os_abstraction.cpp os_abstraction.h packet.cpp @@ -25,8 +26,6 @@ add_files( tcp_coordinator.h tcp_game.cpp tcp_game.h - tcp_http.cpp - tcp_http.h tcp_listen.h tcp_stun.cpp tcp_stun.h @@ -35,3 +34,16 @@ add_files( udp.cpp udp.h ) + +add_files( + http_curl.cpp + CONDITION CURL_FOUND +) +add_files( + http_winhttp.cpp + CONDITION WIN32 +) +add_files( + http_none.cpp + CONDITION NOT CURL_FOUND AND NOT WIN32 +) diff --git a/src/network/core/config.cpp b/src/network/core/config.cpp index 6e7f8a11c3c1d..c2f4467d8ed26 100644 --- a/src/network/core/config.cpp +++ b/src/network/core/config.cpp @@ -59,11 +59,11 @@ const char *NetworkContentServerConnectionString() } /** - * Get the connection string for the content mirror from the environment variable OTTD_CONTENT_MIRROR_CS, - * or when it has not been set a hard coded default DNS hostname of the production server. - * @return The content mirror's connection string. + * Get the URI string for the content mirror from the environment variable OTTD_CONTENT_MIRROR_URI, + * or when it has not been set a hard coded URI of the production server. + * @return The content mirror's URI string. */ -const char *NetworkContentMirrorConnectionString() +const char *NetworkContentMirrorUriString() { - return GetEnv("OTTD_CONTENT_MIRROR_CS", "binaries.openttd.org"); + return GetEnv("OTTD_CONTENT_MIRROR_URI", "https://binaries.openttd.org/bananas"); } diff --git a/src/network/core/config.h b/src/network/core/config.h index 3c9e1a50c1a36..175d865a8b21c 100644 --- a/src/network/core/config.h +++ b/src/network/core/config.h @@ -15,16 +15,12 @@ const char *NetworkCoordinatorConnectionString(); const char *NetworkStunConnectionString(); const char *NetworkContentServerConnectionString(); -const char *NetworkContentMirrorConnectionString(); - -/** URL of the HTTP mirror system */ -static const char * const NETWORK_CONTENT_MIRROR_URL = "/bananas"; +const char *NetworkContentMirrorUriString(); static const uint16 NETWORK_COORDINATOR_SERVER_PORT = 3976; ///< The default port of the Game Coordinator server (TCP) static const uint16 NETWORK_STUN_SERVER_PORT = 3975; ///< The default port of the STUN server (TCP) static const uint16 NETWORK_TURN_SERVER_PORT = 3974; ///< The default port of the TURN server (TCP) static const uint16 NETWORK_CONTENT_SERVER_PORT = 3978; ///< The default port of the content server (TCP) -static const uint16 NETWORK_CONTENT_MIRROR_PORT = 80; ///< The default port of the content mirror (TCP) static const uint16 NETWORK_DEFAULT_PORT = 3979; ///< The default port of the game server (TCP & UDP) static const uint16 NETWORK_ADMIN_PORT = 3977; ///< The default port for admin network static const uint16 NETWORK_DEFAULT_DEBUGLOG_PORT = 3982; ///< The default port debug-log is sent to (TCP) @@ -49,7 +45,6 @@ static const uint16 COMPAT_MTU = 1460; ///< Numbe static const byte NETWORK_GAME_ADMIN_VERSION = 2; ///< What version of the admin network do we use? static const byte NETWORK_GAME_INFO_VERSION = 6; ///< What version of game-info do we use? -static const byte NETWORK_COMPANY_INFO_VERSION = 6; ///< What version of company info is this? static const byte NETWORK_COORDINATOR_VERSION = 6; ///< What version of game-coordinator-protocol do we use? static const uint NETWORK_NAME_LENGTH = 80; ///< The maximum length of the server name and map name, in bytes including '\0' @@ -59,7 +54,6 @@ static const uint NETWORK_HOSTNAME_PORT_LENGTH = 80 + 6; ///< The m static const uint NETWORK_SERVER_ID_LENGTH = 33; ///< The maximum length of the network id of the servers, in bytes including '\0' static const uint NETWORK_REVISION_LENGTH = 33; ///< The maximum length of the revision, in bytes including '\0' static const uint NETWORK_PASSWORD_LENGTH = 33; ///< The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH) -static const uint NETWORK_CLIENTS_LENGTH = 200; ///< The maximum length for the list of clients that controls a company, in bytes including '\0' static const uint NETWORK_CLIENT_NAME_LENGTH = 25; ///< The maximum length of a client's name, in bytes including '\0' static const uint NETWORK_RCONCOMMAND_LENGTH = 500; ///< The maximum length of a rconsole command, in bytes including '\0' static const uint NETWORK_GAMESCRIPT_JSON_LENGTH = COMPAT_MTU - 3; ///< The maximum length of a gamescript json string, in bytes including '\0'. Must not be longer than COMPAT_MTU including header (3 bytes) diff --git a/src/network/core/game_info.cpp b/src/network/core/game_info.cpp index 1576ae4132de5..4cbcb31ba7495 100644 --- a/src/network/core/game_info.cpp +++ b/src/network/core/game_info.cpp @@ -126,8 +126,8 @@ void FillStaticNetworkServerGameInfo() _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; - _network_game_info.map_width = MapSizeX(); - _network_game_info.map_height = MapSizeY(); + _network_game_info.map_width = Map::SizeX(); + _network_game_info.map_height = Map::SizeY(); _network_game_info.landscape = _settings_game.game_creation.landscape; _network_game_info.dedicated = _network_dedicated; _network_game_info.grfconfig = _grfconfig; @@ -281,14 +281,14 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info, const GameInfo } case 4: { - GRFConfig **dst = &info->grfconfig; - uint i; + /* Ensure that the maximum number of NewGRFs and the field in the network + * protocol are matched to eachother. If that is not the case anymore a + * check must be added to ensure the received data is still valid. */ + static_assert(std::numeric_limits::max() == NETWORK_MAX_GRF_COUNT); uint num_grfs = p->Recv_uint8(); - /* Broken/bad data. It cannot have that many NewGRFs. */ - if (num_grfs > NETWORK_MAX_GRF_COUNT) return; - - for (i = 0; i < num_grfs; i++) { + GRFConfig **dst = &info->grfconfig; + for (uint i = 0; i < num_grfs; i++) { NamedGRFIdentifier grf; switch (newgrf_serialisation) { case NST_GRFID_MD5: diff --git a/src/network/core/http.h b/src/network/core/http.h new file mode 100644 index 0000000000000..78b5be87af48a --- /dev/null +++ b/src/network/core/http.h @@ -0,0 +1,74 @@ +/* + * 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 http.h Basic functions to send and receive HTTP packets. + */ + +#ifndef NETWORK_CORE_HTTP_H +#define NETWORK_CORE_HTTP_H + +#include "tcp.h" + +/** Callback for when the HTTP handler has something to tell us. */ +struct HTTPCallback { + /** + * An error has occurred and the connection has been closed. + * @note HTTP socket handler is closed/freed. + */ + virtual void OnFailure() = 0; + + /** + * We're receiving data. + * @param data the received data, nullptr when all data has been received. + * @param length the amount of received data, 0 when all data has been received. + * @note When nullptr is sent the HTTP socket handler is closed/freed. + */ + virtual void OnReceiveData(const char *data, size_t length) = 0; + + /** + * Check if there is a request to cancel the transfer. + * + * @return true iff the connection is cancelled. + * @note Cancellations are never instant, and can take a bit of time to be processed. + * The object needs to remain valid until the OnFailure() callback is called. + */ + virtual bool IsCancelled() const = 0; + + /** Silentium */ + virtual ~HTTPCallback() {} +}; + +/** Base socket handler for HTTP traffic. */ +class NetworkHTTPSocketHandler { +public: + /** + * Connect to the given URI. + * + * @param uri the URI to connect to (https://.../..). + * @param callback the callback to send data back on. + * @param data the data we want to send. When non-empty, this will be a POST request, otherwise a GET request. + */ + static void Connect(const std::string &uri, HTTPCallback *callback, const std::string data = ""); + + /** + * Do the receiving for all HTTP connections. + */ + static void HTTPReceive(); +}; + +/** + * Initialize the HTTP socket handler. + */ +void NetworkHTTPInitialize(); + +/** + * Uninitialize the HTTP socket handler. + */ +void NetworkHTTPUninitialize(); + +#endif /* NETWORK_CORE_HTTP_H */ diff --git a/src/network/core/http_curl.cpp b/src/network/core/http_curl.cpp new file mode 100644 index 0000000000000..3781eb2d4f8f7 --- /dev/null +++ b/src/network/core/http_curl.cpp @@ -0,0 +1,239 @@ +/* + * 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 http_curl.cpp CURL-based implementation for HTTP requests. + */ + +#include "../../stdafx.h" +#include "../../debug.h" +#include "../../fileio_func.h" +#include "../../rev.h" +#include "../../thread.h" +#include "../network_internal.h" + +#include "http.h" + +#include +#include +#include +#include +#include +#include + +#include "../../safeguards.h" + +#if defined(UNIX) +/** List of certificate bundles, depending on OS. Taken from: https://go.dev/src/crypto/x509/root_linux.go. */ +static auto _certificate_files = { + "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. + "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6 + "/etc/ssl/ca-bundle.pem", // OpenSUSE + "/etc/pki/tls/cacert.pem", // OpenELEC + "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7 + "/etc/ssl/cert.pem", // Alpine Linux +}; +/** List of certificate directories, depending on OS. Taken from: https://go.dev/src/crypto/x509/root_linux.go. */ +static auto _certificate_directories = { + "/etc/ssl/certs", // SLES10/SLES11, https://golang.org/issue/12139 + "/etc/pki/tls/certs", // Fedora/RHEL + "/system/etc/security/cacerts", // Android +}; +#endif /* UNIX */ + +/** Single HTTP request. */ +class NetworkHTTPRequest { +public: + /** + * Create a new HTTP request. + * + * @param uri the URI to connect to (https://.../..). + * @param callback the callback to send data back on. + * @param data the data we want to send. When non-empty, this will be a POST request, otherwise a GET request. + */ + NetworkHTTPRequest(const std::string &uri, HTTPCallback *callback, const std::string &data) : + uri(uri), + callback(callback), + data(data) + { + } + + const std::string uri; ///< URI to connect to. + HTTPCallback *callback; ///< Callback to send data back on. + const std::string data; ///< Data to send, if any. +}; + +static std::thread _http_thread; +static std::atomic _http_thread_exit = false; +static std::queue> _http_requests; +static std::mutex _http_mutex; +static std::condition_variable _http_cv; +#if defined(UNIX) +static std::string _http_ca_file = ""; +static std::string _http_ca_path = ""; +#endif /* UNIX */ + +/* static */ void NetworkHTTPSocketHandler::Connect(const std::string &uri, HTTPCallback *callback, const std::string data) +{ +#if defined(UNIX) + if (_http_ca_file.empty() && _http_ca_path.empty()) { + callback->OnFailure(); + return; + } +#endif /* UNIX */ + + std::lock_guard lock(_http_mutex); + _http_requests.push(std::make_unique(uri, callback, data)); + _http_cv.notify_one(); +} + +/* static */ void NetworkHTTPSocketHandler::HTTPReceive() +{ +} + +void HttpThread() +{ + CURL *curl = curl_easy_init(); + assert(curl != nullptr); + + for (;;) { + std::unique_lock lock(_http_mutex); + + /* Wait for a new request. */ + while (_http_requests.empty() && !_http_thread_exit) { + _http_cv.wait(lock); + } + if (_http_thread_exit) break; + + std::unique_ptr request = std::move(_http_requests.front()); + _http_requests.pop(); + + /* Release the lock, as we will take a while to process the request. */ + lock.unlock(); + + /* Reset to default settings. */ + curl_easy_reset(curl); + + if (_debug_net_level >= 5) { + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + } + + /* Setup some default options. */ + std::string user_agent = fmt::format("OpenTTD/{}", GetNetworkRevisionString()); + curl_easy_setopt(curl, CURLOPT_USERAGENT, user_agent.c_str()); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5L); + + /* Ensure we validate the certificate and hostname of the server. */ +#if defined(UNIX) + curl_easy_setopt(curl, CURLOPT_CAINFO, _http_ca_file.empty() ? nullptr : _http_ca_file.c_str()); + curl_easy_setopt(curl, CURLOPT_CAPATH, _http_ca_path.empty() ? nullptr : _http_ca_path.c_str()); +#endif /* UNIX */ + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, true); + + /* Give the connection about 10 seconds to complete. */ + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); + + /* Set a buffer of 100KiB, as the default of 16KiB seems a bit small. */ + curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 100L * 1024L); + + /* Fail our call if we don't receive a 2XX return value. */ + curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); + + /* Prepare POST body and URI. */ + if (!request->data.empty()) { + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request->data.c_str()); + } + curl_easy_setopt(curl, CURLOPT_URL, request->uri.c_str()); + + /* Setup our (C-style) callback function which we pipe back into the callback. */ + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, +[](char *ptr, size_t size, size_t nmemb, void *userdata) -> size_t { + Debug(net, 4, "HTTP callback: {} bytes", size * nmemb); + HTTPCallback *callback = static_cast(userdata); + callback->OnReceiveData(ptr, size * nmemb); + return size * nmemb; + }); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, request->callback); + + /* Create a callback from which we can cancel. Sadly, there is no other + * thread-safe way to do this. If the connection went idle, it can take + * up to a second before this callback is called. There is little we can + * do about this. */ + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, +[](void *userdata, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) -> int { + const HTTPCallback *callback = static_cast(userdata); + return (callback->IsCancelled() || _http_thread_exit) ? 1 : 0; + }); + curl_easy_setopt(curl, CURLOPT_XFERINFODATA, request->callback); + + /* Perform the request. */ + CURLcode res = curl_easy_perform(curl); + + if (res == CURLE_OK) { + Debug(net, 1, "HTTP request succeeded"); + request->callback->OnReceiveData(nullptr, 0); + } else { + Debug(net, (request->callback->IsCancelled() || _http_thread_exit) ? 1 : 0, "HTTP request failed: {}", curl_easy_strerror(res)); + request->callback->OnFailure(); + } + } + + curl_easy_cleanup(curl); +} + +void NetworkHTTPInitialize() +{ + curl_global_init(CURL_GLOBAL_DEFAULT); + +#if defined(UNIX) + /* Depending on the Linux distro, certificates can either be in + * a bundle or a folder, in a wide range of different locations. + * Try to find what location is used by this OS. */ + for (auto &ca_file : _certificate_files) { + if (FileExists(ca_file)) { + _http_ca_file = ca_file; + break; + } + } + if (_http_ca_file.empty()) { + for (auto &ca_path : _certificate_directories) { + if (FileExists(ca_path)) { + _http_ca_path = ca_path; + break; + } + } + } + Debug(net, 3, "Using certificate file: {}", _http_ca_file.empty() ? "none" : _http_ca_file); + Debug(net, 3, "Using certificate path: {}", _http_ca_path.empty() ? "none" : _http_ca_path); + + /* Tell the user why HTTPS will not be working. */ + if (_http_ca_file.empty() && _http_ca_path.empty()) { + Debug(net, 0, "No certificate files or directories found, HTTPS will not work!"); + } +#endif /* UNIX */ + + _http_thread_exit = false; + StartNewThread(&_http_thread, "ottd:http", &HttpThread); +} + +void NetworkHTTPUninitialize() +{ + curl_global_cleanup(); + + _http_thread_exit = true; + + { + std::lock_guard lock(_http_mutex); + _http_cv.notify_one(); + } + + if (_http_thread.joinable()) { + _http_thread.join(); + } +} diff --git a/src/network/core/http_none.cpp b/src/network/core/http_none.cpp new file mode 100644 index 0000000000000..41ba7c8cba70e --- /dev/null +++ b/src/network/core/http_none.cpp @@ -0,0 +1,37 @@ +/* + * 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 http_emscripten.cpp Emscripten-based implementation for HTTP requests. + */ + +#include "../../stdafx.h" +#include "../../debug.h" +#include "../../rev.h" +#include "../network_internal.h" + +#include "http.h" + +#include "../../safeguards.h" + +/* static */ void NetworkHTTPSocketHandler::Connect(const std::string &uri, HTTPCallback *callback, const std::string data) +{ + /* No valid HTTP backend was compiled in, so we fail all HTTP requests. */ + callback->OnFailure(); +} + +/* static */ void NetworkHTTPSocketHandler::HTTPReceive() +{ +} + +void NetworkHTTPInitialize() +{ +} + +void NetworkHTTPUninitialize() +{ +} diff --git a/src/network/core/http_winhttp.cpp b/src/network/core/http_winhttp.cpp new file mode 100644 index 0000000000000..9fc28d62cbc80 --- /dev/null +++ b/src/network/core/http_winhttp.cpp @@ -0,0 +1,325 @@ +/* + * 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 http_winhttp.cpp WinHTTP-based implementation for HTTP requests. + */ + +#include "../../stdafx.h" +#include "../../debug.h" +#include "../../rev.h" +#include "../network_internal.h" + +#include "http.h" + +#include + +#include "../../safeguards.h" + +static HINTERNET _winhttp_session = nullptr; + +/** Single HTTP request. */ +class NetworkHTTPRequest { +private: + const std::wstring uri; ///< URI to connect to. + HTTPCallback *callback; ///< Callback to send data back on. + const std::string data; ///< Data to send, if any. + + HINTERNET connection = nullptr; ///< Current connection object. + HINTERNET request = nullptr; ///< Current request object. + std::atomic finished = false; ///< Whether we are finished with the request. + int depth = 0; ///< Current redirect depth we are in. + +public: + NetworkHTTPRequest(const std::wstring &uri, HTTPCallback *callback, const std::string &data); + + ~NetworkHTTPRequest(); + + void Connect(); + bool Receive(); + void WinHttpCallback(DWORD code, void *info, DWORD length); +}; + +static std::vector _http_requests; +static std::vector _new_http_requests; + +/** + * Create a new HTTP request. + * + * @param uri the URI to connect to (https://.../..). + * @param callback the callback to send data back on. + * @param data the data we want to send. When non-empty, this will be a POST request, otherwise a GET request. + */ +NetworkHTTPRequest::NetworkHTTPRequest(const std::wstring &uri, HTTPCallback *callback, const std::string &data) : + uri(uri), + callback(callback), + data(data) +{ +} + +static std::string GetLastErrorAsString() +{ + char buffer[512]; + DWORD error_code = GetLastError(); + + if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, GetModuleHandleA("winhttp.dll"), error_code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL) == 0) { + return fmt::format("unknown error {}", error_code); + } + + return buffer; +} + +/** + * Callback from the WinHTTP library, called when-ever something changes about the HTTP request status. + * + * The callback needs to call some WinHttp functions for certain states, so WinHttp continues + * to read the request. This also allows us to abort when things go wrong, by simply not calling + * those functions. + * Comments with "Next step:" mark where WinHttp needs a call to continue. + * + * @param code The code of the event. + * @param info The information about the event. + * @param length The length of the information. + */ +void NetworkHTTPRequest::WinHttpCallback(DWORD code, void *info, DWORD length) +{ + if (this->finished) return; + + switch (code) { + case WINHTTP_CALLBACK_STATUS_RESOLVING_NAME: + case WINHTTP_CALLBACK_STATUS_NAME_RESOLVED: + case WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER: + case WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER: + case WINHTTP_CALLBACK_STATUS_SENDING_REQUEST: + case WINHTTP_CALLBACK_STATUS_REQUEST_SENT: + case WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE: + case WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED: + case WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION: + case WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED: + case WINHTTP_CALLBACK_STATUS_HANDLE_CREATED: + case WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING: + /* We don't care about these events, and explicitly ignore them. */ + break; + + case WINHTTP_CALLBACK_STATUS_REDIRECT: + /* Make sure we are not in a redirect loop. */ + if (this->depth++ > 5) { + Debug(net, 0, "HTTP request failed: too many redirects"); + this->finished = true; + this->callback->OnFailure(); + return; + } + break; + + case WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE: + /* Next step: read response. */ + WinHttpReceiveResponse(this->request, nullptr); + break; + + case WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE: + { + /* Retrieve the status code. */ + DWORD status_code = 0; + DWORD status_code_size = sizeof(status_code); + WinHttpQueryHeaders(this->request, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &status_code, &status_code_size, WINHTTP_NO_HEADER_INDEX); + Debug(net, 3, "HTTP request status code: {}", status_code); + + /* If there is any error, we simply abort the request. */ + if (status_code >= 400) { + Debug(net, 0, "HTTP request failed: status-code {}", status_code); + this->finished = true; + this->callback->OnFailure(); + return; + } + + /* Next step: query for any data. */ + WinHttpQueryDataAvailable(this->request, nullptr); + } break; + + case WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE: + { + /* Retrieve the amount of data available to process. */ + DWORD size = *(DWORD *)info; + + /* Next step: read the data in a temporary allocated buffer. + * The buffer will be free'd in the next step. */ + char *buffer = size == 0 ? nullptr : MallocT(size); + WinHttpReadData(this->request, buffer, size, 0); + } break; + + case WINHTTP_CALLBACK_STATUS_READ_COMPLETE: + Debug(net, 4, "HTTP callback: {} bytes", length); + + this->callback->OnReceiveData(static_cast(info), length); + /* Free the temporary buffer that was allocated in the previous step. */ + free(info); + + if (length == 0) { + /* Next step: no more data available: request is finished. */ + this->finished = true; + Debug(net, 1, "HTTP request succeeded"); + } else { + /* Next step: query for more data. */ + WinHttpQueryDataAvailable(this->request, nullptr); + } + + break; + + case WINHTTP_CALLBACK_STATUS_SECURE_FAILURE: + case WINHTTP_CALLBACK_STATUS_REQUEST_ERROR: + Debug(net, 0, "HTTP request failed: {}", GetLastErrorAsString()); + this->finished = true; + this->callback->OnFailure(); + break; + + default: + Debug(net, 0, "HTTP request failed: unexepected callback code 0x{:x}", code); + this->finished = true; + this->callback->OnFailure(); + return; + } +} + +static void CALLBACK StaticWinHttpCallback(HINTERNET handle, DWORD_PTR context, DWORD code, void *info, DWORD length) +{ + if (context == 0) return; + + NetworkHTTPRequest *request = (NetworkHTTPRequest *)context; + request->WinHttpCallback(code, info, length); +} + +/** + * Start the HTTP request handling. + * + * This is done in an async manner, so we can do other things while waiting for + * the HTTP request to finish. The actual receiving of the data is done in + * Receive(). + */ +void NetworkHTTPRequest::Connect() +{ + Debug(net, 1, "HTTP request to {}", std::string(uri.begin(), uri.end())); + + URL_COMPONENTS url_components = {}; + wchar_t scheme[32]; + wchar_t hostname[128]; + wchar_t url_path[4096]; + + /* Convert the URL to its components. */ + url_components.dwStructSize = sizeof(url_components); + url_components.lpszScheme = scheme; + url_components.dwSchemeLength = lengthof(scheme); + url_components.lpszHostName = hostname; + url_components.dwHostNameLength = lengthof(hostname); + url_components.lpszUrlPath = url_path; + url_components.dwUrlPathLength = lengthof(url_path); + WinHttpCrackUrl(this->uri.c_str(), 0, 0, &url_components); + + /* Create the HTTP connection. */ + this->connection = WinHttpConnect(_winhttp_session, url_components.lpszHostName, url_components.nPort, 0); + if (this->connection == nullptr) { + Debug(net, 0, "HTTP request failed: {}", GetLastErrorAsString()); + this->finished = true; + this->callback->OnFailure(); + return; + } + + this->request = WinHttpOpenRequest(connection, data.empty() ? L"GET" : L"POST", url_components.lpszUrlPath, nullptr, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, url_components.nScheme == INTERNET_SCHEME_HTTPS ? WINHTTP_FLAG_SECURE : 0); + if (this->request == nullptr) { + WinHttpCloseHandle(this->connection); + + Debug(net, 0, "HTTP request failed: {}", GetLastErrorAsString()); + this->finished = true; + this->callback->OnFailure(); + return; + } + + /* Send the request (possibly with a payload). */ + if (data.empty()) { + WinHttpSendRequest(this->request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, reinterpret_cast(this)); + } else { + WinHttpSendRequest(this->request, L"Content-Type: application/x-www-form-urlencoded\r\n", -1, const_cast(data.c_str()), static_cast(data.size()), static_cast(data.size()), reinterpret_cast(this)); + } +} + +/** + * Poll and process the HTTP request/response. + * + * @return True iff the request is done; no call to Receive() should be done after it returns true. + */ +bool NetworkHTTPRequest::Receive() +{ + if (this->callback->IsCancelled()) { + Debug(net, 1, "HTTP request failed: cancelled by user"); + this->finished = true; + this->callback->OnFailure(); + return true; + } + + return this->finished; +} + +/** + * Destructor of the HTTP request. + * + * Makes sure all handlers are closed, and all memory is free'd. + */ +NetworkHTTPRequest::~NetworkHTTPRequest() +{ + if (this->request) { + WinHttpCloseHandle(this->request); + WinHttpCloseHandle(this->connection); + } +} + +/* static */ void NetworkHTTPSocketHandler::Connect(const std::string &uri, HTTPCallback *callback, const std::string data) +{ + auto request = new NetworkHTTPRequest(std::wstring(uri.begin(), uri.end()), callback, data); + request->Connect(); + _new_http_requests.push_back(request); +} + +/* static */ void NetworkHTTPSocketHandler::HTTPReceive() +{ + if (!_new_http_requests.empty()) { + /* We delay adding new requests, as Receive() below can cause a callback which adds a new requests. */ + _http_requests.insert(_http_requests.end(), _new_http_requests.begin(), _new_http_requests.end()); + _new_http_requests.clear(); + } + + if (_http_requests.empty()) return; + + for (auto it = _http_requests.begin(); it != _http_requests.end(); /* nothing */) { + NetworkHTTPRequest *cur = *it; + + if (cur->Receive()) { + it = _http_requests.erase(it); + delete cur; + continue; + } + + ++it; + } +} + +void NetworkHTTPInitialize() +{ + /* We create a single session, from which we build up every other request. */ + std::string user_agent = fmt::format("OpenTTD/{}", GetNetworkRevisionString()); + _winhttp_session = WinHttpOpen(std::wstring(user_agent.begin(), user_agent.end()).c_str(), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, WINHTTP_FLAG_ASYNC); + + /* Set the callback function for all requests. The "context" maps it back into the actual request instance. */ + WinHttpSetStatusCallback(_winhttp_session, StaticWinHttpCallback, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, 0); + + /* 10 seconds timeout for requests. */ + WinHttpSetTimeouts(_winhttp_session, 10000, 10000, 10000, 10000); +} + +void NetworkHTTPUninitialize() +{ + WinHttpCloseHandle(_winhttp_session); +} diff --git a/src/network/core/tcp.h b/src/network/core/tcp.h index 7bce8f6c0afad..252f2c2456e94 100644 --- a/src/network/core/tcp.h +++ b/src/network/core/tcp.h @@ -115,7 +115,7 @@ class TCPConnecter { public: TCPConnecter() {}; - TCPConnecter(const std::string &connection_string, uint16 default_port, NetworkAddress bind_address = {}, int family = AF_UNSPEC); + TCPConnecter(const std::string &connection_string, uint16 default_port, const NetworkAddress &bind_address = {}, int family = AF_UNSPEC); virtual ~TCPConnecter(); /** diff --git a/src/network/core/tcp_connect.cpp b/src/network/core/tcp_connect.cpp index a9cc77934e136..17c1de886f026 100644 --- a/src/network/core/tcp_connect.cpp +++ b/src/network/core/tcp_connect.cpp @@ -29,7 +29,7 @@ static std::vector _tcp_connecters; * @param default_port If not indicated in connection_string, what port to use. * @param bind_address The local bind address to use. Defaults to letting the OS find one. */ -TCPConnecter::TCPConnecter(const std::string &connection_string, uint16 default_port, NetworkAddress bind_address, int family) : +TCPConnecter::TCPConnecter(const std::string &connection_string, uint16 default_port, const NetworkAddress &bind_address, int family) : bind_address(bind_address), family(family) { diff --git a/src/network/core/tcp_content.cpp b/src/network/core/tcp_content.cpp index 84573d5575ecd..14108fb8ab20d 100644 --- a/src/network/core/tcp_content.cpp +++ b/src/network/core/tcp_content.cpp @@ -85,7 +85,6 @@ const char *ContentInfo::GetTextfile(TextfileType type) const break; case CONTENT_TYPE_SCENARIO: case CONTENT_TYPE_HEIGHTMAP: - extern const char *FindScenario(const ContentInfo *ci, bool md5sum); tmp = FindScenario(this, true); break; } diff --git a/src/network/core/tcp_game.cpp b/src/network/core/tcp_game.cpp index 2e9965913383a..ad94536aaa8ad 100644 --- a/src/network/core/tcp_game.cpp +++ b/src/network/core/tcp_game.cpp @@ -42,7 +42,6 @@ NetworkRecvStatus NetworkGameSocketHandler::CloseConnection(bool error) { /* Clients drop back to the main menu */ if (!_network_server && _networking) { - extern void ClientNetworkEmergencySave(); // from network_client.cpp ClientNetworkEmergencySave(); _switch_mode = SM_MENU; _networking = false; diff --git a/src/network/core/tcp_http.cpp b/src/network/core/tcp_http.cpp deleted file mode 100644 index 3472a7642ade4..0000000000000 --- a/src/network/core/tcp_http.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/* - * 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 tcp_http.cpp Basic functions to receive and send HTTP TCP packets. - */ - -#include "../../stdafx.h" -#include "../../debug.h" -#include "../../rev.h" -#include "../network_internal.h" -#include "game_info.h" - -#include "tcp_http.h" - -#include "../../safeguards.h" - -/** List of open HTTP connections. */ -static std::vector _http_connections; - -/** - * Start the querying - * @param s the socket of this connection - * @param callback the callback for HTTP retrieval - * @param host the hostname of the server to connect to - * @param url the url at the server - * @param data the data to send - * @param depth the depth (redirect recursion) of the queries - */ -NetworkHTTPSocketHandler::NetworkHTTPSocketHandler(SOCKET s, - HTTPCallback *callback, const std::string &host, const char *url, - const char *data, int depth) : - NetworkSocketHandler(), - recv_pos(0), - recv_length(0), - callback(callback), - data(data), - redirect_depth(depth), - sock(s) -{ - Debug(net, 5, "[tcp/http] Requesting {}{}", host, url); - std::string request; - if (data != nullptr) { - request = fmt::format("POST {} HTTP/1.0\r\nHost: {}\r\nUser-Agent: OpenTTD/{}\r\nContent-Type: text/plain\r\nContent-Length: {}\r\n\r\n{}\r\n", url, host, GetNetworkRevisionString(), strlen(data), data); - } else { - request = fmt::format("GET {} HTTP/1.0\r\nHost: {}\r\nUser-Agent: OpenTTD/{}\r\n\r\n", url, host, GetNetworkRevisionString()); - } - - ssize_t res = send(this->sock, request.data(), (int)request.size(), 0); - if (res != (ssize_t)request.size()) { - /* Sending all data failed. Socket can't handle this little bit - * of information? Just fall back to the old system! */ - this->callback->OnFailure(); - delete this; - return; - } - - _http_connections.push_back(this); -} - -/** Free whatever needs to be freed. */ -NetworkHTTPSocketHandler::~NetworkHTTPSocketHandler() -{ - this->CloseSocket(); - - free(this->data); -} - -/** - * Close the actual socket of the connection. - */ -void NetworkHTTPSocketHandler::CloseSocket() -{ - if (this->sock != INVALID_SOCKET) closesocket(this->sock); - this->sock = INVALID_SOCKET; -} - -/** - * Helper to simplify the error handling. - * @param msg the error message to show. - */ -#define return_error(msg) { Debug(net, 1, msg); return -1; } - -static const char * const NEWLINE = "\r\n"; ///< End of line marker -static const char * const END_OF_HEADER = "\r\n\r\n"; ///< End of header marker -static const char * const HTTP_1_0 = "HTTP/1.0 "; ///< Preamble for HTTP 1.0 servers -static const char * const HTTP_1_1 = "HTTP/1.1 "; ///< Preamble for HTTP 1.1 servers -static const char * const CONTENT_LENGTH = "Content-Length: "; ///< Header for the length of the content -static const char * const LOCATION = "Location: "; ///< Header for location - -/** - * Handle the header of a HTTP reply. - * @return amount of data to continue downloading. - * > 0: we need to download N bytes. - * = 0: we're being redirected. - * < 0: an error occurred. Downloading failed. - * @note if an error occurred the header might not be in its - * original state. No effort is undertaken to bring - * the header in its original state. - */ -int NetworkHTTPSocketHandler::HandleHeader() -{ - assert(strlen(HTTP_1_0) == strlen(HTTP_1_1)); - assert(strstr(this->recv_buffer, END_OF_HEADER) != nullptr); - - /* We expect a HTTP/1.[01] reply */ - if (strncmp(this->recv_buffer, HTTP_1_0, strlen(HTTP_1_0)) != 0 && - strncmp(this->recv_buffer, HTTP_1_1, strlen(HTTP_1_1)) != 0) { - return_error("[tcp/http] Received invalid HTTP reply"); - } - - char *status = this->recv_buffer + strlen(HTTP_1_0); - if (strncmp(status, "200", 3) == 0) { - /* We are going to receive a document. */ - - /* Get the length of the document to receive */ - char *length = strcasestr(this->recv_buffer, CONTENT_LENGTH); - if (length == nullptr) return_error("[tcp/http] Missing 'content-length' header"); - - /* Skip the header */ - length += strlen(CONTENT_LENGTH); - - /* Search the end of the line. This is safe because the header will - * always end with two newlines. */ - char *end_of_line = strstr(length, NEWLINE); - - /* Read the length */ - *end_of_line = '\0'; - int len = atoi(length); - /* Restore the header. */ - *end_of_line = '\r'; - - /* Make sure we're going to download at least something; - * zero sized files are, for OpenTTD's purposes, always - * wrong. You can't have gzips of 0 bytes! */ - if (len == 0) return_error("[tcp/http] Refusing to download 0 bytes"); - - Debug(net, 7, "[tcp/http] Downloading {} bytes", len); - return len; - } - - if (strncmp(status, "301", 3) != 0 && - strncmp(status, "302", 3) != 0 && - strncmp(status, "303", 3) != 0 && - strncmp(status, "307", 3) != 0) { - /* We are not going to be redirected :(. */ - - /* Search the end of the line. This is safe because the header will - * always end with two newlines. */ - *strstr(status, NEWLINE) = '\0'; - Debug(net, 1, "[tcp/http] Unhandled status reply {}", status); - return -1; - } - - if (this->redirect_depth == 5) return_error("[tcp/http] Too many redirects, looping redirects?"); - - /* Redirect to other URL */ - char *uri = strcasestr(this->recv_buffer, LOCATION); - if (uri == nullptr) return_error("[tcp/http] Missing 'location' header for redirect"); - - uri += strlen(LOCATION); - - /* Search the end of the line. This is safe because the header will - * always end with two newlines. */ - char *end_of_line = strstr(uri, NEWLINE); - *end_of_line = '\0'; - - Debug(net, 7, "[tcp/http] Redirecting to {}", uri); - - int ret = NetworkHTTPSocketHandler::Connect(uri, this->callback, this->data, this->redirect_depth + 1); - if (ret != 0) return ret; - - /* We've relinquished control of data now. */ - this->data = nullptr; - - /* Restore the header. */ - *end_of_line = '\r'; - return 0; -} - -/** - * Connect to the given URI. - * @param uri the URI to connect to. - * @param callback the callback to send data back on. - * @param data the data we want to send (as POST). - * @param depth the recursion/redirect depth. - */ -/* static */ int NetworkHTTPSocketHandler::Connect(char *uri, HTTPCallback *callback, const char *data, int depth) -{ - char *hname = strstr(uri, "://"); - if (hname == nullptr) return_error("[tcp/http] Invalid location"); - - hname += 3; - - char *url = strchr(hname, '/'); - if (url == nullptr) return_error("[tcp/http] Invalid location"); - - *url = '\0'; - - std::string hostname = std::string(hname); - - /* Restore the URL. */ - *url = '/'; - new NetworkHTTPContentConnecter(hostname, callback, url, data, depth); - return 0; -} - -#undef return_error - -/** - * Handle receiving of HTTP data. - * @return state of the receival of HTTP data. - * > 0: we need more cycles for downloading - * = 0: we are done downloading - * < 0: we have hit an error - */ -int NetworkHTTPSocketHandler::Receive() -{ - for (;;) { - ssize_t res = recv(this->sock, (char *)this->recv_buffer + this->recv_pos, lengthof(this->recv_buffer) - this->recv_pos, 0); - if (res == -1) { - NetworkError err = NetworkError::GetLast(); - if (!err.WouldBlock()) { - /* Something went wrong... */ - if (!err.IsConnectionReset()) Debug(net, 0, "Recv failed: {}", err.AsString()); - return -1; - } - /* Connection would block, so stop for now */ - return 1; - } - - /* No more data... did we get everything we wanted? */ - if (res == 0) { - if (this->recv_length != 0) return -1; - - this->callback->OnReceiveData(nullptr, 0); - return 0; - } - - /* Wait till we read the end-of-header identifier */ - if (this->recv_length == 0) { - ssize_t read = this->recv_pos + res; - ssize_t end = std::min(read, lengthof(this->recv_buffer) - 1); - - /* Do a 'safe' search for the end of the header. */ - char prev = this->recv_buffer[end]; - this->recv_buffer[end] = '\0'; - char *end_of_header = strstr(this->recv_buffer, END_OF_HEADER); - this->recv_buffer[end] = prev; - - if (end_of_header == nullptr) { - if (read == lengthof(this->recv_buffer)) { - Debug(net, 1, "[tcp/http] Header too big"); - return -1; - } - this->recv_pos = read; - } else { - int ret = this->HandleHeader(); - if (ret <= 0) return ret; - - this->recv_length = ret; - - end_of_header += strlen(END_OF_HEADER); - int len = std::min(read - (end_of_header - this->recv_buffer), res); - if (len != 0) { - this->callback->OnReceiveData(end_of_header, len); - this->recv_length -= len; - } - - this->recv_pos = 0; - } - } else { - res = std::min(this->recv_length, res); - /* Receive whatever we're expecting. */ - this->callback->OnReceiveData(this->recv_buffer, res); - this->recv_length -= res; - } - } -} - -/** - * Do the receiving for all HTTP connections. - */ -/* static */ void NetworkHTTPSocketHandler::HTTPReceive() -{ - /* No connections, just bail out. */ - if (_http_connections.size() == 0) return; - - fd_set read_fd; - struct timeval tv; - - FD_ZERO(&read_fd); - for (NetworkHTTPSocketHandler *handler : _http_connections) { - FD_SET(handler->sock, &read_fd); - } - - tv.tv_sec = tv.tv_usec = 0; // don't block at all. - int n = select(FD_SETSIZE, &read_fd, nullptr, nullptr, &tv); - if (n == -1) return; - - for (auto iter = _http_connections.begin(); iter < _http_connections.end(); /* nothing */) { - NetworkHTTPSocketHandler *cur = *iter; - - if (FD_ISSET(cur->sock, &read_fd)) { - int ret = cur->Receive(); - /* First send the failure. */ - if (ret < 0) cur->callback->OnFailure(); - if (ret <= 0) { - /* Then... the connection can be closed */ - cur->CloseSocket(); - iter = _http_connections.erase(iter); - delete cur; - continue; - } - } - iter++; - } -} diff --git a/src/network/core/tcp_http.h b/src/network/core/tcp_http.h deleted file mode 100644 index 608d50200cff3..0000000000000 --- a/src/network/core/tcp_http.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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 tcp_http.h Basic functions to receive and send HTTP TCP packets. - */ - -#ifndef NETWORK_CORE_TCP_HTTP_H -#define NETWORK_CORE_TCP_HTTP_H - -#include "tcp.h" - -/** Callback for when the HTTP handler has something to tell us. */ -struct HTTPCallback { - /** - * An error has occurred and the connection has been closed. - * @note HTTP socket handler is closed/freed. - */ - virtual void OnFailure() = 0; - - /** - * We're receiving data. - * @param data the received data, nullptr when all data has been received. - * @param length the amount of received data, 0 when all data has been received. - * @note When nullptr is sent the HTTP socket handler is closed/freed. - */ - virtual void OnReceiveData(const char *data, size_t length) = 0; - - /** Silentium */ - virtual ~HTTPCallback() {} -}; - -/** Base socket handler for HTTP traffic. */ -class NetworkHTTPSocketHandler : public NetworkSocketHandler { -private: - char recv_buffer[4096]; ///< Partially received message. - int recv_pos; ///< Current position in buffer. - int recv_length; ///< Length of the data still retrieving. - HTTPCallback *callback; ///< The callback to call for the incoming data. - const char *data; ///< The (POST) data we might want to forward (to a redirect). - int redirect_depth; ///< The depth of the redirection. - - int HandleHeader(); - int Receive(); -public: - SOCKET sock; ///< The socket currently connected to - - /** - * Whether this socket is currently bound to a socket. - * @return true when the socket is bound, false otherwise - */ - bool IsConnected() const - { - return this->sock != INVALID_SOCKET; - } - - void CloseSocket(); - - NetworkHTTPSocketHandler(SOCKET sock, HTTPCallback *callback, - const std::string &host, const char *url, const char *data, int depth); - - ~NetworkHTTPSocketHandler(); - - static int Connect(char *uri, HTTPCallback *callback, - const char *data = nullptr, int depth = 0); - - static void HTTPReceive(); -}; - -/** Connect with a HTTP server and do ONE query. */ -class NetworkHTTPContentConnecter : TCPConnecter { - std::string hostname; ///< Hostname we are connecting to. - HTTPCallback *callback; ///< Callback to tell that we received some data (or won't). - const char *url; ///< The URL we want to get at the server. - const char *data; ///< The data to send - int depth; ///< How far we have recursed - -public: - /** - * Start the connecting. - * @param hostname The hostname to connect to. - * @param callback The callback for HTTP retrieval. - * @param url The url at the server. - * @param data The data to send. - * @param depth The depth (redirect recursion) of the queries. - */ - NetworkHTTPContentConnecter(const std::string &hostname, HTTPCallback *callback, const char *url, const char *data = nullptr, int depth = 0) : - TCPConnecter(hostname, 80), - hostname(hostname), - callback(callback), - url(stredup(url)), - data(data), - depth(depth) - { - } - - /** Free all our allocated data. */ - ~NetworkHTTPContentConnecter() - { - free(this->url); - } - - void OnFailure() override - { - this->callback->OnFailure(); - free(this->data); - } - - void OnConnect(SOCKET s) override - { - new NetworkHTTPSocketHandler(s, this->callback, this->hostname, this->url, this->data, this->depth); - /* We've relinquished control of data now. */ - this->data = nullptr; - } -}; - -#endif /* NETWORK_CORE_TCP_HTTP_H */ diff --git a/src/network/network.cpp b/src/network/network.cpp index 66c1956561914..00cad970863d5 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -85,9 +85,6 @@ static_assert((int)NETWORK_COMPANY_NAME_LENGTH == MAX_LENGTH_COMPANY_NAME_CHARS /** The amount of clients connected */ byte _network_clients_connected = 0; -/* Some externs / forwards */ -extern void StateGameLoop(); - /** * Return whether there is any client connected or trying to connect at all. * @return whether we have any client activity @@ -609,6 +606,7 @@ void NetworkClose(bool close_admins) delete[] _network_company_states; _network_company_states = nullptr; + _network_company_passworded = 0; InitializeNetworkPools(close_admins); } @@ -1270,12 +1268,14 @@ void NetworkStartUp() NetworkUDPInitialize(); Debug(net, 3, "Network online, multiplayer available"); NetworkFindBroadcastIPs(&_broadcast_list); + NetworkHTTPInitialize(); } /** This shuts the network down */ void NetworkShutDown() { NetworkDisconnect(true); + NetworkHTTPUninitialize(); NetworkUDPClose(); Debug(net, 3, "Shutting down network"); diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index 6729ece6c3cc7..4a2baa3f23810 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.cpp @@ -178,8 +178,8 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendWelcome() p->Send_uint32(_settings_game.game_creation.generation_seed); p->Send_uint8 (_settings_game.game_creation.landscape); p->Send_uint32(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1)); - p->Send_uint16(MapSizeX()); - p->Send_uint16(MapSizeY()); + p->Send_uint16(Map::SizeX()); + p->Send_uint16(Map::SizeY()); this->SendPacket(p); diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp index 8645c11da84c5..ffea399e29512 100644 --- a/src/network/network_chat_gui.cpp +++ b/src/network/network_chat_gui.cpp @@ -17,6 +17,7 @@ #include "../window_func.h" #include "../toolbar_gui.h" #include "../core/geometry_func.hpp" +#include "../zoom_func.h" #include "network.h" #include "network_client.h" #include "network_base.h" @@ -106,8 +107,8 @@ void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const std::st void NetworkReInitChatBoxSize() { _chatmsg_box.y = 3 * FONT_HEIGHT_NORMAL; - _chatmsg_box.height = MAX_CHAT_MESSAGES * (FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING) + 4; - _chatmessage_backup = ReallocT(_chatmessage_backup, _chatmsg_box.width * _chatmsg_box.height * BlitterFactory::GetCurrentBlitter()->GetBytesPerPixel()); + _chatmsg_box.height = MAX_CHAT_MESSAGES * (FONT_HEIGHT_NORMAL + ScaleGUITrad(NETWORK_CHAT_LINE_SPACING)) + ScaleGUITrad(4); + _chatmessage_backup = ReallocT(_chatmessage_backup, static_cast(_chatmsg_box.width) * _chatmsg_box.height * BlitterFactory::GetCurrentBlitter()->GetBytesPerPixel()); } /** Initialize all buffers of the chat visualisation. */ @@ -116,7 +117,7 @@ void NetworkInitChatMessage() MAX_CHAT_MESSAGES = _settings_client.gui.network_chat_box_height; _chatmsg_list.clear(); - _chatmsg_box.x = 10; + _chatmsg_box.x = ScaleGUITrad(10); _chatmsg_box.width = _settings_client.gui.network_chat_box_width_pct * _screen.width / 100; NetworkReInitChatBoxSize(); _chatmessage_visible = false; @@ -213,7 +214,7 @@ void NetworkDrawChatMessage() } if (width <= 0 || height <= 0) return; - assert(blitter->BufferSize(width, height) <= (int)(_chatmsg_box.width * _chatmsg_box.height * blitter->GetBytesPerPixel())); + assert(blitter->BufferSize(width, height) <= static_cast(_chatmsg_box.width) * _chatmsg_box.height * blitter->GetBytesPerPixel()); /* Make a copy of the screen as it is before painting (for undraw) */ blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), _chatmessage_backup, width, height); @@ -242,7 +243,7 @@ void NetworkDrawChatMessage() for (auto &cmsg : _chatmsg_list) { if (!show_all && cmsg.remove_time < now) continue; - ypos = DrawStringMultiLine(_chatmsg_box.x + 3, _chatmsg_box.x + _chatmsg_box.width - 1, top, ypos, cmsg.message, cmsg.colour, SA_LEFT | SA_BOTTOM | SA_FORCE) - NETWORK_CHAT_LINE_SPACING; + ypos = DrawStringMultiLine(_chatmsg_box.x + ScaleGUITrad(3), _chatmsg_box.x + _chatmsg_box.width - 1, top, ypos, cmsg.message, cmsg.colour, SA_LEFT | SA_BOTTOM | SA_FORCE) - NETWORK_CHAT_LINE_SPACING; if (ypos < top) break; } @@ -508,7 +509,7 @@ static const NWidgetPart _nested_chat_window_widgets[] = { NWidget(WWT_CLOSEBOX, COLOUR_GREY, WID_NC_CLOSE), NWidget(WWT_PANEL, COLOUR_GREY, WID_NC_BACKGROUND), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXT, COLOUR_GREY, WID_NC_DESTINATION), SetMinimalSize(62, 12), SetPadding(1, 0, 1, 0), SetTextColour(TC_BLACK), SetAlignment(SA_TOP | SA_RIGHT), SetDataTip(STR_NULL, STR_NULL), + NWidget(WWT_TEXT, COLOUR_GREY, WID_NC_DESTINATION), SetMinimalSize(62, 12), SetPadding(1, 0, 1, 0), SetAlignment(SA_VERT_CENTER | SA_RIGHT), SetDataTip(STR_NULL, STR_NULL), NWidget(WWT_EDITBOX, COLOUR_GREY, WID_NC_TEXTBOX), SetMinimalSize(100, 12), SetPadding(1, 0, 1, 0), SetResize(1, 0), SetDataTip(STR_NETWORK_CHAT_OSKTITLE, STR_NULL), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NC_SENDBUTTON), SetMinimalSize(62, 12), SetPadding(1, 0, 1, 0), SetDataTip(STR_NETWORK_CHAT_SEND, STR_NULL), diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 587a39e81e795..7322b08236d4f 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -223,7 +223,9 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res) ClientNetworkEmergencySave(); } - _switch_mode = SM_MENU; + CloseWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); + + if (_game_mode != GM_MENU) _switch_mode = SM_MENU; _networking = false; } @@ -264,7 +266,6 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res) NetworkExecuteLocalCommandQueue(); - extern void StateGameLoop(); StateGameLoop(); /* Check if we are in sync! */ @@ -532,7 +533,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FULL(Packet *p) { /* We try to join a server which is full */ ShowErrorMessage(STR_NETWORK_ERROR_SERVER_FULL, INVALID_STRING_ID, WL_CRITICAL); - CloseWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); return NETWORK_RECV_STATUS_SERVER_FULL; } @@ -541,7 +541,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_BANNED(Packet * { /* We try to join a server where we are banned */ ShowErrorMessage(STR_NETWORK_ERROR_SERVER_BANNED, INVALID_STRING_ID, WL_CRITICAL); - CloseWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); return NETWORK_RECV_STATUS_SERVER_BANNED; } @@ -648,8 +647,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p /* Perform an emergency save if we had already entered the game */ if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave(); - CloseWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); - return NETWORK_RECV_STATUS_SERVER_ERROR; } @@ -818,7 +815,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet this->last_packet = std::chrono::steady_clock::now(); if (!load_success) { - CloseWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); ShowErrorMessage(STR_NETWORK_ERROR_SAVEGAMEERROR, INVALID_STRING_ID, WL_CRITICAL); return NETWORK_RECV_STATUS_SAVEGAME; } @@ -1115,6 +1111,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CONFIG_UPDATE(P _network_server_max_companies = p->Recv_uint8(); _network_server_name = p->Recv_string(NETWORK_NAME_LENGTH); + SetWindowClassesDirty(WC_CLIENT_LIST); return NETWORK_RECV_STATUS_OKAY; } @@ -1323,11 +1320,20 @@ bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio) return false; } +/** + * Get the maximum number of companies that are allowed by the server. + * @return The number of companies allowed. + */ +uint NetworkMaxCompaniesAllowed() +{ + return _network_server ? _settings_client.network.max_companies : _network_server_max_companies; +} + /** * Check if max_companies has been reached on the server (local check only). * @return true if the max value has been reached or exceeded, false otherwise. */ bool NetworkMaxCompaniesReached() { - return Company::GetNumItems() >= (_network_server ? _settings_client.network.max_companies : _network_server_max_companies); + return Company::GetNumItems() >= NetworkMaxCompaniesAllowed(); } diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index d39618abf41f4..ceb1df20da82e 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.cpp @@ -26,6 +26,7 @@ #include "../group_cmd.h" #include "../industry_cmd.h" #include "../landscape_cmd.h" +#include "../league_cmd.h" #include "../misc_cmd.h" #include "../news_cmd.h" #include "../object_cmd.h" @@ -149,7 +150,7 @@ constexpr UnpackNetworkCommandProc MakeUnpackNetworkCommandCallback() noexcept template constexpr UnpackDispatchT MakeUnpackNetworkCommand(std::index_sequence) noexcept { - return UnpackDispatchT{{ {MakeUnpackNetworkCommandCallback()}...}}; + return UnpackDispatchT{{ MakeUnpackNetworkCommandCallback()...}}; } template @@ -260,17 +261,15 @@ static size_t FindCallbackIndex(CommandCallback *callback) * @param err_message Message prefix to show on error * @param callback A callback function to call after the command is finished * @param company The company that wants to send the command - * @param location Location of the command (e.g. for error message position) * @param cmd_data The command proc arguments. */ -void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex location, const CommandDataBuffer &cmd_data) +void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, const CommandDataBuffer &cmd_data) { CommandPacket c; c.company = company; c.cmd = cmd; c.err_msg = err_message; c.callback = callback; - c.tile = location; c.data = cmd_data; if (_network_server) { @@ -428,7 +427,6 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c if (!IsValidCommand(cp->cmd)) return "invalid command"; if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "single-player only command"; cp->err_msg = p->Recv_uint16(); - cp->tile = p->Recv_uint32(); cp->data = _cmd_dispatch[cp->cmd].Sanitize(p->Recv_buffer()); byte callback = p->Recv_uint8(); @@ -448,7 +446,6 @@ void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp) p->Send_uint8(cp->company); p->Send_uint16(cp->cmd); p->Send_uint16(cp->err_msg); - p->Send_uint32(cp->tile); p->Send_buffer(cp->data); size_t callback = FindCallbackIndex(cp->callback); @@ -539,5 +536,5 @@ template void UnpackNetworkCommand(const CommandPacket* cp) { auto args = EndianBufferReader::ToValue::Args>(cp->data); - Command::PostFromNet(cp->err_msg, std::get(_callback_tuple), cp->my_cmd, cp->tile, args); + Command::PostFromNet(cp->err_msg, std::get(_callback_tuple), cp->my_cmd, args); } diff --git a/src/network/network_content.cpp b/src/network/network_content.cpp index d6381a71b698a..6ac2cbbd10e25 100644 --- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -311,13 +311,6 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContent(uint &files, uin { bytes = 0; -#ifdef __EMSCRIPTEN__ - /* Emscripten is loaded via an HTTPS connection. As such, it is very - * difficult to make HTTP connections. So always use the TCP method of - * downloading content. */ - fallback = true; -#endif - ContentIDList content; for (const ContentInfo *ci : this->infos) { if (!ci->IsSelected() || ci->state == ContentInfo::ALREADY_HERE) continue; @@ -331,6 +324,8 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContent(uint &files, uin /* If there's nothing to download, do nothing. */ if (files == 0) return; + this->isCancelled = false; + if (_settings_client.network.no_http_content_downloads || fallback) { this->DownloadSelectedContentFallback(content); } else { @@ -344,25 +339,14 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContent(uint &files, uin */ void ClientNetworkContentSocketHandler::DownloadSelectedContentHTTP(const ContentIDList &content) { - uint count = (uint)content.size(); - - /* Allocate memory for the whole request. - * Requests are "id\nid\n..." (as strings), so assume the maximum ID, - * which is uint32 so 10 characters long. Then the newlines and - * multiply that all with the count and then add the '\0'. */ - uint bytes = (10 + 1) * count + 1; - char *content_request = MallocT(bytes); - const char *lastof = content_request + bytes - 1; - - char *p = content_request; + std::string content_request; for (const ContentID &id : content) { - p += seprintf(p, lastof, "%d\n", id); + content_request += std::to_string(id) + "\n"; } this->http_response_index = -1; - new NetworkHTTPContentConnecter(NetworkContentMirrorConnectionString(), this, NETWORK_CONTENT_MIRROR_URL, content_request); - /* NetworkHTTPContentConnecter takes over freeing of content_request! */ + NetworkHTTPSocketHandler::Connect(NetworkContentMirrorUriString(), this, content_request); } /** @@ -592,25 +576,31 @@ void ClientNetworkContentSocketHandler::AfterDownload() } } +bool ClientNetworkContentSocketHandler::IsCancelled() const +{ + return this->isCancelled; +} + /* Also called to just clean up the mess. */ void ClientNetworkContentSocketHandler::OnFailure() { - /* If we fail, download the rest via the 'old' system. */ - uint files, bytes; - this->DownloadSelectedContent(files, bytes, true); - this->http_response.clear(); this->http_response.shrink_to_fit(); this->http_response_index = -2; if (this->curFile != nullptr) { - /* Revert the download progress when we are going for the old system. */ - long size = ftell(this->curFile); - if (size > 0) this->OnDownloadProgress(this->curInfo, (int)-size); + this->OnDownloadProgress(this->curInfo, -1); fclose(this->curFile); this->curFile = nullptr; } + + /* If we fail, download the rest via the 'old' system. */ + if (!this->isCancelled) { + uint files, bytes; + + this->DownloadSelectedContent(files, bytes, true); + } } void ClientNetworkContentSocketHandler::OnReceiveData(const char *data, size_t length) @@ -746,7 +736,8 @@ ClientNetworkContentSocketHandler::ClientNetworkContentSocketHandler() : http_response_index(-2), curFile(nullptr), curInfo(nullptr), - isConnecting(false) + isConnecting(false), + isCancelled(false) { this->lastActivity = std::chrono::steady_clock::now(); } @@ -792,7 +783,10 @@ class NetworkContentConnecter : TCPConnecter { void ClientNetworkContentSocketHandler::Connect() { if (this->sock != INVALID_SOCKET || this->isConnecting) return; + + this->isCancelled = false; this->isConnecting = true; + new NetworkContentConnecter(NetworkContentServerConnectionString()); } @@ -801,6 +795,7 @@ void ClientNetworkContentSocketHandler::Connect() */ NetworkRecvStatus ClientNetworkContentSocketHandler::CloseConnection(bool error) { + this->isCancelled = true; NetworkContentSocketHandler::CloseConnection(); if (this->sock == INVALID_SOCKET) return NETWORK_RECV_STATUS_OKAY; @@ -1054,11 +1049,11 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci) * After that's done run over them once again to test their children * to unselect. Don't do it immediately because it'll do exactly what * we're doing now. */ - for (const ContentInfo *c : parents) { - if (c->state == ContentInfo::AUTOSELECTED) this->Unselect(c->id); + for (const ContentInfo *parent : parents) { + if (parent->state == ContentInfo::AUTOSELECTED) this->Unselect(parent->id); } - for (const ContentInfo *c : parents) { - this->CheckDependencyState(this->GetContent(c->id)); + for (const ContentInfo *parent : parents) { + this->CheckDependencyState(this->GetContent(parent->id)); } } } diff --git a/src/network/network_content.h b/src/network/network_content.h index cf60681a20afc..8a2877f9047e6 100644 --- a/src/network/network_content.h +++ b/src/network/network_content.h @@ -11,7 +11,7 @@ #define NETWORK_CONTENT_H #include "core/tcp_content.h" -#include "core/tcp_http.h" +#include "core/http.h" #include /** Vector with content info */ @@ -76,6 +76,7 @@ class ClientNetworkContentSocketHandler : public NetworkContentSocketHandler, Co FILE *curFile; ///< Currently downloaded file ContentInfo *curInfo; ///< Information about the currently downloaded file bool isConnecting; ///< Whether we're connecting + bool isCancelled; ///< Whether the download has been cancelled std::chrono::steady_clock::time_point lastActivity; ///< The last time there was network activity friend class NetworkContentConnecter; @@ -94,6 +95,7 @@ class ClientNetworkContentSocketHandler : public NetworkContentSocketHandler, Co void OnFailure() override; void OnReceiveData(const char *data, size_t length) override; + bool IsCancelled() const override; bool BeforeDownload(); void AfterDownload(); diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 483e2b5273b57..2f3375f2a5544 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -21,6 +21,7 @@ #include "../querystring_gui.h" #include "../core/geometry_func.hpp" #include "../textfile_gui.h" +#include "../fios.h" #include "network_content_gui.h" @@ -81,14 +82,12 @@ void ShowContentTextfileWindow(TextfileType file_type, const ContentInfo *ci) /** Nested widgets for the download window. */ static const NWidgetPart _nested_network_content_download_status_window_widgets[] = { NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_CONTENT_DOWNLOAD_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_PANEL, COLOUR_GREY, WID_NCDS_BACKGROUND), - NWidget(NWID_SPACER), SetMinimalSize(350, 0), SetMinimalTextLines(3, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 30), - NWidget(NWID_HORIZONTAL), - NWidget(NWID_SPACER), SetMinimalSize(125, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCDS_CANCELOK), SetMinimalSize(101, 12), SetDataTip(STR_BUTTON_CANCEL, STR_NULL), - NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NCDS_PROGRESS_BAR), SetFill(1, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NCDS_PROGRESS_TEXT), SetFill(1, 0), SetMinimalSize(350, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NCDS_CANCELOK), SetDataTip(STR_BUTTON_CANCEL, STR_NULL), SetFill(1, 0), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 4), EndContainer(), }; @@ -101,7 +100,7 @@ static WindowDesc _network_content_download_status_window_desc( ); BaseNetworkContentDownloadStatusWindow::BaseNetworkContentDownloadStatusWindow(WindowDesc *desc) : - Window(desc), cur_id(UINT32_MAX) + Window(desc), downloaded_bytes(0), downloaded_files(0), cur_id(UINT32_MAX) { _network_content_client.AddCallback(this); _network_content_client.DownloadSelectedContent(this->total_files, this->total_bytes); @@ -115,33 +114,56 @@ void BaseNetworkContentDownloadStatusWindow::Close() this->Window::Close(); } -void BaseNetworkContentDownloadStatusWindow::DrawWidget(const Rect &r, int widget) const +void BaseNetworkContentDownloadStatusWindow::UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { - if (widget != WID_NCDS_BACKGROUND) return; - - /* Draw nice progress bar :) */ - DrawFrameRect(r.left + 20, r.top + 4, r.left + 20 + (int)((this->width - 40LL) * this->downloaded_bytes / this->total_bytes), r.top + 14, COLOUR_MAUVE, FR_NONE); - - int y = r.top + 20; - SetDParam(0, this->downloaded_bytes); - SetDParam(1, this->total_bytes); - SetDParam(2, this->downloaded_bytes * 100LL / this->total_bytes); - DrawString(r.left + 2, r.right - 2, y, STR_CONTENT_DOWNLOAD_PROGRESS_SIZE, TC_FROMSTRING, SA_HOR_CENTER); - - StringID str; - if (this->downloaded_bytes == this->total_bytes) { - str = STR_CONTENT_DOWNLOAD_COMPLETE; - } else if (!this->name.empty()) { - SetDParamStr(0, this->name); - SetDParam(1, this->downloaded_files); - SetDParam(2, this->total_files); - str = STR_CONTENT_DOWNLOAD_FILE; - } else { - str = STR_CONTENT_DOWNLOAD_INITIALISE; + switch (widget) { + case WID_NCDS_PROGRESS_BAR: + SetDParamMaxDigits(0, 8); + SetDParamMaxDigits(1, 8); + SetDParamMaxDigits(2, 8); + *size = GetStringBoundingBox(STR_CONTENT_DOWNLOAD_PROGRESS_SIZE); + /* We need some spacing for the 'border' */ + size->height += WidgetDimensions::scaled.frametext.Horizontal(); + size->width += WidgetDimensions::scaled.frametext.Vertical(); + break; + + case WID_NCDS_PROGRESS_TEXT: + size->height = FONT_HEIGHT_NORMAL * 2 + WidgetDimensions::scaled.vsep_normal; + break; } +} + +void BaseNetworkContentDownloadStatusWindow::DrawWidget(const Rect &r, int widget) const +{ + switch (widget) { + case WID_NCDS_PROGRESS_BAR: { + /* Draw the % complete with a bar and a text */ + DrawFrameRect(r, COLOUR_GREY, FR_BORDERONLY | FR_LOWERED); + Rect ir = r.Shrink(WidgetDimensions::scaled.bevel); + DrawFrameRect(ir.WithWidth((uint64)ir.Width() * this->downloaded_bytes / this->total_bytes, false), COLOUR_MAUVE, FR_NONE); + SetDParam(0, this->downloaded_bytes); + SetDParam(1, this->total_bytes); + SetDParam(2, this->downloaded_bytes * 100LL / this->total_bytes); + DrawString(ir.left, ir.right, CenterBounds(ir.top, ir.bottom, FONT_HEIGHT_NORMAL), STR_CONTENT_DOWNLOAD_PROGRESS_SIZE, TC_FROMSTRING, SA_HOR_CENTER); + break; + } - y += FONT_HEIGHT_NORMAL + 5; - DrawStringMultiLine(r.left + 2, r.right - 2, y, y + FONT_HEIGHT_NORMAL * 2, str, TC_FROMSTRING, SA_CENTER); + case WID_NCDS_PROGRESS_TEXT: { + StringID str; + if (this->downloaded_bytes == this->total_bytes) { + str = STR_CONTENT_DOWNLOAD_COMPLETE; + } else if (!this->name.empty()) { + SetDParamStr(0, this->name); + SetDParam(1, this->downloaded_files); + SetDParam(2, this->total_files); + str = STR_CONTENT_DOWNLOAD_FILE; + } else { + str = STR_CONTENT_DOWNLOAD_INITIALISE; + } + DrawStringMultiLine(r, str, TC_FROMSTRING, SA_CENTER); + break; + } + } } void BaseNetworkContentDownloadStatusWindow::OnDownloadProgress(const ContentInfo *ci, int bytes) @@ -152,7 +174,13 @@ void BaseNetworkContentDownloadStatusWindow::OnDownloadProgress(const ContentInf this->downloaded_files++; } - this->downloaded_bytes += bytes; + /* A negative value means we are resetting; for example, when retrying or using a fallback. */ + if (bytes < 0) { + this->downloaded_bytes = 0; + } else { + this->downloaded_bytes += bytes; + } + this->SetDirty(); } @@ -242,7 +270,6 @@ struct NetworkContentDownloadStatusWindow : public BaseNetworkContentDownloadSta case CONTENT_TYPE_SCENARIO: case CONTENT_TYPE_HEIGHTMAP: - extern void ScanScenarios(); ScanScenarios(); InvalidateWindowData(WC_SAVELOAD, 0, 0); break; @@ -323,8 +350,6 @@ class NetworkContentListWindow : public Window, ContentCallback { /** Search external websites for content */ void OpenExternalSearch() { - extern void OpenBrowser(const char *url); - char url[1024]; const char *last = lastof(url); @@ -524,8 +549,6 @@ class NetworkContentListWindow : public Window, ContentCallback { selected(nullptr), list_pos(0) { - this->checkbox_size = maxdim(maxdim(GetSpriteSize(SPR_BOX_EMPTY), GetSpriteSize(SPR_BOX_CHECKED)), GetSpriteSize(SPR_BLOT)); - this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_NCL_SCROLLBAR); this->FinishInitNested(WN_NETWORK_WINDOW_CONTENT_LIST); @@ -556,15 +579,16 @@ class NetworkContentListWindow : public Window, ContentCallback { this->Window::Close(); } + void OnInit() override + { + this->checkbox_size = maxdim(maxdim(GetSpriteSize(SPR_BOX_EMPTY), GetSpriteSize(SPR_BOX_CHECKED)), GetSpriteSize(SPR_BLOT)); + } + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { - case WID_NCL_FILTER_CAPT: - *size = maxdim(*size, GetStringBoundingBox(STR_CONTENT_FILTER_TITLE)); - break; - case WID_NCL_CHECKBOX: - size->width = this->checkbox_size.width + WD_MATRIX_RIGHT + WD_MATRIX_LEFT; + size->width = this->checkbox_size.width + padding.width; break; case WID_NCL_TYPE: { @@ -572,12 +596,12 @@ class NetworkContentListWindow : public Window, ContentCallback { for (int i = CONTENT_TYPE_BEGIN; i < CONTENT_TYPE_END; i++) { d = maxdim(d, GetStringBoundingBox(STR_CONTENT_TYPE_BASE_GRAPHICS + i - CONTENT_TYPE_BASE_GRAPHICS)); } - size->width = d.width + WD_MATRIX_RIGHT + WD_MATRIX_LEFT; + size->width = d.width + padding.width; break; } case WID_NCL_MATRIX: - resize->height = std::max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + resize->height = std::max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL) + padding.height; size->height = 10 * resize->height; break; } @@ -587,10 +611,6 @@ class NetworkContentListWindow : public Window, ContentCallback { void DrawWidget(const Rect &r, int widget) const override { switch (widget) { - case WID_NCL_FILTER_CAPT: - DrawString(r.left, r.right, r.top, STR_CONTENT_FILTER_TITLE, TC_FROMSTRING, SA_RIGHT); - break; - case WID_NCL_DETAILS: this->DrawDetails(r); break; @@ -624,17 +644,15 @@ class NetworkContentListWindow : public Window, ContentCallback { */ void DrawMatrix(const Rect &r) const { - const NWidgetBase *nwi_checkbox = this->GetWidget(WID_NCL_CHECKBOX); - const NWidgetBase *nwi_name = this->GetWidget(WID_NCL_NAME); - const NWidgetBase *nwi_type = this->GetWidget(WID_NCL_TYPE); - - int line_height = std::max(this->checkbox_size.height, (uint)FONT_HEIGHT_NORMAL); + Rect checkbox = this->GetWidget(WID_NCL_CHECKBOX)->GetCurrentRect(); + Rect name = this->GetWidget(WID_NCL_NAME)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); + Rect type = this->GetWidget(WID_NCL_TYPE)->GetCurrentRect(); /* Fill the matrix with the information */ - int sprite_y_offset = WD_MATRIX_TOP + (line_height - this->checkbox_size.height) / 2 - 1; - int text_y_offset = WD_MATRIX_TOP + (line_height - FONT_HEIGHT_NORMAL) / 2; - uint y = r.top; + int sprite_y_offset = (this->resize.step_height - this->checkbox_size.height) / 2; + int text_y_offset = (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2; + Rect mr = r.WithHeight(this->resize.step_height); auto iter = this->content.begin() + this->vscroll->GetPosition(); size_t last = this->vscroll->GetPosition() + this->vscroll->GetCapacity(); auto end = (last < this->content.size()) ? this->content.begin() + last : this->content.end(); @@ -642,7 +660,7 @@ class NetworkContentListWindow : public Window, ContentCallback { for (/**/; iter != end; iter++) { const ContentInfo *ci = *iter; - if (ci == this->selected) GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 1, PC_GREY); + if (ci == this->selected) GfxFillRect(mr.Shrink(WidgetDimensions::scaled.bevel), PC_GREY); SpriteID sprite; SpriteID pal = PAL_NONE; @@ -654,13 +672,13 @@ class NetworkContentListWindow : public Window, ContentCallback { case ContentInfo::DOES_NOT_EXIST: sprite = SPR_BLOT; pal = PALETTE_TO_RED; break; default: NOT_REACHED(); } - DrawSprite(sprite, pal, nwi_checkbox->pos_x + (pal == PAL_NONE ? 2 : 3), y + sprite_y_offset + (pal == PAL_NONE ? 1 : 0)); + DrawSprite(sprite, pal, checkbox.left + (sprite == SPR_BLOT ? 3 : 2), mr.top + sprite_y_offset + (sprite == SPR_BLOT ? 0 : 1)); StringID str = STR_CONTENT_TYPE_BASE_GRAPHICS + ci->type - CONTENT_TYPE_BASE_GRAPHICS; - DrawString(nwi_type->pos_x, nwi_type->pos_x + nwi_type->current_x - 1, y + text_y_offset, str, TC_BLACK, SA_HOR_CENTER); + DrawString(type.left, type.right, mr.top + text_y_offset, str, TC_BLACK, SA_HOR_CENTER); - DrawString(nwi_name->pos_x + WD_FRAMERECT_LEFT, nwi_name->pos_x + nwi_name->current_x - WD_FRAMERECT_RIGHT, y + text_y_offset, ci->name, TC_BLACK); - y += this->resize.step_height; + DrawString(name.left, name.right, mr.top + text_y_offset, ci->name, TC_BLACK); + mr = mr.Translate(0, this->resize.step_height); } } @@ -670,60 +688,59 @@ class NetworkContentListWindow : public Window, ContentCallback { */ void DrawDetails(const Rect &r) const { - static const int DETAIL_LEFT = 5; ///< Number of pixels at the left - static const int DETAIL_RIGHT = 5; ///< Number of pixels at the right - static const int DETAIL_TOP = 5; ///< Number of pixels at the top - /* Height for the title banner */ - int DETAIL_TITLE_HEIGHT = 5 * FONT_HEIGHT_NORMAL; + int HEADER_HEIGHT = 3 * FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.frametext.Vertical(); + + Rect hr = r.WithHeight(HEADER_HEIGHT).Shrink(WidgetDimensions::scaled.frametext); + Rect tr = r.Shrink(WidgetDimensions::scaled.frametext); + tr.top += HEADER_HEIGHT; /* Create the nice grayish rectangle at the details top */ - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + DETAIL_TITLE_HEIGHT, PC_DARK_BLUE); - DrawString(r.left + WD_INSET_LEFT, r.right - WD_INSET_RIGHT, r.top + FONT_HEIGHT_NORMAL + WD_INSET_TOP, STR_CONTENT_DETAIL_TITLE, TC_FROMSTRING, SA_HOR_CENTER); + GfxFillRect(r.WithHeight(HEADER_HEIGHT).Shrink(WidgetDimensions::scaled.bevel.left, WidgetDimensions::scaled.bevel.top, WidgetDimensions::scaled.bevel.right, 0), PC_DARK_BLUE); + DrawString(hr.left, hr.right, hr.top, STR_CONTENT_DETAIL_TITLE, TC_FROMSTRING, SA_HOR_CENTER); /* Draw the total download size */ SetDParam(0, this->filesize_sum); - DrawString(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, r.bottom - FONT_HEIGHT_NORMAL - WD_PAR_VSEP_NORMAL, STR_CONTENT_TOTAL_DOWNLOAD_SIZE); + DrawString(tr.left, tr.right, tr.bottom - FONT_HEIGHT_NORMAL + 1, STR_CONTENT_TOTAL_DOWNLOAD_SIZE); if (this->selected == nullptr) return; /* And fill the rest of the details when there's information to place there */ - DrawStringMultiLine(r.left + WD_INSET_LEFT, r.right - WD_INSET_RIGHT, r.top + DETAIL_TITLE_HEIGHT / 2, r.top + DETAIL_TITLE_HEIGHT, STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED + this->selected->state, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(hr.left, hr.right, hr.top + FONT_HEIGHT_NORMAL, hr.bottom, STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED + this->selected->state, TC_FROMSTRING, SA_CENTER); /* Also show the total download size, so keep some space from the bottom */ - const uint max_y = r.bottom - FONT_HEIGHT_NORMAL - WD_PAR_VSEP_WIDE; - int y = r.top + DETAIL_TITLE_HEIGHT + DETAIL_TOP; + tr.bottom -= FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide; if (this->selected->upgrade) { SetDParam(0, STR_CONTENT_TYPE_BASE_GRAPHICS + this->selected->type - CONTENT_TYPE_BASE_GRAPHICS); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_UPDATE); - y += WD_PAR_VSEP_WIDE; + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_UPDATE); + tr.top += WidgetDimensions::scaled.vsep_wide; } SetDParamStr(0, this->selected->name); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_NAME); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_NAME); if (!this->selected->version.empty()) { SetDParamStr(0, this->selected->version); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_VERSION); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_VERSION); } if (!this->selected->description.empty()) { SetDParamStr(0, this->selected->description); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_DESCRIPTION); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_DESCRIPTION); } if (!this->selected->url.empty()) { SetDParamStr(0, this->selected->url); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_URL); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_URL); } SetDParam(0, STR_CONTENT_TYPE_BASE_GRAPHICS + this->selected->type - CONTENT_TYPE_BASE_GRAPHICS); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_TYPE); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_TYPE); - y += WD_PAR_VSEP_WIDE; + tr.top += WidgetDimensions::scaled.vsep_wide; SetDParam(0, this->selected->filesize); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_FILESIZE); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_FILESIZE); if (!this->selected->dependencies.empty()) { /* List dependencies */ @@ -741,7 +758,7 @@ class NetworkContentListWindow : public Window, ContentCallback { } } SetDParamStr(0, buf); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_DEPENDENCIES); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_DEPENDENCIES); } if (!this->selected->tags.empty()) { @@ -752,7 +769,7 @@ class NetworkContentListWindow : public Window, ContentCallback { p += seprintf(p, lastof(buf), p == buf ? "%s" : ", %s", tag.c_str()); } SetDParamStr(0, buf); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_TAGS); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_TAGS); } if (this->selected->IsSelected()) { @@ -769,7 +786,7 @@ class NetworkContentListWindow : public Window, ContentCallback { } if (p != buf) { SetDParamStr(0, buf); - y = DrawStringMultiLine(r.left + DETAIL_LEFT, r.right - DETAIL_RIGHT, y, max_y, STR_CONTENT_DETAIL_SELECTED_BECAUSE_OF); + tr.top = DrawStringMultiLine(tr, STR_CONTENT_DETAIL_SELECTED_BECAUSE_OF); } } } @@ -841,7 +858,6 @@ class NetworkContentListWindow : public Window, ContentCallback { case WID_NCL_OPEN_URL: if (this->selected != nullptr) { - extern void OpenBrowser(const char *url); OpenBrowser(this->selected->url.c_str()); } break; @@ -1029,7 +1045,7 @@ static const NWidgetPart _nested_network_content_list_widgets[] = { NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetResize(1, 0), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(8, 8, 8), /* Top */ - NWidget(WWT_EMPTY, COLOUR_LIGHT_BLUE, WID_NCL_FILTER_CAPT), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_TEXT, COLOUR_LIGHT_BLUE, WID_NCL_FILTER_CAPT), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_CONTENT_FILTER_TITLE, STR_NULL), SetAlignment(SA_RIGHT), NWidget(WWT_EDITBOX, COLOUR_LIGHT_BLUE, WID_NCL_FILTER), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), EndContainer(), diff --git a/src/network/network_content_gui.h b/src/network/network_content_gui.h index 54fbcc36b35e3..570f15462fda2 100644 --- a/src/network/network_content_gui.h +++ b/src/network/network_content_gui.h @@ -33,6 +33,7 @@ class BaseNetworkContentDownloadStatusWindow : public Window, ContentCallback { BaseNetworkContentDownloadStatusWindow(WindowDesc *desc); void Close() override; + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override; void DrawWidget(const Rect &r, int widget) const override; void OnDownloadProgress(const ContentInfo *ci, int bytes) override; }; diff --git a/src/network/network_func.h b/src/network/network_func.h index 3ac4ae05f5805..63d3d0cdc0b2a 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -59,6 +59,7 @@ void NetworkClientSendRcon(const std::string &password, const std::string &comma void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, int64 data = 0); bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio); bool NetworkCompanyIsPassworded(CompanyID company_id); +uint NetworkMaxCompaniesAllowed(); bool NetworkMaxCompaniesReached(); void NetworkPrintClients(); void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode); @@ -85,6 +86,7 @@ uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const std::string &r uint NetworkServerKickOrBanIP(const std::string &ip, bool ban, const std::string &reason); void NetworkInitChatMessage(); +void NetworkReInitChatBoxSize(); void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const std::string &message); void NetworkUndrawChatMessage(); void NetworkChatMessageLoop(); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 1e8b2f4b9cd1f..40f1bb64e6a38 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -103,8 +103,7 @@ class NWidgetServerListHeader : public NWidgetContainer { leaf = new NWidgetLeaf(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_INFO, STR_EMPTY, STR_NETWORK_SERVER_LIST_INFO_ICONS_TOOLTIP); leaf->SetMinimalSize(14 + GetSpriteSize(SPR_LOCK, nullptr, ZOOM_LVL_OUT_4X).width - + GetSpriteSize(SPR_BLOT, nullptr, ZOOM_LVL_OUT_4X).width - + GetSpriteSize(SPR_FLAGS_BASE, nullptr, ZOOM_LVL_OUT_4X).width, 12); + + GetSpriteSize(SPR_BLOT, nullptr, ZOOM_LVL_OUT_4X).width, 12); leaf->SetFill(0, 1); this->Add(leaf); @@ -127,7 +126,7 @@ class NWidgetServerListHeader : public NWidgetContainer { /* First initialise some variables... */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical()); } /* ... then in a second pass make sure the 'current' sizes are set. Won't change for most widgets. */ @@ -392,66 +391,70 @@ class NetworkGameWindow : public Window { * @param y from where to draw? * @param highlight does the line need to be highlighted? */ - void DrawServerLine(const NetworkGameList *cur_item, uint y, bool highlight) const + void DrawServerLine(const NetworkGameList *cur_item, int y, bool highlight) const { - const NWidgetBase *nwi_name = this->GetWidget(WID_NG_NAME); - const NWidgetBase *nwi_info = this->GetWidget(WID_NG_INFO); + Rect name = this->GetWidget(WID_NG_NAME)->GetCurrentRect(); + Rect info = this->GetWidget(WID_NG_INFO)->GetCurrentRect(); /* show highlighted item with a different colour */ - if (highlight) GfxFillRect(nwi_name->pos_x + 1, y + 1, nwi_info->pos_x + nwi_info->current_x - 2, y + this->resize.step_height - 2, PC_GREY); + if (highlight) { + Rect r = {std::min(name.left, info.left), y, std::max(name.right, info.right), y + (int)this->resize.step_height - 1}; + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), PC_GREY); + } /* offsets to vertically centre text and icons */ int text_y_offset = (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2 + 1; int icon_y_offset = (this->resize.step_height - GetSpriteSize(SPR_BLOT).height) / 2; int lock_y_offset = (this->resize.step_height - GetSpriteSize(SPR_LOCK).height) / 2; - DrawString(nwi_name->pos_x + WD_FRAMERECT_LEFT, nwi_name->pos_x + nwi_name->current_x - WD_FRAMERECT_RIGHT, y + text_y_offset, cur_item->info.server_name, TC_BLACK); + name = name.Shrink(WidgetDimensions::scaled.framerect); + DrawString(name.left, name.right, y + text_y_offset, cur_item->info.server_name, TC_BLACK); /* only draw details if the server is online */ if (cur_item->status == NGLS_ONLINE) { const NWidgetServerListHeader *nwi_header = this->GetWidget(WID_NG_HEADER); if (nwi_header->IsWidgetVisible(WID_NG_CLIENTS)) { - const NWidgetBase *nwi_clients = this->GetWidget(WID_NG_CLIENTS); + Rect clients = this->GetWidget(WID_NG_CLIENTS)->GetCurrentRect(); SetDParam(0, cur_item->info.clients_on); SetDParam(1, cur_item->info.clients_max); SetDParam(2, cur_item->info.companies_on); SetDParam(3, cur_item->info.companies_max); - DrawString(nwi_clients->pos_x, nwi_clients->pos_x + nwi_clients->current_x - 1, y + text_y_offset, STR_NETWORK_SERVER_LIST_GENERAL_ONLINE, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(clients.left, clients.right, y + text_y_offset, STR_NETWORK_SERVER_LIST_GENERAL_ONLINE, TC_FROMSTRING, SA_HOR_CENTER); } if (nwi_header->IsWidgetVisible(WID_NG_MAPSIZE)) { /* map size */ - const NWidgetBase *nwi_mapsize = this->GetWidget(WID_NG_MAPSIZE); + Rect mapsize = this->GetWidget(WID_NG_MAPSIZE)->GetCurrentRect(); SetDParam(0, cur_item->info.map_width); SetDParam(1, cur_item->info.map_height); - DrawString(nwi_mapsize->pos_x, nwi_mapsize->pos_x + nwi_mapsize->current_x - 1, y + text_y_offset, STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(mapsize.left, mapsize.right, y + text_y_offset, STR_NETWORK_SERVER_LIST_MAP_SIZE_SHORT, TC_FROMSTRING, SA_HOR_CENTER); } if (nwi_header->IsWidgetVisible(WID_NG_DATE)) { /* current date */ - const NWidgetBase *nwi_date = this->GetWidget(WID_NG_DATE); + Rect date = this->GetWidget(WID_NG_DATE)->GetCurrentRect(); YearMonthDay ymd; ConvertDateToYMD(cur_item->info.game_date, &ymd); SetDParam(0, ymd.year); - DrawString(nwi_date->pos_x, nwi_date->pos_x + nwi_date->current_x - 1, y + text_y_offset, STR_JUST_INT, TC_BLACK, SA_HOR_CENTER); + DrawString(date.left, date.right, y + text_y_offset, STR_JUST_INT, TC_BLACK, SA_HOR_CENTER); } if (nwi_header->IsWidgetVisible(WID_NG_YEARS)) { /* number of years the game is running */ - const NWidgetBase *nwi_years = this->GetWidget(WID_NG_YEARS); + Rect years = this->GetWidget(WID_NG_YEARS)->GetCurrentRect(); YearMonthDay ymd_cur, ymd_start; ConvertDateToYMD(cur_item->info.game_date, &ymd_cur); ConvertDateToYMD(cur_item->info.start_date, &ymd_start); SetDParam(0, ymd_cur.year - ymd_start.year); - DrawString(nwi_years->pos_x, nwi_years->pos_x + nwi_years->current_x - 1, y + text_y_offset, STR_JUST_INT, TC_BLACK, SA_HOR_CENTER); + DrawString(years.left, years.right, y + text_y_offset, STR_JUST_INT, TC_BLACK, SA_HOR_CENTER); } /* draw a lock if the server is password protected */ - if (cur_item->info.use_password) DrawSprite(SPR_LOCK, PAL_NONE, nwi_info->pos_x + this->lock_offset, y + lock_y_offset); + if (cur_item->info.use_password) DrawSprite(SPR_LOCK, PAL_NONE, info.left + this->lock_offset, y + lock_y_offset); /* draw red or green icon, depending on compatibility with server */ - DrawSprite(SPR_BLOT, (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), nwi_info->pos_x + this->blot_offset, y + icon_y_offset + 1); + DrawSprite(SPR_BLOT, (cur_item->info.compatible ? PALETTE_TO_GREEN : (cur_item->info.version_compatible ? PALETTE_TO_YELLOW : PALETTE_TO_RED)), info.left + this->blot_offset, y + icon_y_offset + 1); } } @@ -474,10 +477,6 @@ class NetworkGameWindow : public Window { this->list_pos = SLP_INVALID; this->server = nullptr; - this->lock_offset = 5; - this->blot_offset = this->lock_offset + 3 + GetSpriteSize(SPR_LOCK).width; - this->flag_offset = this->blot_offset + 2 + GetSpriteSize(SPR_BLOT).width; - this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_NG_SCROLLBAR); this->FinishInitNested(WN_NETWORK_WINDOW_GAME); @@ -513,17 +512,24 @@ class NetworkGameWindow : public Window { this->last_sorting = this->servers.GetListing(); } + void OnInit() override + { + this->lock_offset = ScaleGUITrad(5); + this->blot_offset = this->lock_offset + ScaleGUITrad(3) + GetSpriteSize(SPR_LOCK).width; + this->flag_offset = this->blot_offset + ScaleGUITrad(2) + GetSpriteSize(SPR_BLOT).width; + } + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_NG_MATRIX: - resize->height = WD_MATRIX_TOP + std::max(GetSpriteSize(SPR_BLOT).height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_BOTTOM; + resize->height = std::max(GetSpriteSize(SPR_BLOT).height, (uint)FONT_HEIGHT_NORMAL) + padding.height; fill->height = resize->height; size->height = 12 * resize->height; break; case WID_NG_LASTJOINED: - size->height = WD_MATRIX_TOP + std::max(GetSpriteSize(SPR_BLOT).height, (uint)FONT_HEIGHT_NORMAL) + WD_MATRIX_BOTTOM; + size->height = std::max(GetSpriteSize(SPR_BLOT).height, (uint)FONT_HEIGHT_NORMAL) + WidgetDimensions::scaled.matrix.Vertical(); break; case WID_NG_LASTJOINED_SPACER: @@ -634,15 +640,19 @@ class NetworkGameWindow : public Window { { NetworkGameList *sel = this->server; - const int detail_height = 6 + 8 + 6 + 3 * FONT_HEIGHT_NORMAL; + /* Height for the title banner */ + int HEADER_HEIGHT = 3 * FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.frametext.Vertical(); + + Rect hr = r.WithHeight(HEADER_HEIGHT).Shrink(WidgetDimensions::scaled.frametext); + Rect tr = r.Shrink(WidgetDimensions::scaled.frametext); + tr.top += HEADER_HEIGHT; /* Draw the right menu */ - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + detail_height - 1, PC_DARK_BLUE); + /* Create the nice grayish rectangle at the details top */ + GfxFillRect(r.WithHeight(HEADER_HEIGHT).Shrink(WidgetDimensions::scaled.bevel.left, WidgetDimensions::scaled.bevel.top, WidgetDimensions::scaled.bevel.right, 0), PC_DARK_BLUE); if (sel == nullptr) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(hr.left, hr.right, hr.top, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER); } else if (sel->status != NGLS_ONLINE) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name - StringID message = INVALID_STRING_ID; switch (sel->status) { case NGLS_OFFLINE: message = STR_NETWORK_SERVER_LIST_SERVER_OFFLINE; break; @@ -653,63 +663,63 @@ class NetworkGameWindow : public Window { /* Handled by the if-case above. */ case NGLS_ONLINE: NOT_REACHED(); } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + detail_height + 4, message, TC_FROMSTRING, SA_HOR_CENTER); // server offline - } else { // show game info - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name + DrawString(hr.left, hr.right, hr.top, message, TC_FROMSTRING, SA_HOR_CENTER); // server offline + DrawStringMultiLine(hr.left, hr.right, hr.top + FONT_HEIGHT_NORMAL, hr.bottom, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name + DrawString(tr.left, tr.right, tr.top, message, TC_FROMSTRING, SA_HOR_CENTER); // server offline + } else { // show game info - uint16 y = r.top + detail_height + 4; + DrawString(hr.left, hr.right, hr.top, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER); + DrawStringMultiLine(hr.left, hr.right, hr.top + FONT_HEIGHT_NORMAL, hr.bottom, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name SetDParam(0, sel->info.clients_on); SetDParam(1, sel->info.clients_max); SetDParam(2, sel->info.companies_on); SetDParam(3, sel->info.companies_max); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CLIENTS); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_NETWORK_SERVER_LIST_CLIENTS); + tr.top += FONT_HEIGHT_NORMAL; - SetDParam(0, STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE + sel->info.landscape); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_LANDSCAPE); // landscape - y += FONT_HEIGHT_NORMAL; + SetDParam(0, STR_CLIMATE_TEMPERATE_LANDSCAPE + sel->info.landscape); + DrawString(tr, STR_NETWORK_SERVER_LIST_LANDSCAPE); // landscape + tr.top += FONT_HEIGHT_NORMAL; SetDParam(0, sel->info.map_width); SetDParam(1, sel->info.map_height); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_MAP_SIZE); // map size - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_NETWORK_SERVER_LIST_MAP_SIZE); // map size + tr.top += FONT_HEIGHT_NORMAL; SetDParamStr(0, sel->info.server_revision); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version + tr.top += FONT_HEIGHT_NORMAL; SetDParamStr(0, sel->connection_string); StringID invite_or_address = StrStartsWith(sel->connection_string, "+") ? STR_NETWORK_SERVER_LIST_INVITE_CODE : STR_NETWORK_SERVER_LIST_SERVER_ADDRESS; - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, invite_or_address); // server address / invite code - y += FONT_HEIGHT_NORMAL; + DrawString(tr, invite_or_address); // server address / invite code + tr.top += FONT_HEIGHT_NORMAL; SetDParam(0, sel->info.start_date); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_START_DATE); // start date - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_NETWORK_SERVER_LIST_START_DATE); // start date + tr.top += FONT_HEIGHT_NORMAL; SetDParam(0, sel->info.game_date); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CURRENT_DATE); // current date - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_NETWORK_SERVER_LIST_CURRENT_DATE); // current date + tr.top += FONT_HEIGHT_NORMAL; if (sel->info.gamescript_version != -1) { SetDParamStr(0, sel->info.gamescript_name); SetDParam(1, sel->info.gamescript_version); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_GAMESCRIPT); // gamescript name and version - y += FONT_HEIGHT_NORMAL; + tr.top = DrawStringMultiLine(tr, STR_NETWORK_SERVER_LIST_GAMESCRIPT); // gamescript name and version } - y += WD_PAR_VSEP_NORMAL; + tr.top += WidgetDimensions::scaled.vsep_wide; if (!sel->info.compatible) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, sel->info.version_compatible ? STR_NETWORK_SERVER_LIST_GRF_MISMATCH : STR_NETWORK_SERVER_LIST_VERSION_MISMATCH, TC_FROMSTRING, SA_HOR_CENTER); // server mismatch + DrawString(tr, sel->info.version_compatible ? STR_NETWORK_SERVER_LIST_GRF_MISMATCH : STR_NETWORK_SERVER_LIST_VERSION_MISMATCH, TC_FROMSTRING, SA_HOR_CENTER); // server mismatch } else if (sel->info.clients_on == sel->info.clients_max) { /* Show: server full, when clients_on == max_clients */ - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_FULL, TC_FROMSTRING, SA_HOR_CENTER); // server full + DrawString(tr, STR_NETWORK_SERVER_LIST_SERVER_FULL, TC_FROMSTRING, SA_HOR_CENTER); // server full } else if (sel->info.use_password) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_PASSWORD, TC_FROMSTRING, SA_HOR_CENTER); // password warning + DrawString(tr, STR_NETWORK_SERVER_LIST_PASSWORD, TC_FROMSTRING, SA_HOR_CENTER); // password warning } } } @@ -956,7 +966,7 @@ static const NWidgetPart _nested_network_game_widgets[] = { EndContainer(), NWidget(WWT_PANEL, COLOUR_LIGHT_BLUE, WID_NG_DETAILS), NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(5, 5, 5), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NG_DETAILS_SPACER), SetMinimalSize(140, 0), SetMinimalTextLines(15, 24 + WD_PAR_VSEP_NORMAL), SetResize(0, 1), SetFill(1, 1), // Make sure it's at least this wide + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NG_DETAILS_SPACER), SetMinimalSize(140, 0), SetMinimalTextLines(15, 24 + WidgetDimensions::unscaled.vsep_normal), SetResize(0, 1), SetFill(1, 1), // Make sure it's at least this wide NWidget(NWID_HORIZONTAL, NC_NONE), SetPIP(5, 5, 5), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NG_NEWGRF_MISSING_SEL), NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NG_NEWGRF_MISSING), SetFill(1, 0), SetDataTip(STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_BUTTON, STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_TOOLTIP), @@ -1070,7 +1080,7 @@ struct NetworkStartServerWindow : public Window { switch (widget) { case WID_NSS_SETPWD: /* If password is set, draw red '*' next to 'Set password' button. */ - if (!_settings_client.network.server_password.empty()) 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 + WidgetDimensions::scaled.framerect.left, this->width - WidgetDimensions::scaled.framerect.right, r.top, "*", TC_RED); } } @@ -1336,16 +1346,18 @@ static const NWidgetPart _nested_client_list_widgets[] = { NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_CL_CLIENT_NAME_EDIT), SetMinimalSize(12, 14), SetDataTip(SPR_RENAME, STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP), EndContainer(), EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(NWID_VERTICAL), - NWidget(WWT_MATRIX, COLOUR_GREY, WID_CL_MATRIX), SetMinimalSize(180, 0), SetResize(1, 1), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_CL_SCROLLBAR), - NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_CLIENT_COMPANY_COUNT), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetPadding(2, 1, 2, 1), SetAlignment(SA_CENTER), SetDataTip(STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT, STR_NULL), - EndContainer(), - NWidget(NWID_VERTICAL), - NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_CL_SCROLLBAR), - NWidget(WWT_RESIZEBOX, COLOUR_GREY), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_VERTICAL), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_CL_MATRIX), SetMinimalSize(180, 0), SetResize(1, 1), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_CL_SCROLLBAR), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(WWT_TEXT, COLOUR_GREY, WID_CL_CLIENT_COMPANY_COUNT), SetFill(1, 0), SetMinimalTextLines(1, 0), SetResize(1, 0), SetPadding(2, 1, 2, 1), SetAlignment(SA_CENTER), SetDataTip(STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT, STR_NETWORK_CLIENT_LIST_CLIENT_COMPANY_COUNT_TOOLTIP), EndContainer(), EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_CL_SCROLLBAR), + NWidget(WWT_RESIZEBOX, COLOUR_GREY), + EndContainer(), EndContainer(), }; @@ -1433,8 +1445,8 @@ class ButtonCommon { disabled(disabled) { Dimension d = GetSpriteSize(sprite); - this->height = d.height + ScaleGUITrad(WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); - this->width = d.width + ScaleGUITrad(WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT); + this->height = d.height + WidgetDimensions::scaled.framerect.Vertical(); + this->width = d.width + WidgetDimensions::scaled.framerect.Horizontal(); } virtual ~ButtonCommon() {} @@ -1494,8 +1506,6 @@ struct NetworkClientListWindow : Window { std::map>> buttons; ///< Per line which buttons are available. - static const int CLIENT_OFFSET_LEFT = 12; ///< Offset of client entries compared to company entries. - /** * Chat button on a Company is clicked. * @param w The instance of this window. @@ -1676,10 +1686,10 @@ struct NetworkClientListWindow : Window { ButtonCommon *GetButtonAtPoint(Point pt) { uint index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_CL_MATRIX); - NWidgetBase *widget_matrix = this->GetWidget(WID_CL_MATRIX); + Rect matrix = this->GetWidget(WID_CL_MATRIX)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); bool rtl = _current_text_dir == TD_RTL; - uint x = rtl ? (uint)widget_matrix->pos_x + WD_FRAMERECT_LEFT : widget_matrix->current_x - WD_FRAMERECT_RIGHT; + uint x = rtl ? matrix.left : matrix.right; /* Find the buttons for this row. */ auto button_find = this->buttons.find(index); @@ -1694,7 +1704,7 @@ struct NetworkClientListWindow : Window { return button.get(); } - int width = button->width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + int width = button->width + WidgetDimensions::scaled.framerect.Horizontal(); x += rtl ? width : -width; } @@ -1714,6 +1724,11 @@ struct NetworkClientListWindow : Window { this->FinishInitNested(window_number); } + void OnInit() override + { + RebuildList(); + } + void OnInvalidateData(int data = 0, bool gui_scope = true) override { this->RebuildList(); @@ -1734,8 +1749,8 @@ struct NetworkClientListWindow : Window { case WID_CL_MATRIX: { uint height = std::max({GetSpriteSize(SPR_COMPANY_ICON).height, GetSpriteSize(SPR_JOIN).height, GetSpriteSize(SPR_ADMIN).height, GetSpriteSize(SPR_CHAT).height}); - height += ScaleGUITrad(WD_FRAMERECT_TOP) + ScaleGUITrad(WD_FRAMERECT_BOTTOM); - this->line_height = std::max(height, (uint)FONT_HEIGHT_NORMAL) + ScaleGUITrad(WD_MATRIX_TOP + WD_MATRIX_BOTTOM); + height += WidgetDimensions::scaled.framerect.Vertical(); + this->line_height = std::max(height, (uint)FONT_HEIGHT_NORMAL) + padding.height; resize->width = 1; resize->height = this->line_height; @@ -1772,13 +1787,16 @@ struct NetworkClientListWindow : Window { SetDParam(0, STR_NETWORK_CLIENT_LIST_SERVER_CONNECTION_TYPE_UNKNOWN + _network_server_connection_type); break; - case WID_CL_CLIENT_NAME: - SetDParamStr(0, _settings_client.network.client_name); + case WID_CL_CLIENT_NAME: { + const NetworkClientInfo *own_ci = NetworkClientInfo::GetByClientID(_network_own_client_id); + SetDParamStr(0, own_ci != nullptr ? own_ci->client_name : _settings_client.network.client_name); break; + } case WID_CL_CLIENT_COMPANY_COUNT: SetDParam(0, NetworkClientInfo::GetNumItems()); SetDParam(1, Company::GetNumItems()); + SetDParam(2, NetworkMaxCompaniesAllowed()); break; } } @@ -1794,12 +1812,13 @@ struct NetworkClientListWindow : Window { ShowQueryString(STR_JUST_RAW_STRING, STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION, NETWORK_NAME_LENGTH, this, CS_ALPHANUMERAL, QSF_LEN_IN_CHARS); break; - case WID_CL_CLIENT_NAME_EDIT: + case WID_CL_CLIENT_NAME_EDIT: { + const NetworkClientInfo *own_ci = NetworkClientInfo::GetByClientID(_network_own_client_id); this->query_widget = WID_CL_CLIENT_NAME_EDIT; - SetDParamStr(0, _settings_client.network.client_name); + SetDParamStr(0, own_ci != nullptr ? own_ci->client_name : _settings_client.network.client_name); ShowQueryString(STR_JUST_RAW_STRING, STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION, NETWORK_CLIENT_NAME_LENGTH, this, CS_ALPHANUMERAL, QSF_LEN_IN_CHARS); break; - + } case WID_CL_SERVER_VISIBILITY: if (!_network_server) break; @@ -1823,14 +1842,14 @@ struct NetworkClientListWindow : Window { int index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_CL_MATRIX); bool rtl = _current_text_dir == TD_RTL; - NWidgetBase *widget_matrix = this->GetWidget(WID_CL_MATRIX); + Rect matrix = this->GetWidget(WID_CL_MATRIX)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); Dimension d = GetSpriteSize(SPR_COMPANY_ICON); - uint text_left = widget_matrix->pos_x + (rtl ? (uint)WD_FRAMERECT_LEFT : d.width + 8); - uint text_right = widget_matrix->pos_x + widget_matrix->current_x - (rtl ? d.width + 8 : (uint)WD_FRAMERECT_RIGHT); + uint text_left = matrix.left + (rtl ? 0 : d.width + WidgetDimensions::scaled.hsep_wide); + uint text_right = matrix.right - (rtl ? d.width + WidgetDimensions::scaled.hsep_wide : 0); Dimension d2 = GetSpriteSize(SPR_PLAYER_SELF); - uint offset_x = CLIENT_OFFSET_LEFT - d2.width - 3; + uint offset_x = WidgetDimensions::scaled.hsep_indent - d2.width - ScaleGUITrad(3); uint player_icon_x = rtl ? text_right - offset_x - d2.width : text_left + offset_x; @@ -1963,23 +1982,26 @@ struct NetworkClientListWindow : Window { * @param y The y-position to start with the buttons. * @param buttons The buttons to draw. */ - void DrawButtons(uint &x, uint y, const std::vector> &buttons) const + void DrawButtons(int &x, uint y, const std::vector> &buttons) const { + Rect r; + for (auto &button : buttons) { bool rtl = _current_text_dir == TD_RTL; - uint left = rtl ? x : x - button->width; - uint right = rtl ? x + button->width : x; - - int offset = std::max(0, ((int)(this->line_height + 1) - (int)button->height) / 2); + int offset = (this->line_height - button->height) / 2; + r.left = rtl ? x : x - button->width + 1; + r.right = rtl ? x + button->width - 1 : x; + r.top = y + offset; + r.bottom = r.top + button->height - 1; - DrawFrameRect(left, y + offset, right, y + offset + button->height, button->colour, FR_NONE); - DrawSprite(button->sprite, PAL_NONE, left + ScaleGUITrad(WD_FRAMERECT_LEFT), y + offset + ScaleGUITrad(WD_FRAMERECT_TOP)); + DrawFrameRect(r, button->colour, FR_NONE); + DrawSprite(button->sprite, PAL_NONE, r.left + WidgetDimensions::scaled.framerect.left, r.top + WidgetDimensions::scaled.framerect.top); if (button->disabled) { - GfxFillRect(left + 1, y + offset + 1, right - 1, y + offset + button->height - 1, _colour_gradient[button->colour & 0xF][2], FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[button->colour & 0xF][2], FILLRECT_CHECKER); } - int width = button->width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + int width = button->width + WidgetDimensions::scaled.hsep_normal; x += rtl ? width : -width; } } @@ -1987,30 +2009,27 @@ struct NetworkClientListWindow : Window { /** * Draw a company and its clients on the matrix. * @param company_id The company to draw. - * @param left The most left pixel of the line. - * @param right The most right pixel of the line. - * @param top The top of the first line. + * @param r The rect to draw within. * @param line The Nth line we are drawing. Updated during this function. */ - void DrawCompany(CompanyID company_id, uint left, uint right, uint top, uint &line) const + void DrawCompany(CompanyID company_id, const Rect &r, uint &line) const { bool rtl = _current_text_dir == TD_RTL; - int text_y_offset = std::max(0, ((int)(this->line_height + 1) - (int)FONT_HEIGHT_NORMAL) / 2) + WD_MATRIX_BOTTOM; + int text_y_offset = CenterBounds(0, this->line_height, FONT_HEIGHT_NORMAL); Dimension d = GetSpriteSize(SPR_COMPANY_ICON); - int offset = std::max(0, ((int)(this->line_height + 1) - (int)d.height) / 2); - - uint text_left = left + (rtl ? (uint)WD_FRAMERECT_LEFT : d.width + 8); - uint text_right = right - (rtl ? d.width + 8 : (uint)WD_FRAMERECT_RIGHT); + int offset = CenterBounds(0, this->line_height, d.height); uint line_start = this->vscroll->GetPosition(); uint line_end = line_start + this->vscroll->GetCapacity(); - uint y = top + (this->line_height * (line - line_start)); + uint y = r.top + (this->line_height * (line - line_start)); /* Draw the company line (if in range of scrollbar). */ if (IsInsideMM(line, line_start, line_end)) { - uint x = rtl ? text_left : text_right; + int icon_left = r.WithWidth(d.width, rtl).left; + Rect tr = r.Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl); + int &x = rtl ? tr.left : tr.right; /* If there are buttons for this company, draw them. */ auto button_find = this->buttons.find(line); @@ -2019,17 +2038,17 @@ struct NetworkClientListWindow : Window { } if (company_id == COMPANY_SPECTATOR) { - DrawSprite(SPR_COMPANY_ICON, PALETTE_TO_GREY, rtl ? right - d.width - 4 : left + 4, y + offset); - DrawString(rtl ? x : text_left, rtl ? text_right : x, y + text_y_offset, STR_NETWORK_CLIENT_LIST_SPECTATORS, TC_SILVER); + DrawSprite(SPR_COMPANY_ICON, PALETTE_TO_GREY, icon_left, y + offset); + DrawString(tr.left, tr.right, y + text_y_offset, STR_NETWORK_CLIENT_LIST_SPECTATORS, TC_SILVER); } else if (company_id == COMPANY_NEW_COMPANY) { - DrawSprite(SPR_COMPANY_ICON, PALETTE_TO_GREY, rtl ? right - d.width - 4 : left + 4, y + offset); - DrawString(rtl ? x : text_left, rtl ? text_right : x, y + text_y_offset, STR_NETWORK_CLIENT_LIST_NEW_COMPANY, TC_WHITE); + DrawSprite(SPR_COMPANY_ICON, PALETTE_TO_GREY, icon_left, y + offset); + DrawString(tr.left, tr.right, y + text_y_offset, STR_NETWORK_CLIENT_LIST_NEW_COMPANY, TC_WHITE); } else { - DrawCompanyIcon(company_id, rtl ? right - d.width - 4 : left + 4, y + offset); + DrawCompanyIcon(company_id, icon_left, y + offset); SetDParam(0, company_id); SetDParam(1, company_id); - DrawString(rtl ? x : text_left, rtl ? text_right : x, y + text_y_offset, STR_COMPANY_NAME, TC_SILVER); + DrawString(tr.left, tr.right, y + text_y_offset, STR_COMPANY_NAME, TC_SILVER); } } @@ -2041,11 +2060,12 @@ struct NetworkClientListWindow : Window { /* Draw the player line (if in range of scrollbar). */ if (IsInsideMM(line, line_start, line_end)) { - uint x = rtl ? text_left : text_right; + Rect tr = r.Indent(WidgetDimensions::scaled.hsep_indent, rtl); /* If there are buttons for this client, draw them. */ auto button_find = this->buttons.find(line); if (button_find != this->buttons.end()) { + int &x = rtl ? tr.left : tr.right; this->DrawButtons(x, y, button_find->second); } @@ -2058,13 +2078,13 @@ struct NetworkClientListWindow : Window { if (player_icon != 0) { Dimension d2 = GetSpriteSize(player_icon); - uint offset_x = CLIENT_OFFSET_LEFT - 3; - int offset_y = std::max(0, ((int)(this->line_height + 1) - (int)d2.height) / 2); - DrawSprite(player_icon, PALETTE_TO_GREY, rtl ? text_right - offset_x : text_left + offset_x - d2.width, y + offset_y); + int offset_y = CenterBounds(0, this->line_height, d2.height); + DrawSprite(player_icon, PALETTE_TO_GREY, rtl ? tr.right - d2.width : tr.left, y + offset_y); + tr = tr.Indent(d2.width + WidgetDimensions::scaled.hsep_normal, rtl); } SetDParamStr(0, ci->client_name); - DrawString(rtl ? x : text_left + CLIENT_OFFSET_LEFT, rtl ? text_right - CLIENT_OFFSET_LEFT : x, y + text_y_offset, STR_JUST_RAW_STRING, TC_BLACK); + DrawString(tr.left, tr.right, y + text_y_offset, STR_JUST_RAW_STRING, TC_BLACK); } y += this->line_height; @@ -2076,52 +2096,51 @@ struct NetworkClientListWindow : Window { { switch (widget) { case WID_CL_MATRIX: { + Rect ir = r.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero); uint line = 0; if (this->hover_index >= 0) { - uint offset = this->hover_index * this->line_height; - GfxFillRect(r.left + 2, r.top + offset, r.right - 1, r.top + offset + this->line_height - 2, GREY_SCALE(9)); + Rect br = r.WithHeight(this->line_height).Translate(0, this->hover_index * this->line_height); + GfxFillRect(br.Shrink(WidgetDimensions::scaled.bevel), GREY_SCALE(9)); } NetworkClientInfo *own_ci = NetworkClientInfo::GetByClientID(_network_own_client_id); CompanyID client_playas = own_ci == nullptr ? COMPANY_SPECTATOR : own_ci->client_playas; if (client_playas == COMPANY_SPECTATOR && !NetworkMaxCompaniesReached()) { - this->DrawCompany(COMPANY_NEW_COMPANY, r.left, r.right, r.top, line); + this->DrawCompany(COMPANY_NEW_COMPANY, ir, line); } if (client_playas != COMPANY_SPECTATOR) { - this->DrawCompany(client_playas, r.left, r.right, r.top, line); + this->DrawCompany(client_playas, ir, line); } for (const Company *c : Company::Iterate()) { if (client_playas == c->index) continue; - this->DrawCompany(c->index, r.left, r.right, r.top, line); + this->DrawCompany(c->index, ir, line); } /* Spectators */ - this->DrawCompany(COMPANY_SPECTATOR, r.left, r.right, r.top, line); + this->DrawCompany(COMPANY_SPECTATOR, ir, line); break; } } } - virtual void OnMouseLoop() override + void OnMouseOver(Point pt, int widget) override { - if (GetWidgetFromPos(this, _cursor.pos.x - this->left, _cursor.pos.y - this->top) != WID_CL_MATRIX) { - this->hover_index = -1; - this->SetDirty(); - return; - } - - NWidgetBase *nwi = this->GetWidget(WID_CL_MATRIX); - int y = _cursor.pos.y - this->top - nwi->pos_y - 2; - int index = y / this->line_height; - - if (index != this->hover_index) { - this->hover_index = index; - this->SetDirty(); + if (widget != WID_CL_MATRIX) { + if (this->hover_index != -1) { + this->hover_index = -1; + this->SetWidgetDirty(WID_CL_MATRIX); + } + } else { + int index = this->GetRowFromWidget(pt.y, widget, 0, -1); + if (index != this->hover_index) { + this->hover_index = index; + this->SetWidgetDirty(WID_CL_MATRIX); + } } } }; @@ -2147,62 +2166,79 @@ struct NetworkJoinStatusWindow : Window { void DrawWidget(const Rect &r, int widget) const override { - if (widget != WID_NJS_BACKGROUND) return; - - uint8 progress; // used for progress bar - DrawString(r.left + 2, r.right - 2, r.top + 20, STR_NETWORK_CONNECTING_1 + _network_join_status, TC_FROMSTRING, SA_HOR_CENTER); - switch (_network_join_status) { - case NETWORK_JOIN_STATUS_CONNECTING: case NETWORK_JOIN_STATUS_AUTHORIZING: - case NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO: - progress = 10; // first two stages 10% - break; - case NETWORK_JOIN_STATUS_WAITING: - SetDParam(0, _network_join_waiting); - DrawString(r.left + 2, r.right - 2, r.top + 20 + FONT_HEIGHT_NORMAL, STR_NETWORK_CONNECTING_WAITING, TC_FROMSTRING, SA_HOR_CENTER); - progress = 15; // third stage is 15% - break; - case NETWORK_JOIN_STATUS_DOWNLOADING: - SetDParam(0, _network_join_bytes); - SetDParam(1, _network_join_bytes_total); - DrawString(r.left + 2, r.right - 2, r.top + 20 + FONT_HEIGHT_NORMAL, _network_join_bytes_total == 0 ? STR_NETWORK_CONNECTING_DOWNLOADING_1 : STR_NETWORK_CONNECTING_DOWNLOADING_2, TC_FROMSTRING, SA_HOR_CENTER); - if (_network_join_bytes_total == 0) { - progress = 15; // We don't have the final size yet; the server is still compressing! - break; + switch (widget) { + case WID_NJS_PROGRESS_BAR: { + /* Draw the % complete with a bar and a text */ + DrawFrameRect(r, COLOUR_GREY, FR_BORDERONLY | FR_LOWERED); + Rect ir = r.Shrink(WidgetDimensions::scaled.bevel); + uint8 progress; // used for progress bar + switch (_network_join_status) { + case NETWORK_JOIN_STATUS_CONNECTING: + case NETWORK_JOIN_STATUS_AUTHORIZING: + case NETWORK_JOIN_STATUS_GETTING_COMPANY_INFO: + progress = 10; // first two stages 10% + break; + case NETWORK_JOIN_STATUS_WAITING: + progress = 15; // third stage is 15% + break; + case NETWORK_JOIN_STATUS_DOWNLOADING: + if (_network_join_bytes_total == 0) { + progress = 15; // We don't have the final size yet; the server is still compressing! + break; + } + FALLTHROUGH; + + default: // Waiting is 15%, so the resting receivement of map is maximum 70% + progress = 15 + _network_join_bytes * (100 - 15) / _network_join_bytes_total; + break; } - FALLTHROUGH; + DrawFrameRect(ir.WithWidth(ir.Width() * progress / 100, false), COLOUR_MAUVE, FR_NONE); + DrawString(ir.left, ir.right, CenterBounds(ir.top, ir.bottom, FONT_HEIGHT_NORMAL), STR_NETWORK_CONNECTING_1 + _network_join_status, TC_FROMSTRING, SA_HOR_CENTER); + break; + } - default: // Waiting is 15%, so the resting receivement of map is maximum 70% - progress = 15 + _network_join_bytes * (100 - 15) / _network_join_bytes_total; + case WID_NJS_PROGRESS_TEXT: + switch (_network_join_status) { + case NETWORK_JOIN_STATUS_WAITING: + SetDParam(0, _network_join_waiting); + DrawStringMultiLine(r, STR_NETWORK_CONNECTING_WAITING, TC_FROMSTRING, SA_CENTER); + break; + case NETWORK_JOIN_STATUS_DOWNLOADING: + SetDParam(0, _network_join_bytes); + SetDParam(1, _network_join_bytes_total); + DrawStringMultiLine(r, _network_join_bytes_total == 0 ? STR_NETWORK_CONNECTING_DOWNLOADING_1 : STR_NETWORK_CONNECTING_DOWNLOADING_2, TC_FROMSTRING, SA_CENTER); + break; + default: + break; + } + break; } - - /* Draw nice progress bar :) */ - DrawFrameRect(r.left + 20, r.top + 5, (int)((this->width - 20) * progress / 100), r.top + 15, COLOUR_MAUVE, FR_NONE); } void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { - if (widget != WID_NJS_BACKGROUND) return; - - size->height = 25 + 2 * FONT_HEIGHT_NORMAL; + switch (widget) { + case WID_NJS_PROGRESS_BAR: + /* Account for the statuses */ + for (uint i = 0; i < NETWORK_JOIN_STATUS_END; i++) { + *size = maxdim(*size, GetStringBoundingBox(STR_NETWORK_CONNECTING_1 + i)); + } + /* For the number of waiting (other) players */ + SetDParamMaxValue(0, MAX_CLIENTS); + *size = maxdim(*size, GetStringBoundingBox(STR_NETWORK_CONNECTING_WAITING)); + /* We need some spacing for the 'border' */ + size->height += WidgetDimensions::scaled.frametext.Horizontal(); + size->width += WidgetDimensions::scaled.frametext.Vertical(); + break; - /* Account for the statuses */ - uint width = 0; - for (uint i = 0; i < NETWORK_JOIN_STATUS_END; i++) { - width = std::max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_1 + i).width); + case WID_NJS_PROGRESS_TEXT: + /* Account for downloading ~ 10 MiB */ + SetDParamMaxDigits(0, 8); + SetDParamMaxDigits(1, 8); + *size = maxdim(*size, GetStringBoundingBox(STR_NETWORK_CONNECTING_DOWNLOADING_1)); + *size = maxdim(*size, GetStringBoundingBox(STR_NETWORK_CONNECTING_DOWNLOADING_1)); + break; } - - /* For the number of waiting (other) players */ - SetDParamMaxValue(0, MAX_CLIENTS); - width = std::max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_WAITING).width); - - /* Account for downloading ~ 10 MiB */ - SetDParamMaxDigits(0, 8); - SetDParamMaxDigits(1, 8); - width = std::max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_DOWNLOADING_1).width); - width = std::max(width, GetStringBoundingBox(STR_NETWORK_CONNECTING_DOWNLOADING_2).width); - - /* Give a bit more clearing for the widest strings than strictly needed */ - size->width = width + WD_FRAMERECT_LEFT + WD_FRAMERECT_BOTTOM + 10; } void OnClick(Point pt, int widget, int click_count) override @@ -2232,13 +2268,11 @@ struct NetworkJoinStatusWindow : Window { static const NWidgetPart _nested_network_join_status_window_widgets[] = { NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_NETWORK_CONNECTING_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(WWT_EMPTY, COLOUR_GREY, WID_NJS_BACKGROUND), - NWidget(NWID_HORIZONTAL), - NWidget(NWID_SPACER), SetMinimalSize(75, 0), SetFill(1, 0), - NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NJS_CANCELOK), SetMinimalSize(101, 12), SetDataTip(STR_NETWORK_CONNECTION_DISCONNECT, STR_NULL), - NWidget(NWID_SPACER), SetMinimalSize(75, 0), SetFill(1, 0), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NJS_PROGRESS_BAR), SetFill(1, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NJS_PROGRESS_TEXT), SetFill(1, 0), SetMinimalSize(350, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_WHITE, WID_NJS_CANCELOK), SetMinimalSize(101, 12), SetDataTip(STR_NETWORK_CONNECTION_DISCONNECT, STR_NULL), SetFill(1, 0), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 4), EndContainer(), }; @@ -2289,9 +2323,9 @@ struct NetworkCompanyPasswordWindow : public Window { void UpdateWarningStringSize() { assert(this->nested_root->smallest_x > 0); - this->warning_size.width = this->nested_root->current_x - (WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT); + this->warning_size.width = this->nested_root->current_x - (WidgetDimensions::scaled.framerect.Horizontal()) * 2; this->warning_size.height = GetStringHeight(STR_WARNING_PASSWORD_SECURITY, this->warning_size.width); - this->warning_size.height += WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + this->warning_size.height += (WidgetDimensions::scaled.framerect.Vertical()) * 2; this->ReInit(); } @@ -2307,8 +2341,7 @@ struct NetworkCompanyPasswordWindow : public Window { { if (widget != WID_NCP_WARNING) return; - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, - r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, + DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER); } @@ -2401,14 +2434,14 @@ struct NetworkAskRelayWindow : public Window { { if (widget == WID_NAR_TEXT) { *size = GetStringBoundingBox(STR_NETWORK_ASK_RELAY_TEXT); - size->height = GetStringHeight(STR_NETWORK_ASK_RELAY_TEXT, size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT) + WD_FRAMETEXT_BOTTOM + WD_FRAMETEXT_TOP; + size->height = GetStringHeight(STR_NETWORK_ASK_RELAY_TEXT, size->width - WidgetDimensions::scaled.frametext.Horizontal()) + WidgetDimensions::scaled.frametext.Vertical(); } } void DrawWidget(const Rect &r, int widget) const override { if (widget == WID_NAR_TEXT) { - DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMETEXT_BOTTOM, STR_NETWORK_ASK_RELAY_TEXT, TC_FROMSTRING, SA_CENTER); + DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.frametext), STR_NETWORK_ASK_RELAY_TEXT, TC_FROMSTRING, SA_CENTER); } } @@ -2484,6 +2517,6 @@ void ShowNetworkAskRelay(const std::string &server_connection_string, const std: { CloseWindowByClass(WC_NETWORK_ASK_RELAY); - Window *parent = FindWindowById(WC_MAIN_WINDOW, 0); + Window *parent = GetMainWindow(); new NetworkAskRelayWindow(&_network_ask_relay_desc, parent, server_connection_string, relay_connection_string, token); } diff --git a/src/network/network_internal.h b/src/network/network_internal.h index 58c99867c24fe..3ea63570f3947 100644 --- a/src/network/network_internal.h +++ b/src/network/network_internal.h @@ -108,7 +108,7 @@ void UpdateNetworkGameWindow(); */ struct CommandPacket { /** Make sure the pointer is nullptr. */ - CommandPacket() : next(nullptr), company(INVALID_COMPANY), frame(0), my_cmd(false), tile(0) {} + CommandPacket() : next(nullptr), company(INVALID_COMPANY), frame(0), my_cmd(false) {} CommandPacket *next; ///< the next command packet (if in queue) CompanyID company; ///< company that is executing the command uint32 frame; ///< the frame in which this packet is executed @@ -117,7 +117,6 @@ struct CommandPacket { Commands cmd; ///< command being executed. StringID err_msg; ///< string ID of error message to use. CommandCallback *callback; ///< any callback function executed upon successful completion of the command. - TileIndex tile; ///< location of the command (for e.g. error message or effect display). CommandDataBuffer data; ///< command parameters. }; @@ -138,4 +137,6 @@ std::string_view ParseCompanyFromConnectionString(const std::string &connection_ NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port); std::string NormalizeConnectionString(const std::string &connection_string, uint16 default_port); +void ClientNetworkEmergencySave(); + #endif /* NETWORK_INTERNAL_H */ diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 4cb3b19422244..e235ea4e5de08 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1532,6 +1532,7 @@ static void NetworkAutoCleanCompanies() if (!_network_dedicated) { const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); + assert(ci != nullptr); if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true; } @@ -1918,6 +1919,7 @@ void NetworkServerDoMove(ClientID client_id, CompanyID company_id) if (client_id == CLIENT_ID_SERVER && _network_dedicated) return; NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); + assert(ci != nullptr); /* No need to waste network resources if the client is in the company already! */ if (ci->client_playas == company_id) return; diff --git a/src/newgrf.cpp b/src/newgrf.cpp index e8140419129af..5f3491dc85211 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -48,6 +48,7 @@ #include "language.h" #include "vehicle_base.h" #include "road.h" +#include "newgrf_roadstop.h" #include "table/strings.h" #include "table/build_industry.h" @@ -328,7 +329,6 @@ struct GRFTempEngineData { uint8 roadtramtype; const GRFFile *defaultcargo_grf; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'. Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied. - bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)? uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8 CargoTypes ctt_include_mask; ///< Cargo types always included in the refit mask. CargoTypes ctt_exclude_mask; ///< Cargo types always excluded from the refit mask. @@ -430,13 +430,7 @@ static GRFFile *GetFileByFilename(const char *filename) /** Reset all NewGRFData that was used only while processing data */ static void ClearTemporaryNewGRFData(GRFFile *gf) { - /* Clear the GOTO labels used for GRF processing */ - for (GRFLabel *l = gf->label; l != nullptr;) { - GRFLabel *l2 = l->next; - free(l); - l = l2; - } - gf->label = nullptr; + gf->labels.clear(); } /** @@ -563,10 +557,10 @@ static StringID TTDPStringIDToOTTDStringIDMapping(StringID str) */ StringID MapGRFStringID(uint32 grfid, StringID str) { - if (IsInsideMM(str, 0xD800, 0xE000)) { + if (IsInsideMM(str, 0xD800, 0x10000)) { /* General text provided by NewGRF. * In the specs this is called the 0xDCxx range (misc persistent texts), - * but we meanwhile extended the range to 0xD800-0xDFFF. + * but we meanwhile extended the range to 0xD800-0xFFFF. * Note: We are not involved in the "persistent" business, since we do not store * any NewGRF strings in savegames. */ return GetGRFStringID(grfid, str); @@ -1244,7 +1238,7 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop } case 0x1E: // Callback - ei->callback_mask = buf->ReadByte(); + SB(ei->callback_mask, 0, 8, buf->ReadByte()); break; case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient @@ -1295,7 +1289,6 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop case 0x27: // Miscellaneous flags ei->misc_flags = buf->ReadByte(); _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC); - _gted[e->index].prop27_set = true; break; case 0x28: // Cargo classes allowed @@ -1336,6 +1329,18 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop rvi->curve_speed_mod = buf->ReadWord(); break; + case 0x2F: // Engine variant + ei->variant_id = buf->ReadWord(); + break; + + case 0x30: // Extra miscellaneous flags + ei->extra_flags = static_cast(buf->ReadDWord()); + break; + + case 0x31: // Callback additional mask + SB(ei->callback_mask, 8, 8, buf->ReadByte()); + break; + default: ret = CommonVehicleChangeInfo(ei, prop, buf); break; @@ -1454,7 +1459,7 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop } case 0x17: // Callback mask - ei->callback_mask = buf->ReadByte(); + SB(ei->callback_mask, 0, 8, buf->ReadByte()); break; case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256. @@ -1530,6 +1535,18 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop break; } + case 0x26: // Engine variant + ei->variant_id = buf->ReadWord(); + break; + + case 0x27: // Extra miscellaneous flags + ei->extra_flags = static_cast(buf->ReadDWord()); + break; + + case 0x28: // Callback additional mask + SB(ei->callback_mask, 8, 8, buf->ReadByte()); + break; + default: ret = CommonVehicleChangeInfo(ei, prop, buf); break; @@ -1604,7 +1621,7 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop ei->cargo_type = ctype; } else { ei->cargo_type = CT_INVALID; - grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype); + grfmsg(2, "ShipVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype); } break; } @@ -1630,7 +1647,7 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop } case 0x12: // Callback mask - ei->callback_mask = buf->ReadByte(); + SB(ei->callback_mask, 0, 8, buf->ReadByte()); break; case 0x13: // Refit cost @@ -1702,6 +1719,18 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop break; } + case 0x20: // Engine variant + ei->variant_id = buf->ReadWord(); + break; + + case 0x21: // Extra miscellaneous flags + ei->extra_flags = static_cast(buf->ReadDWord()); + break; + + case 0x22: // Callback additional mask + SB(ei->callback_mask, 8, 8, buf->ReadByte()); + break; + default: ret = CommonVehicleChangeInfo(ei, prop, buf); break; @@ -1798,7 +1827,7 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int } case 0x14: // Callback mask - ei->callback_mask = buf->ReadByte(); + SB(ei->callback_mask, 0, 8, buf->ReadByte()); break; case 0x15: // Refit cost @@ -1856,6 +1885,18 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int avi->max_range = buf->ReadWord(); break; + case 0x20: // Engine variant + ei->variant_id = buf->ReadWord(); + break; + + case 0x21: // Extra miscellaneous flags + ei->extra_flags = static_cast(buf->ReadDWord()); + break; + + case 0x22: // Callback additional mask + SB(ei->callback_mask, 8, 8, buf->ReadByte()); + break; + default: ret = CommonVehicleChangeInfo(ei, prop, buf); break; @@ -1948,6 +1989,12 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte } dts->Clone(tmp_layout.data()); } + + /* Number of layouts must be even, alternating X and Y */ + if (statspec->renderdata.size() & 1) { + grfmsg(1, "StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i); + statspec->renderdata.pop_back(); + } break; } @@ -2070,6 +2117,12 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte /* On error, bail out immediately. Temporary GRF data was already freed */ if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED; } + + /* Number of layouts must be even, alternating X and Y */ + if (statspec->renderdata.size() & 1) { + grfmsg(1, "StationChangeInfo: Station %u defines an odd number of sprite layouts, dropping the last item", stid + i); + statspec->renderdata.pop_back(); + } break; } @@ -2154,7 +2207,7 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteR case 0x0A: // Maximum length bridge->max_length = buf->ReadByte(); - if (bridge->max_length > 16) bridge->max_length = 0xFFFF; + if (bridge->max_length > 16) bridge->max_length = UINT16_MAX; break; case 0x0B: // Cost factor @@ -2163,6 +2216,7 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteR case 0x0C: // Maximum speed bridge->speed = buf->ReadWord(); + if (bridge->speed == 0) bridge->speed = UINT16_MAX; break; case 0x0D: { // Bridge sprite tables @@ -4005,6 +4059,7 @@ static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf) case 0x14: case 0x16: case 0x17: + case 0x18: buf->ReadByte(); break; @@ -4071,13 +4126,12 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteRea if (*ospec == nullptr) { *ospec = CallocT(1); (*ospec)->views = 1; // Default for NewGRFs that don't set it. - (*ospec)->size = 0x11; // Default for NewGRFs that manage to not set it (1x1) + (*ospec)->size = OBJECT_SIZE_1X1; // Default for NewGRFs that manage to not set it (1x1) } /* Swap classid because we read it in BE. */ uint32 classid = buf->ReadDWord(); (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid)); - (*ospec)->enabled = true; break; } @@ -4099,7 +4153,7 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteRea spec->size = buf->ReadByte(); if (GB(spec->size, 0, 4) == 0 || GB(spec->size, 4, 4) == 0) { grfmsg(0, "ObjectChangeInfo: Invalid object size requested (0x%x) for object id %u. Ignoring.", spec->size, id + i); - spec->size = 0x11; // 1x1 + spec->size = OBJECT_SIZE_1X1; } break; @@ -4234,13 +4288,13 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR int n = buf->ReadByte(); for (int j = 0; j != n; j++) { RailTypeLabel label = buf->ReadDWord(); - RailType rt = GetRailTypeByLabel(BSWAP32(label), false); - if (rt != INVALID_RAILTYPE) { + RailType resolved_rt = GetRailTypeByLabel(BSWAP32(label), false); + if (resolved_rt != INVALID_RAILTYPE) { switch (prop) { - case 0x0F: SetBit(rti->powered_railtypes, rt); FALLTHROUGH; // Powered implies compatible. - case 0x0E: SetBit(rti->compatible_railtypes, rt); break; - case 0x18: SetBit(rti->introduction_required_railtypes, rt); break; - case 0x19: SetBit(rti->introduces_railtypes, rt); break; + case 0x0F: SetBit(rti->powered_railtypes, resolved_rt); FALLTHROUGH; // Powered implies compatible. + case 0x0E: SetBit(rti->compatible_railtypes, resolved_rt); break; + case 0x18: SetBit(rti->introduction_required_railtypes, resolved_rt); break; + case 0x19: SetBit(rti->introduces_railtypes, resolved_rt); break; } } } @@ -4448,12 +4502,12 @@ static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteR int n = buf->ReadByte(); for (int j = 0; j != n; j++) { RoadTypeLabel label = buf->ReadDWord(); - RoadType rt = GetRoadTypeByLabel(BSWAP32(label), false); - if (rt != INVALID_ROADTYPE) { + RoadType resolved_rt = GetRoadTypeByLabel(BSWAP32(label), false); + if (resolved_rt != INVALID_ROADTYPE) { switch (prop) { - case 0x0F: SetBit(rti->powered_roadtypes, rt); break; - case 0x18: SetBit(rti->introduction_required_roadtypes, rt); break; - case 0x19: SetBit(rti->introduces_roadtypes, rt); break; + case 0x0F: SetBit(rti->powered_roadtypes, resolved_rt); break; + case 0x18: SetBit(rti->introduction_required_roadtypes, resolved_rt); break; + case 0x19: SetBit(rti->introduces_roadtypes, resolved_rt); break; } } } @@ -4695,6 +4749,137 @@ static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int pro return ret; } +/** + * Ignore properties for roadstops + * @param prop The property to ignore. + * @param buf The property value. + * @return ChangeInfoResult. + */ +static ChangeInfoResult IgnoreRoadStopProperty(uint prop, ByteReader *buf) +{ + ChangeInfoResult ret = CIR_SUCCESS; + + switch (prop) { + case 0x09: + case 0x0C: + case 0x0F: + case 0x11: + buf->ReadByte(); + break; + + case 0x0A: + case 0x0B: + case 0x0E: + case 0x10: + case 0x15: + buf->ReadWord(); + break; + + case 0x08: + case 0x0D: + case 0x12: + buf->ReadDWord(); + break; + + default: + ret = CIR_UNKNOWN; + break; + } + + return ret; +} + +static ChangeInfoResult RoadStopChangeInfo(uint id, int numinfo, int prop, ByteReader *buf) +{ + ChangeInfoResult ret = CIR_SUCCESS; + + if (id + numinfo > 255) { + grfmsg(1, "RoadStopChangeInfo: RoadStop %u is invalid, max %u, ignoring", id + numinfo, 255); + return CIR_INVALID_ID; + } + + if (_cur.grffile->roadstops == nullptr) _cur.grffile->roadstops = CallocT(255); + + for (int i = 0; i < numinfo; i++) { + RoadStopSpec *rs = _cur.grffile->roadstops[id + i]; + + if (rs == nullptr && prop != 0x08) { + grfmsg(1, "RoadStopChangeInfo: Attempt to modify undefined road stop %u, ignoring", id + i); + ChangeInfoResult cir = IgnoreRoadStopProperty(prop, buf); + if (cir > ret) ret = cir; + continue; + } + + switch (prop) { + case 0x08: { // Road Stop Class ID + RoadStopSpec **spec = &_cur.grffile->roadstops[id + i]; + + if (*spec == nullptr) { + *spec = CallocT(1); + new (*spec) RoadStopSpec(); + } + + uint32 classid = buf->ReadDWord(); + (*spec)->cls_id = RoadStopClass::Allocate(BSWAP32(classid)); + (*spec)->spec_id = id + i; + break; + } + + case 0x09: // Road stop type + rs->stop_type = (RoadStopAvailabilityType)buf->ReadByte(); + break; + + case 0x0A: // Road Stop Name + AddStringForMapping(buf->ReadWord(), &rs->name); + break; + + case 0x0B: // Road Stop Class name + AddStringForMapping(buf->ReadWord(), &RoadStopClass::Get(rs->cls_id)->name); + break; + + case 0x0C: // The draw mode + rs->draw_mode = (RoadStopDrawMode)buf->ReadByte(); + break; + + case 0x0D: // Cargo types for random triggers + rs->cargo_triggers = TranslateRefitMask(buf->ReadDWord()); + break; + + case 0x0E: // Animation info + rs->animation.frames = buf->ReadByte(); + rs->animation.status = buf->ReadByte(); + break; + + case 0x0F: // Animation speed + rs->animation.speed = buf->ReadByte(); + break; + + case 0x10: // Animation triggers + rs->animation.triggers = buf->ReadWord(); + break; + + case 0x11: // Callback mask + rs->callback_mask = buf->ReadByte(); + break; + + case 0x12: // General flags + rs->flags = (uint8)buf->ReadDWord(); // Future-proofing, size this as 4 bytes, but we only need one byte's worth of flags at present + break; + + case 0x15: // Cost multipliers + rs->build_cost_multiplier = buf->ReadByte(); + rs->clear_cost_multiplier = buf->ReadByte(); + break; + + default: + ret = CIR_UNKNOWN; + break; + } + } + + return ret; +} + static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property) { switch (cir) { @@ -4759,6 +4944,7 @@ static void FeatureChangeInfo(ByteReader *buf) /* GSF_AIRPORTTILES */ AirportTilesChangeInfo, /* GSF_ROADTYPES */ RoadTypeChangeInfo, /* GSF_TRAMTYPES */ TramTypeChangeInfo, + /* GSF_ROADSTOPS */ RoadStopChangeInfo, }; static_assert(GSF_END == lengthof(handler)); @@ -5237,7 +5423,8 @@ static void NewSpriteGroup(ByteReader *buf) case GSF_HOUSES: case GSF_AIRPORTTILES: case GSF_OBJECTS: - case GSF_INDUSTRYTILES: { + case GSF_INDUSTRYTILES: + case GSF_ROADSTOPS: { byte num_building_sprites = std::max((uint8)1, type); assert(TileLayoutSpriteGroup::CanAllocateItem()); @@ -5352,7 +5539,7 @@ static CargoID TranslateCargo(uint8 feature, uint8 ctype) } } /* Special cargo types for purchase list and stations */ - if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA; + if ((feature == GSF_STATIONS || feature == GSF_ROADSTOPS) && ctype == 0xFE) return CT_DEFAULT_NA; if (ctype == 0xFF) return CT_PURCHASE; if (_cur.grffile->cargo_list.size() == 0) { @@ -5871,6 +6058,61 @@ static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount) } } +static void RoadStopMapSpriteGroup(ByteReader *buf, uint8 idcount) +{ + uint8 *roadstops = AllocaM(uint8, idcount); + for (uint i = 0; i < idcount; i++) { + roadstops[i] = buf->ReadByte(); + } + + uint8 cidcount = buf->ReadByte(); + for (uint c = 0; c < cidcount; c++) { + uint8 ctype = buf->ReadByte(); + uint16 groupid = buf->ReadWord(); + if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) continue; + + ctype = TranslateCargo(GSF_ROADSTOPS, ctype); + if (ctype == CT_INVALID) continue; + + for (uint i = 0; i < idcount; i++) { + RoadStopSpec *roadstopspec = _cur.grffile->roadstops == nullptr ? nullptr : _cur.grffile->roadstops[roadstops[i]]; + + if (roadstopspec == nullptr) { + grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping", roadstops[i]); + continue; + } + + roadstopspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid]; + } + } + + uint16 groupid = buf->ReadWord(); + if (!IsValidGroupID(groupid, "RoadStopMapSpriteGroup")) return; + + if (_cur.grffile->roadstops == nullptr) { + grfmsg(0, "RoadStopMapSpriteGroup: No roadstops defined, skipping."); + return; + } + + for (uint i = 0; i < idcount; i++) { + RoadStopSpec *roadstopspec = _cur.grffile->roadstops == nullptr ? nullptr : _cur.grffile->roadstops[roadstops[i]]; + + if (roadstopspec == nullptr) { + grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X does not exist, skipping.", roadstops[i]); + continue; + } + + if (roadstopspec->grf_prop.grffile != nullptr) { + grfmsg(1, "RoadStopMapSpriteGroup: Road stop with ID 0x%02X mapped multiple times, skipping", roadstops[i]); + continue; + } + + roadstopspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid]; + roadstopspec->grf_prop.grffile = _cur.grffile; + roadstopspec->grf_prop.local_id = roadstops[i]; + RoadStopClass::Assign(roadstopspec); + } +} /* Action 0x03 */ static void FeatureMapSpriteGroup(ByteReader *buf) @@ -5971,6 +6213,10 @@ static void FeatureMapSpriteGroup(ByteReader *buf) AirportTileMapSpriteGroup(buf, idcount); return; + case GSF_ROADSTOPS: + RoadStopMapSpriteGroup(buf, idcount); + return; + default: grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature); return; @@ -6043,7 +6289,7 @@ static void FeatureNewName(ByteReader *buf) break; default: - if (IsInsideMM(id, 0xD000, 0xD400) || IsInsideMM(id, 0xD800, 0xE000)) { + if (IsInsideMM(id, 0xD000, 0xD400) || IsInsideMM(id, 0xD800, 0x10000)) { AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED); break; } @@ -6158,7 +6404,7 @@ static const Action5Type _action5_types[] = { /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" }, /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" }, /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" }, - /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" }, + /* 0x14 */ { A5BLOCK_INVALID, 0, 1, 0, "Flag graphics" }, // deprecated, no longer used. /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" }, /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" }, /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" }, @@ -6238,9 +6484,17 @@ static void GraphicsNew(ByteReader *buf) if (offset <= depot_no_track_offset && offset + num > depot_no_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NO_TRACK; } + /* If the baseset or grf only provides sprites for flat tiles (pre #10282), duplicate those for use on slopes. */ + bool dup_oneway_sprites = ((type == 0x09) && (offset + num <= SPR_ONEWAY_SLOPE_N_OFFSET)); + for (; num > 0; num--) { _cur.nfo_line++; - LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, *_cur.file, _cur.nfo_line); + int load_index = (replace == 0 ? _cur.spriteid++ : replace++); + LoadNextSprite(load_index, *_cur.file, _cur.nfo_line); + if (dup_oneway_sprites) { + DupSprite(load_index, load_index + SPR_ONEWAY_SLOPE_N_OFFSET); + DupSprite(load_index, load_index + SPR_ONEWAY_SLOPE_S_OFFSET); + } } _cur.skip_sprites = skip_num; @@ -6307,7 +6561,7 @@ bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile) } case 0x0A: // animation counter - *value = _tick_counter; + *value = GB(_tick_counter, 0, 16); return true; case 0x0B: { // TTDPatch version @@ -6709,15 +6963,15 @@ static void SkipIf(ByteReader *buf) * file. The jump will always be the first matching label that follows * the current nfo_line. If no matching label is found, the first matching * label in the file is used. */ - GRFLabel *choice = nullptr; - for (GRFLabel *label = _cur.grffile->label; label != nullptr; label = label->next) { - if (label->label != numsprites) continue; + const GRFLabel *choice = nullptr; + for (const auto &label : _cur.grffile->labels) { + if (label.label != numsprites) continue; /* Remember a goto before the current line */ - if (choice == nullptr) choice = label; + if (choice == nullptr) choice = &label; /* If we find a label here, this is definitely good */ - if (label->nfo_line > _cur.nfo_line) { - choice = label; + if (label.nfo_line > _cur.nfo_line) { + choice = &label; break; } } @@ -7038,8 +7292,8 @@ static uint32 GetPatchVariable(uint8 param) */ case 0x13: { byte map_bits = 0; - byte log_X = MapLogX() - 6; // subtraction is required to make the minimal size (64) zero based - byte log_Y = MapLogY() - 6; + byte log_X = Map::LogX() - 6; // subtraction is required to make the minimal size (64) zero based + byte log_Y = Map::LogY() - 6; byte max_edge = std::max(log_X, log_Y); if (log_X == log_Y) { // we have a squared map, since both edges are identical @@ -7565,23 +7819,9 @@ static void DefineGotoLabel(ByteReader *buf) byte nfo_label = buf->ReadByte(); - GRFLabel *label = MallocT(1); - label->label = nfo_label; - label->nfo_line = _cur.nfo_line; - label->pos = _cur.file->GetPos(); - label->next = nullptr; + _cur.grffile->labels.emplace_back(nfo_label, _cur.nfo_line, _cur.file->GetPos()); - /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */ - if (_cur.grffile->label == nullptr) { - _cur.grffile->label = label; - } else { - /* Attach the label to the end of the list */ - GRFLabel *l; - for (l = _cur.grffile->label; l->next != nullptr; l = l->next) {} - l->next = label; - } - - grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label); + grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", nfo_label); } /** @@ -8359,89 +8599,90 @@ static void GRFUnsafe(ByteReader *buf) /** Initialize the TTDPatch flags */ static void InitializeGRFSpecial() { - _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport - | (1 << 0x0D) // newairports - | (1 << 0x0E) // largestations - | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges - | (0 << 0x10) // loadtime - | (1 << 0x12) // presignals - | (1 << 0x13) // extpresignals - | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist - | (1 << 0x1B) // multihead - | (1 << 0x1D) // lowmemory - | (1 << 0x1E); // generalfixes - - _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise - | (1 << 0x08) // mammothtrains - | (1 << 0x09) // trainrefit - | (0 << 0x0B) // subsidiaries - | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading - | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD - | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode - | (1 << 0x14) // bridgespeedlimits - | (1 << 0x16) // eternalgame - | (1 << 0x17) // newtrains - | (1 << 0x18) // newrvs - | (1 << 0x19) // newships - | (1 << 0x1A) // newplanes - | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside - | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway - - _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote - | (1 << 0x03) // semaphores - | (1 << 0x0A) // newobjects - | (0 << 0x0B) // enhancedgui - | (0 << 0x0C) // newagerating - | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes - | (1 << 0x0E) // fullloadany - | (1 << 0x0F) // planespeed - | (0 << 0x10) // moreindustriesperclimate - obsolete - | (0 << 0x11) // moretoylandfeatures - | (1 << 0x12) // newstations - | (1 << 0x13) // tracktypecostdiff - | (1 << 0x14) // manualconvert - | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts - | (1 << 0x16) // canals - | (1 << 0x17) // newstartyear - | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains - | (1 << 0x19) // newhouses - | (1 << 0x1A) // newbridges - | (1 << 0x1B) // newtownnames - | (1 << 0x1C) // moreanimation - | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits - | (1 << 0x1E) // newshistory - | (0 << 0x1F); // custombridgeheads - - _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution - | (1 << 0x01) // windowsnap - | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad - | (1 << 0x03) // pathbasedsignalling - | (0 << 0x04) // aichoosechance - | (1 << 0x05) // resolutionwidth - | (1 << 0x06) // resolutionheight - | (1 << 0x07) // newindustries - | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading - | (0 << 0x09) // townroadbranchprob - | (0 << 0x0A) // tempsnowline - | (1 << 0x0B) // newcargo - | (1 << 0x0C) // enhancemultiplayer - | (1 << 0x0D) // onewayroads - | (1 << 0x0E) // irregularstations - | (1 << 0x0F) // statistics - | (1 << 0x10) // newsounds - | (1 << 0x11) // autoreplace - | (1 << 0x12) // autoslope - | (0 << 0x13) // followvehicle - | (1 << 0x14) // trams - | (0 << 0x15) // enhancetunnels - | (1 << 0x16) // shortrvs - | (1 << 0x17) // articulatedrvs - | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines - | (1 << 0x1E) // variablerunningcosts - | (1 << 0x1F); // any switch is on - - _ttdpatch_flags[4] = (1 << 0x00) // larger persistent storage - | ((_settings_game.economy.inflation ? 1 : 0) << 0x01); // inflation is on + _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1U : 0U) << 0x0C) // keepsmallairport + | (1U << 0x0D) // newairports + | (1U << 0x0E) // largestations + | ((_settings_game.construction.max_bridge_length > 16 ? 1U : 0U) << 0x0F) // longbridges + | (0U << 0x10) // loadtime + | (1U << 0x12) // presignals + | (1U << 0x13) // extpresignals + | ((_settings_game.vehicle.never_expire_vehicles ? 1U : 0U) << 0x16) // enginespersist + | (1U << 0x1B) // multihead + | (1U << 0x1D) // lowmemory + | (1U << 0x1E); // generalfixes + + _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1U : 0U) << 0x07) // moreairports - based on units of noise + | (1U << 0x08) // mammothtrains + | (1U << 0x09) // trainrefit + | (0U << 0x0B) // subsidiaries + | ((_settings_game.order.gradual_loading ? 1U : 0U) << 0x0C) // gradualloading + | (1U << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD + | (1U << 0x13) // unifiedmaglevmode - set bit 1 mode + | (1U << 0x14) // bridgespeedlimits + | (1U << 0x16) // eternalgame + | (1U << 0x17) // newtrains + | (1U << 0x18) // newrvs + | (1U << 0x19) // newships + | (1U << 0x1A) // newplanes + | ((_settings_game.construction.train_signal_side == 1 ? 1U : 0U) << 0x1B) // signalsontrafficside + | ((_settings_game.vehicle.disable_elrails ? 0U : 1U) << 0x1C); // electrifiedrailway + + _ttdpatch_flags[2] = (1U << 0x01) // loadallgraphics - obsolote + | (1U << 0x03) // semaphores + | (1U << 0x0A) // newobjects + | (0U << 0x0B) // enhancedgui + | (0U << 0x0C) // newagerating + | ((_settings_game.construction.build_on_slopes ? 1U : 0U) << 0x0D) // buildonslopes + | (1U << 0x0E) // fullloadany + | (1U << 0x0F) // planespeed + | (0U << 0x10) // moreindustriesperclimate - obsolete + | (0U << 0x11) // moretoylandfeatures + | (1U << 0x12) // newstations + | (1U << 0x13) // tracktypecostdiff + | (1U << 0x14) // manualconvert + | ((_settings_game.construction.build_on_slopes ? 1U : 0U) << 0x15) // buildoncoasts + | (1U << 0x16) // canals + | (1U << 0x17) // newstartyear + | ((_settings_game.vehicle.freight_trains > 1 ? 1U : 0U) << 0x18) // freighttrains + | (1U << 0x19) // newhouses + | (1U << 0x1A) // newbridges + | (1U << 0x1B) // newtownnames + | (1U << 0x1C) // moreanimation + | ((_settings_game.vehicle.wagon_speed_limits ? 1U : 0U) << 0x1D) // wagonspeedlimits + | (1U << 0x1E) // newshistory + | (0U << 0x1F); // custombridgeheads + + _ttdpatch_flags[3] = (0U << 0x00) // newcargodistribution + | (1U << 0x01) // windowsnap + | ((_settings_game.economy.allow_town_roads || _generating_world ? 0U : 1U) << 0x02) // townbuildnoroad + | (1U << 0x03) // pathbasedsignalling + | (0U << 0x04) // aichoosechance + | (1U << 0x05) // resolutionwidth + | (1U << 0x06) // resolutionheight + | (1U << 0x07) // newindustries + | ((_settings_game.order.improved_load ? 1U : 0U) << 0x08) // fifoloading + | (0U << 0x09) // townroadbranchprob + | (0U << 0x0A) // tempsnowline + | (1U << 0x0B) // newcargo + | (1U << 0x0C) // enhancemultiplayer + | (1U << 0x0D) // onewayroads + | (1U << 0x0E) // irregularstations + | (1U << 0x0F) // statistics + | (1U << 0x10) // newsounds + | (1U << 0x11) // autoreplace + | (1U << 0x12) // autoslope + | (0U << 0x13) // followvehicle + | (1U << 0x14) // trams + | (0U << 0x15) // enhancetunnels + | (1U << 0x16) // shortrvs + | (1U << 0x17) // articulatedrvs + | ((_settings_game.vehicle.dynamic_engines ? 1U : 0U) << 0x18) // dynamic engines + | (1U << 0x1E) // variablerunningcosts + | (1U << 0x1F); // any switch is on + + _ttdpatch_flags[4] = (1U << 0x00) // larger persistent storage + | ((_settings_game.economy.inflation ? 1U : 0U) << 0x01) // inflation is on + | (1U << 0x02); // extended string range } /** Reset and clear all NewGRF stations */ @@ -8560,6 +8801,20 @@ static void ResetCustomObjects() } } +static void ResetCustomRoadStops() +{ + for (auto file : _grf_files) { + RoadStopSpec **&roadstopspec = file->roadstops; + if (roadstopspec == nullptr) continue; + for (uint i = 0; i < NUM_ROADSTOPS_PER_GRF; i++) { + free(roadstopspec[i]); + } + + free(roadstopspec); + roadstopspec = nullptr; + } +} + /** Reset and clear all NewGRFs */ static void ResetNewGRF() { @@ -8646,6 +8901,10 @@ void ResetNewGRFData() AirportSpec::ResetAirports(); AirportTileSpec::ResetAirportTiles(); + /* Reset road stop classes */ + RoadStopClass::Reset(); + ResetCustomRoadStops(); + /* Reset canal sprite groups and flags */ memset(_water_feature, 0, sizeof(_water_feature)); @@ -8977,15 +9236,16 @@ static void FinaliseEngineArray() } } - if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; - - /* When the train does not set property 27 (misc flags), but it - * is overridden by a NewGRF graphically we want to disable the - * flipping possibility. */ - if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) { - ClrBit(e->info.misc_flags, EF_RAIL_FLIPS); + /* Do final mapping on variant engine ID and set appropriate flags on variant engine */ + if (e->info.variant_id != INVALID_ENGINE) { + e->info.variant_id = GetNewEngineID(e->grf_prop.grffile, e->type, e->info.variant_id); + if (e->info.variant_id != INVALID_ENGINE) { + Engine::Get(e->info.variant_id)->display_flags |= EngineDisplayFlags::HasVariants | EngineDisplayFlags::IsFolded; + } } + if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; + /* Skip wagons, there livery is defined via the engine */ if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) { LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, nullptr); @@ -9258,7 +9518,7 @@ static void FinaliseObjectsArray() ObjectSpec **&objectspec = file->objectspec; if (objectspec != nullptr) { for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) { - if (objectspec[i] != nullptr && objectspec[i]->grf_prop.grffile != nullptr && objectspec[i]->enabled) { + if (objectspec[i] != nullptr && objectspec[i]->grf_prop.grffile != nullptr && objectspec[i]->IsEnabled()) { _object_mngr.SetEntitySpec(objectspec[i]); } } @@ -9782,6 +10042,7 @@ static void AfterLoadGRFs() e->info.climates = 0; } else { e->u.rail.railtype = railtype; + e->u.rail.intended_railtype = railtype; } } @@ -9808,7 +10069,7 @@ void LoadNewGRF(uint load_index, uint num_baseset) Date date = _date; Year year = _cur_year; DateFract date_fract = _date_fract; - uint32 tick_counter = _tick_counter; + uint64 tick_counter = _tick_counter; byte display_opt = _display_opt; if (_networking) { diff --git a/src/newgrf.h b/src/newgrf.h index eb6c22d477e43..7561fb145ba12 100644 --- a/src/newgrf.h +++ b/src/newgrf.h @@ -84,6 +84,7 @@ enum GrfSpecFeature { GSF_AIRPORTTILES, GSF_ROADTYPES, GSF_TRAMTYPES, + GSF_ROADSTOPS, GSF_END, GSF_FAKE_TOWNS = GSF_END, ///< Fake town GrfSpecFeature for NewGRF debugging (parent scope) @@ -98,7 +99,8 @@ struct GRFLabel { byte label; uint32 nfo_line; size_t pos; - struct GRFLabel *next; + + GRFLabel(byte label, uint32 nfo_line, size_t pos) : label(label), nfo_line(nfo_line), pos(pos) {} }; /** Dynamic data of a loaded NewGRF */ @@ -117,11 +119,12 @@ struct GRFFile : ZeroedMemoryAllocator { struct ObjectSpec **objectspec; struct AirportSpec **airportspec; struct AirportTileSpec **airtspec; + struct RoadStopSpec **roadstops; uint32 param[0x80]; uint param_end; ///< one more than the highest set parameter - GRFLabel *label; ///< Pointer to the first label. This is a linked list, not an array. + std::vector labels; ///< List of labels std::vector cargo_list; ///< Cargo translation table (local ID -> label) uint8 cargo_map[NUM_CARGO]; ///< Inverse cargo translation table (CargoID -> local ID) diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index df400145d5b68..f41ab157147c2 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.cpp @@ -143,8 +143,8 @@ bool AirportSpec::IsWithinMapBounds(byte table, TileIndex tile) const byte h = this->size_y; if (this->rotation[table] == DIR_E || this->rotation[table] == DIR_W) Swap(w, h); - return TileX(tile) + w < MapSizeX() && - TileY(tile) + h < MapSizeY(); + return TileX(tile) + w < Map::SizeX() && + TileY(tile) + h < Map::SizeY(); } /** @@ -175,7 +175,7 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as) { byte airport_id = this->AddEntityID(as->grf_prop.local_id, as->grf_prop.grffile->grfid, as->grf_prop.subst_id); - if (airport_id == invalid_ID) { + if (airport_id == this->invalid_id) { grfmsg(1, "Airport.SetEntitySpec: Too many airports allocated. Ignoring."); return; } @@ -183,15 +183,15 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as) memcpy(AirportSpec::GetWithoutOverride(airport_id), as, sizeof(*as)); /* Now add the overrides. */ - for (int i = 0; i < max_offset; i++) { + for (int i = 0; i < this->max_offset; i++) { AirportSpec *overridden_as = AirportSpec::GetWithoutOverride(i); - if (entity_overrides[i] != as->grf_prop.local_id || grfid_overrides[i] != as->grf_prop.grffile->grfid) continue; + if (this->entity_overrides[i] != as->grf_prop.local_id || this->grfid_overrides[i] != as->grf_prop.grffile->grfid) continue; overridden_as->grf_prop.override = airport_id; overridden_as->enabled = false; - entity_overrides[i] = invalid_ID; - grfid_overrides[i] = 0; + this->entity_overrides[i] = this->invalid_id; + this->grfid_overrides[i] = 0; } } diff --git a/src/newgrf_airport.h b/src/newgrf_airport.h index 264da05ebb105..2774fbc645359 100644 --- a/src/newgrf_airport.h +++ b/src/newgrf_airport.h @@ -58,9 +58,9 @@ class AirportTileTableIterator : public TileIterator { return this->att->gfx; } - virtual AirportTileTableIterator *Clone() const + virtual std::unique_ptr Clone() const { - return new AirportTileTableIterator(*this); + return std::make_unique(*this); } }; diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index 01d4baedc9cf2..ebdf226dd07e3 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.cpp @@ -23,6 +23,7 @@ #include "safeguards.h" +extern uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile); AirportTileSpec AirportTileSpec::tiles[NUM_AIRPORTTILES]; @@ -67,7 +68,7 @@ void AirportTileOverrideManager::SetEntitySpec(const AirportTileSpec *airpts) { StationGfx airpt_id = this->AddEntityID(airpts->grf_prop.local_id, airpts->grf_prop.grffile->grfid, airpts->grf_prop.subst_id); - if (airpt_id == invalid_ID) { + if (airpt_id == this->invalid_id) { grfmsg(1, "AirportTile.SetEntitySpec: Too many airport tiles allocated. Ignoring."); return; } @@ -75,15 +76,15 @@ void AirportTileOverrideManager::SetEntitySpec(const AirportTileSpec *airpts) memcpy(&AirportTileSpec::tiles[airpt_id], airpts, sizeof(*airpts)); /* Now add the overrides. */ - for (int i = 0; i < max_offset; i++) { + for (int i = 0; i < this->max_offset; i++) { AirportTileSpec *overridden_airpts = &AirportTileSpec::tiles[i]; - if (entity_overrides[i] != airpts->grf_prop.local_id || grfid_overrides[i] != airpts->grf_prop.grffile->grfid) continue; + if (this->entity_overrides[i] != airpts->grf_prop.local_id || this->grfid_overrides[i] != airpts->grf_prop.grffile->grfid) continue; overridden_airpts->grf_prop.override = airpt_id; overridden_airpts->enabled = false; - entity_overrides[i] = invalid_ID; - grfid_overrides[i] = 0; + this->entity_overrides[i] = this->invalid_id; + this->grfid_overrides[i] = 0; } } @@ -162,8 +163,6 @@ static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 { assert(this->st != nullptr); - extern uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile); - switch (variable) { /* Terrain type */ case 0x41: return GetTerrainType(this->tile); @@ -279,7 +278,7 @@ bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const Airport } /** Helper class for animation control. */ -struct AirportTileAnimationBase : public AnimationBase { +struct AirportTileAnimationBase : public AnimationBase > { static const CallbackID cb_animation_speed = CBID_AIRPTILE_ANIMATION_SPEED; static const CallbackID cb_animation_next_frame = CBID_AIRPTILE_ANIM_NEXT_FRAME; diff --git a/src/newgrf_airporttiles.h b/src/newgrf_airporttiles.h index 37460622d4dc7..e8b40468ecb45 100644 --- a/src/newgrf_airporttiles.h +++ b/src/newgrf_airporttiles.h @@ -82,7 +82,6 @@ struct AirportTileSpec { friend void AirportTileOverrideManager::SetEntitySpec(const AirportTileSpec *airpts); }; -StationGfx GetTranslatedAirportTileID(StationGfx gfx); void AnimateAirportTile(TileIndex tile); void AirportTileAnimationTrigger(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID); void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID); diff --git a/src/newgrf_animation_base.h b/src/newgrf_animation_base.h index ee8622b56e218..8df02284080c8 100644 --- a/src/newgrf_animation_base.h +++ b/src/newgrf_animation_base.h @@ -17,15 +17,22 @@ #include "newgrf_callbacks.h" #include "tile_map.h" +template +struct TileAnimationFrameAnimationHelper { + static byte Get(Tobj *obj, TileIndex tile) { return GetAnimationFrame(tile); } + static void Set(Tobj *obj, TileIndex tile, byte frame) { SetAnimationFrame(tile, frame); } +}; + /** * Helper class for a unified approach to NewGRF animation. - * @tparam Tbase Instantiation of this class. - * @tparam Tspec NewGRF specification related to the animated tile. - * @tparam Tobj Object related to the animated tile. - * @tparam Textra Custom extra callback data. - * @tparam GetCallback The callback function pointer. + * @tparam Tbase Instantiation of this class. + * @tparam Tspec NewGRF specification related to the animated tile. + * @tparam Tobj Object related to the animated tile. + * @tparam Textra Custom extra callback data. + * @tparam GetCallback The callback function pointer. + * @tparam Tframehelper The animation frame get/set helper. */ -template +template struct AnimationBase { /** * Animate a single tile. @@ -53,9 +60,9 @@ struct AnimationBase { * increasing this value by one doubles the wait. 0 is the minimum value * allowed for animation_speed, which corresponds to 30ms, and 16 is the * maximum, corresponding to around 33 minutes. */ - if (_tick_counter % (1 << animation_speed) != 0) return; + if (_tick_counter % (1ULL << animation_speed) != 0) return; - uint8 frame = GetAnimationFrame(tile); + uint8 frame = Tframehelper::Get(obj, tile); uint8 num_frames = spec->animation.frames; bool frame_set_by_callback = false; @@ -98,7 +105,7 @@ struct AnimationBase { } } - SetAnimationFrame(tile, frame); + Tframehelper::Set(obj, tile, frame); MarkTileDirtyByTile(tile); } @@ -124,7 +131,7 @@ struct AnimationBase { case 0xFE: AddAnimatedTile(tile); break; case 0xFF: DeleteAnimatedTile(tile); break; default: - SetAnimationFrame(tile, callback); + Tframehelper::Set(obj, tile, callback); AddAnimatedTile(tile); break; } diff --git a/src/newgrf_callbacks.h b/src/newgrf_callbacks.h index ed32a3abf17db..482031cec0003 100644 --- a/src/newgrf_callbacks.h +++ b/src/newgrf_callbacks.h @@ -279,6 +279,9 @@ enum CallbackID { /** Called to spawn visual effects for vehicles. */ CBID_VEHICLE_SPAWN_VISUAL_EFFECT = 0x160, // 15 bit callback + + /** Called to determine the engine name to show. */ + CBID_VEHICLE_NAME = 0x161, // 15 bit callback }; /** @@ -294,6 +297,7 @@ enum VehicleCallbackMask { CBM_VEHICLE_CARGO_SUFFIX = 5, ///< Show suffix after cargo name CBM_VEHICLE_COLOUR_REMAP = 6, ///< Change colour mapping of vehicle CBM_VEHICLE_SOUND_EFFECT = 7, ///< Vehicle uses custom sound effects + CBM_VEHICLE_NAME = 8, ///< Engine name }; /** @@ -307,6 +311,15 @@ enum StationCallbackMask { CBM_STATION_SLOPE_CHECK = 4, ///< Check slope of new station tiles }; +/** + * Callback masks for road stops. + */ +enum RoadStopCallbackMask { + CBM_ROAD_STOP_AVAIL = 0, ///< Availability of road stop in construction window + CBM_ROAD_STOP_ANIMATION_NEXT_FRAME = 1, ///< Use a custom next frame callback + CBM_ROAD_STOP_ANIMATION_SPEED = 2, ///< Customize the animation speed of the road stop +}; + /** * Callback masks for houses. */ diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index 2af9d888cfe31..eb8d3f8c40666 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -40,25 +40,14 @@ */ OverrideManagerBase::OverrideManagerBase(uint16 offset, uint16 maximum, uint16 invalid) { - max_offset = offset; - max_new_entities = maximum; - invalid_ID = invalid; - - mapping_ID = CallocT(max_new_entities); - entity_overrides = MallocT(max_offset); - for (size_t i = 0; i < max_offset; i++) entity_overrides[i] = invalid; - grfid_overrides = CallocT(max_offset); -} - -/** - * Destructor of the generic class. - * Frees allocated memory of constructor - */ -OverrideManagerBase::~OverrideManagerBase() -{ - free(mapping_ID); - free(entity_overrides); - free(grfid_overrides); + this->max_offset = offset; + this->max_entities = maximum; + this->invalid_id = invalid; + + this->mappings.resize(this->max_entities); + this->entity_overrides.resize(this->max_offset); + std::fill(this->entity_overrides.begin(), this->entity_overrides.end(), this->invalid_id); + this->grfid_overrides.resize(this->max_offset); } /** @@ -71,26 +60,24 @@ OverrideManagerBase::~OverrideManagerBase() */ void OverrideManagerBase::Add(uint8 local_id, uint32 grfid, uint entity_type) { - assert(entity_type < max_offset); + assert(entity_type < this->max_offset); /* An override can be set only once */ - if (entity_overrides[entity_type] != invalid_ID) return; - entity_overrides[entity_type] = local_id; - grfid_overrides[entity_type] = grfid; + if (this->entity_overrides[entity_type] != this->invalid_id) return; + this->entity_overrides[entity_type] = local_id; + this->grfid_overrides[entity_type] = grfid; } /** Resets the mapping, which is used while initializing game */ void OverrideManagerBase::ResetMapping() { - memset(mapping_ID, 0, (max_new_entities - 1) * sizeof(EntityIDMapping)); + std::fill(this->mappings.begin(), this->mappings.end(), EntityIDMapping{}); } /** Resets the override, which is used while initializing game */ void OverrideManagerBase::ResetOverride() { - for (uint16 i = 0; i < max_offset; i++) { - entity_overrides[i] = invalid_ID; - grfid_overrides[i] = 0; - } + std::fill(this->entity_overrides.begin(), this->entity_overrides.end(), this->invalid_id); + std::fill(this->grfid_overrides.begin(), this->grfid_overrides.end(), uint32()); } /** @@ -101,16 +88,14 @@ void OverrideManagerBase::ResetOverride() */ uint16 OverrideManagerBase::GetID(uint8 grf_local_id, uint32 grfid) const { - const EntityIDMapping *map; - - for (uint16 id = 0; id < max_new_entities; id++) { - map = &mapping_ID[id]; + for (uint16 id = 0; id < this->max_entities; id++) { + const EntityIDMapping *map = &this->mappings[id]; if (map->entity_id == grf_local_id && map->grfid == grfid) { return id; } } - return invalid_ID; + return this->invalid_id; } /** @@ -123,19 +108,16 @@ uint16 OverrideManagerBase::GetID(uint8 grf_local_id, uint32 grfid) const uint16 OverrideManagerBase::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id) { uint16 id = this->GetID(grf_local_id, grfid); - EntityIDMapping *map; /* Look to see if this entity has already been added. This is done * separately from the loop below in case a GRF has been deleted, and there * are any gaps in the array. */ - if (id != invalid_ID) { - return id; - } + if (id != this->invalid_id) return id; /* This entity hasn't been defined before, so give it an ID now. */ - for (id = max_offset; id < max_new_entities; id++) { - map = &mapping_ID[id]; + for (id = this->max_offset; id < this->max_entities; id++) { + EntityIDMapping *map = &this->mappings[id]; if (CheckValidNewID(id) && map->entity_id == 0 && map->grfid == 0) { map->entity_id = grf_local_id; @@ -145,7 +127,7 @@ uint16 OverrideManagerBase::AddEntityID(byte grf_local_id, uint32 grfid, byte su } } - return invalid_ID; + return this->invalid_id; } /** @@ -155,7 +137,7 @@ uint16 OverrideManagerBase::AddEntityID(byte grf_local_id, uint32 grfid, byte su */ uint32 OverrideManagerBase::GetGRFID(uint16 entity_id) const { - return mapping_ID[entity_id].grfid; + return this->mappings[entity_id].grfid; } /** @@ -165,7 +147,7 @@ uint32 OverrideManagerBase::GetGRFID(uint16 entity_id) const */ uint16 OverrideManagerBase::GetSubstituteID(uint16 entity_id) const { - return mapping_ID[entity_id].substitute_id; + return this->mappings[entity_id].substitute_id; } /** @@ -177,7 +159,7 @@ void HouseOverrideManager::SetEntitySpec(const HouseSpec *hs) { HouseID house_id = this->AddEntityID(hs->grf_prop.local_id, hs->grf_prop.grffile->grfid, hs->grf_prop.subst_id); - if (house_id == invalid_ID) { + if (house_id == this->invalid_id) { grfmsg(1, "House.SetEntitySpec: Too many houses allocated. Ignoring."); return; } @@ -185,14 +167,14 @@ void HouseOverrideManager::SetEntitySpec(const HouseSpec *hs) MemCpyT(HouseSpec::Get(house_id), hs); /* Now add the overrides. */ - for (int i = 0; i != max_offset; i++) { + for (int i = 0; i < this->max_offset; i++) { HouseSpec *overridden_hs = HouseSpec::Get(i); - if (entity_overrides[i] != hs->grf_prop.local_id || grfid_overrides[i] != hs->grf_prop.grffile->grfid) continue; + if (this->entity_overrides[i] != hs->grf_prop.local_id || this->grfid_overrides[i] != hs->grf_prop.grffile->grfid) continue; overridden_hs->grf_prop.override = house_id; - entity_overrides[i] = invalid_ID; - grfid_overrides[i] = 0; + this->entity_overrides[i] = this->invalid_id; + this->grfid_overrides[i] = 0; } } @@ -205,14 +187,14 @@ void HouseOverrideManager::SetEntitySpec(const HouseSpec *hs) uint16 IndustryOverrideManager::GetID(uint8 grf_local_id, uint32 grfid) const { uint16 id = OverrideManagerBase::GetID(grf_local_id, grfid); - if (id != invalid_ID) return id; + if (id != this->invalid_id) return id; /* No mapping found, try the overrides */ - for (id = 0; id < max_offset; id++) { - if (entity_overrides[id] == grf_local_id && grfid_overrides[id] == grfid) return id; + for (id = 0; id < this->max_offset; id++) { + if (this->entity_overrides[id] == grf_local_id && this->grfid_overrides[id] == grfid) return id; } - return invalid_ID; + return this->invalid_id; } /** @@ -225,9 +207,9 @@ uint16 IndustryOverrideManager::GetID(uint8 grf_local_id, uint32 grfid) const uint16 IndustryOverrideManager::AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id) { /* This entity hasn't been defined before, so give it an ID now. */ - for (uint16 id = 0; id < max_new_entities; id++) { + for (uint16 id = 0; id < this->max_entities; id++) { /* Skip overridden industries */ - if (id < max_offset && entity_overrides[id] != invalid_ID) continue; + if (id < this->max_offset && this->entity_overrides[id] != this->invalid_id) continue; /* Get the real live industry */ const IndustrySpec *inds = GetIndustrySpec(id); @@ -236,7 +218,7 @@ uint16 IndustryOverrideManager::AddEntityID(byte grf_local_id, uint32 grfid, byt * And it must not already be used by a grf (grffile == nullptr). * So reserve this slot here, as it is the chosen one */ if (!inds->enabled && inds->grf_prop.grffile == nullptr) { - EntityIDMapping *map = &mapping_ID[id]; + EntityIDMapping *map = &this->mappings[id]; if (map->entity_id == 0 && map->grfid == 0) { /* winning slot, mark it as been used */ @@ -248,7 +230,7 @@ uint16 IndustryOverrideManager::AddEntityID(byte grf_local_id, uint32 grfid, byt } } - return invalid_ID; + return this->invalid_id; } /** @@ -262,16 +244,16 @@ void IndustryOverrideManager::SetEntitySpec(IndustrySpec *inds) /* First step : We need to find if this industry is already specified in the savegame data. */ IndustryType ind_id = this->GetID(inds->grf_prop.local_id, inds->grf_prop.grffile->grfid); - if (ind_id == invalid_ID) { + if (ind_id == this->invalid_id) { /* Not found. * 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); - inds->grf_prop.override = invalid_ID; // make sure it will not be detected as overridden + inds->grf_prop.override = this->invalid_id; // make sure it will not be detected as overridden } - if (ind_id == invalid_ID) { + if (ind_id == this->invalid_id) { grfmsg(1, "Industry.SetEntitySpec: Too many industries allocated. Ignoring."); return; } @@ -286,7 +268,7 @@ void IndustryTileOverrideManager::SetEntitySpec(const IndustryTileSpec *its) { IndustryGfx indt_id = this->AddEntityID(its->grf_prop.local_id, its->grf_prop.grffile->grfid, its->grf_prop.subst_id); - if (indt_id == invalid_ID) { + if (indt_id == this->invalid_id) { grfmsg(1, "IndustryTile.SetEntitySpec: Too many industry tiles allocated. Ignoring."); return; } @@ -294,15 +276,15 @@ void IndustryTileOverrideManager::SetEntitySpec(const IndustryTileSpec *its) memcpy(&_industry_tile_specs[indt_id], its, sizeof(*its)); /* Now add the overrides. */ - for (int i = 0; i < max_offset; i++) { + for (int i = 0; i < this->max_offset; i++) { IndustryTileSpec *overridden_its = &_industry_tile_specs[i]; - if (entity_overrides[i] != its->grf_prop.local_id || grfid_overrides[i] != its->grf_prop.grffile->grfid) continue; + if (this->entity_overrides[i] != its->grf_prop.local_id || this->grfid_overrides[i] != its->grf_prop.grffile->grfid) continue; overridden_its->grf_prop.override = indt_id; overridden_its->enabled = false; - entity_overrides[i] = invalid_ID; - grfid_overrides[i] = 0; + this->entity_overrides[i] = this->invalid_id; + this->grfid_overrides[i] = 0; } } @@ -317,7 +299,7 @@ void ObjectOverrideManager::SetEntitySpec(ObjectSpec *spec) /* First step : We need to find if this object is already specified in the savegame data. */ ObjectType type = this->GetID(spec->grf_prop.local_id, spec->grf_prop.grffile->grfid); - if (type == invalid_ID) { + if (type == this->invalid_id) { /* Not found. * Or it has already been overridden, so you've lost your place. * Or it is a simple substitute. @@ -325,7 +307,7 @@ void ObjectOverrideManager::SetEntitySpec(ObjectSpec *spec) type = this->AddEntityID(spec->grf_prop.local_id, spec->grf_prop.grffile->grfid, OBJECT_TRANSMITTER); } - if (type == invalid_ID) { + if (type == this->invalid_id) { grfmsg(1, "Object.SetEntitySpec: Too many objects allocated. Ignoring."); return; } @@ -433,7 +415,7 @@ TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets, Axi if (axis == AXIS_Y) Swap(x, y); /* Make sure we never roam outside of the map, better wrap in that case */ - return TILE_MASK(tile + TileDiffXY(x, y)); + return Map::WrapToMap(tile + TileDiffXY(x, y)); } /** diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index ff241369a2be7..a53752ed0ed4f 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -191,20 +191,20 @@ struct EntityIDMapping { class OverrideManagerBase { protected: - uint16 *entity_overrides; - uint32 *grfid_overrides; + std::vector entity_overrides; + std::vector grfid_overrides; - uint16 max_offset; ///< what is the length of the original entity's array of specs - uint16 max_new_entities; ///< what is the amount of entities, old and new summed + uint16 max_offset; ///< what is the length of the original entity's array of specs + uint16 max_entities; ///< what is the amount of entities, old and new summed - uint16 invalid_ID; ///< ID used to detected invalid entities; + uint16 invalid_id; ///< ID used to detected invalid entities virtual bool CheckValidNewID(uint16 testid) { return true; } public: - EntityIDMapping *mapping_ID; ///< mapping of ids from grf files. Public out of convenience + std::vector mappings; ///< mapping of ids from grf files. Public out of convenience OverrideManagerBase(uint16 offset, uint16 maximum, uint16 invalid); - virtual ~OverrideManagerBase(); + virtual ~OverrideManagerBase() {} void ResetOverride(); void ResetMapping(); @@ -216,8 +216,8 @@ class OverrideManagerBase { uint16 GetSubstituteID(uint16 entity_id) const; virtual uint16 GetID(uint8 grf_local_id, uint32 grfid) const; - inline uint16 GetMaxMapping() const { return max_new_entities; } - inline uint16 GetMaxOffset() const { return max_offset; } + inline uint16 GetMaxMapping() const { return this->max_entities; } + inline uint16 GetMaxOffset() const { return this->max_offset; } }; @@ -267,7 +267,7 @@ class AirportOverrideManager : public OverrideManagerBase { struct AirportTileSpec; class AirportTileOverrideManager : public OverrideManagerBase { protected: - virtual bool CheckValidNewID(uint16 testid) { return testid != 0xFF; } + virtual bool CheckValidNewID(uint16 testid) override { return testid != 0xFF; } public: AirportTileOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) : OverrideManagerBase(offset, maximum, invalid) {} @@ -278,7 +278,7 @@ class AirportTileOverrideManager : public OverrideManagerBase { struct ObjectSpec; class ObjectOverrideManager : public OverrideManagerBase { protected: - virtual bool CheckValidNewID(uint16 testid) { return testid != 0xFF; } + virtual bool CheckValidNewID(uint16 testid) override { return testid != 0xFF; } public: ObjectOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) : OverrideManagerBase(offset, maximum, invalid) {} diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index ec221e2f337a4..764fd995cf3ed 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -9,6 +9,7 @@ #include "stdafx.h" #include +#include "core/backup_type.hpp" #include "window_gui.h" #include "window_func.h" #include "random_access_file_type.h" @@ -273,11 +274,6 @@ static inline const NIHelper *GetFeatureHelper(uint window_number) /** Window used for inspecting NewGRFs. */ struct NewGRFInspectWindow : Window { - static const int LEFT_OFFSET = 5; ///< Position of left edge - static const int RIGHT_OFFSET = 5; ///< Position of right edge - static const int TOP_OFFSET = 5; ///< Position of top edge - static const int BOTTOM_OFFSET = 5; ///< Position of bottom edge - /** The value for the variable 60 parameters. */ static uint32 var60params[GSF_FAKE_END][0x20]; @@ -376,15 +372,15 @@ struct NewGRFInspectWindow : Window { case WID_NGRFI_VEH_CHAIN: { assert(this->HasChainIndex()); GrfSpecFeature f = GetFeatureNum(this->window_number); - size->height = std::max(size->height, GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height + 2 + WD_BEVEL_TOP + WD_BEVEL_BOTTOM); + size->height = std::max(size->height, GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height + 2 + WidgetDimensions::scaled.bevel.Vertical()); break; } case WID_NGRFI_MAINPANEL: - resize->height = std::max(11, FONT_HEIGHT_NORMAL + 1); + resize->height = std::max(11, FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal); resize->width = 1; - size->height = 5 * resize->height + TOP_OFFSET + BOTTOM_OFFSET; + size->height = 5 * resize->height + WidgetDimensions::scaled.frametext.Vertical(); break; } } @@ -407,7 +403,7 @@ struct NewGRFInspectWindow : Window { offset -= this->vscroll->GetPosition(); if (offset < 0 || offset >= this->vscroll->GetCapacity()) return; - ::DrawString(r.left + LEFT_OFFSET, r.right - RIGHT_OFFSET, r.top + TOP_OFFSET + (offset * this->resize.step_height), buf, TC_BLACK); + ::DrawString(r.Shrink(WidgetDimensions::scaled.frametext).Shrink(0, offset * this->resize.step_height, 0, 0), buf, TC_BLACK); } void DrawWidget(const Rect &r, int widget) const override @@ -428,7 +424,8 @@ struct NewGRFInspectWindow : Window { if (u == v) sel_end = total_width; } - int width = r.right + 1 - r.left - WD_BEVEL_LEFT - WD_BEVEL_RIGHT; + Rect br = r.Shrink(WidgetDimensions::scaled.bevel); + int width = br.Width(); int skip = 0; if (total_width > width) { int sel_center = (sel_start + sel_end) / 2; @@ -437,8 +434,8 @@ struct NewGRFInspectWindow : Window { GrfSpecFeature f = GetFeatureNum(this->window_number); int h = GetVehicleImageCellSize((VehicleType)(VEH_TRAIN + (f - GSF_TRAINS)), EIT_IN_DEPOT).height; - int y = (r.top + r.bottom - h) / 2; - DrawVehicleImage(v->First(), r.left + WD_BEVEL_LEFT, r.right - WD_BEVEL_RIGHT, y + 1, INVALID_VEHICLE, EIT_IN_DETAILS, skip); + int y = CenterBounds(br.top, br.bottom, h); + DrawVehicleImage(v->First(), br, INVALID_VEHICLE, EIT_IN_DETAILS, skip); /* Highlight the articulated part (this is different to the whole-vehicle highlighting of DrawVehicleImage */ if (_current_text_dir == TD_RTL) { @@ -584,7 +581,7 @@ struct NewGRFInspectWindow : Window { if (nif->variables == nullptr) return; /* Get the line, make sure it's within the boundaries. */ - int line = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NGRFI_MAINPANEL, TOP_OFFSET); + int line = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NGRFI_MAINPANEL, WidgetDimensions::scaled.frametext.top); if (line == INT_MAX) return; /* Find the variable related to the line */ @@ -610,7 +607,7 @@ struct NewGRFInspectWindow : Window { void OnResize() override { - this->vscroll->SetCapacityFromWidget(this, WID_NGRFI_MAINPANEL, TOP_OFFSET + BOTTOM_OFFSET); + this->vscroll->SetCapacityFromWidget(this, WID_NGRFI_MAINPANEL, WidgetDimensions::scaled.frametext.Vertical()); } /** @@ -779,6 +776,8 @@ GrfSpecFeature GetGrfSpecFeature(TileIndex tile) switch (GetStationType(tile)) { case STATION_RAIL: return GSF_STATIONS; case STATION_AIRPORT: return GSF_AIRPORTTILES; + case STATION_BUS: return GSF_ROADSTOPS; + case STATION_TRUCK: return GSF_ROADSTOPS; default: return GSF_INVALID; } } @@ -812,12 +811,18 @@ struct SpriteAlignerWindow : Window { Scrollbar *vscroll; SmallMap offs_start_map; ///< Mapping of starting offsets for the sprites which have been aligned in the sprite aligner window. + static bool centre; + static bool crosshair; + SpriteAlignerWindow(WindowDesc *desc, WindowNumber wno) : Window(desc) { this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_SA_SCROLLBAR); this->FinishInitNested(wno); + this->SetWidgetLoweredState(WID_SA_CENTRE, SpriteAlignerWindow::centre); + this->SetWidgetLoweredState(WID_SA_CROSSHAIR, SpriteAlignerWindow::crosshair); + /* Oh yes, we assume there is at least one normal sprite! */ while (GetSpriteType(this->current_sprite) != ST_NORMAL) this->current_sprite++; } @@ -863,7 +868,9 @@ struct SpriteAlignerWindow : Window { size->height = ScaleGUITrad(200); break; case WID_SA_LIST: - resize->height = FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + SetDParamMaxDigits(0, 6); + size->width = GetStringBoundingBox(STR_BLACK_COMMA).width + padding.width; + resize->height = FONT_HEIGHT_NORMAL + padding.height; resize->width = 1; fill->height = resize->height; break; @@ -878,20 +885,26 @@ struct SpriteAlignerWindow : Window { case WID_SA_SPRITE: { /* Center the sprite ourselves */ const Sprite *spr = GetSprite(this->current_sprite, ST_NORMAL); - int width = r.right - r.left + 1 - WD_BEVEL_LEFT - WD_BEVEL_RIGHT; - int height = r.bottom - r.top + 1 - WD_BEVEL_TOP - WD_BEVEL_BOTTOM; - int x = -UnScaleGUI(spr->x_offs) + (width - UnScaleGUI(spr->width) ) / 2; - int y = -UnScaleGUI(spr->y_offs) + (height - UnScaleGUI(spr->height)) / 2; + Rect ir = r.Shrink(WidgetDimensions::scaled.bevel); + int x; + int y; + if (SpriteAlignerWindow::centre) { + x = -UnScaleGUI(spr->x_offs) + (ir.Width() - UnScaleGUI(spr->width)) / 2; + y = -UnScaleGUI(spr->y_offs) + (ir.Height() - UnScaleGUI(spr->height)) / 2; + } else { + x = ir.Width() / 2; + y = ir.Height() / 2; + } DrawPixelInfo new_dpi; - if (!FillDrawPixelInfo(&new_dpi, r.left + WD_BEVEL_LEFT, r.top + WD_BEVEL_TOP, width, height)) break; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &new_dpi; + if (!FillDrawPixelInfo(&new_dpi, ir.left, ir.top, ir.Width(), ir.Height())) break; + AutoRestoreBackup dpi_backup(_cur_dpi, &new_dpi); DrawSprite(this->current_sprite, PAL_NONE, x, y, nullptr, ZOOM_LVL_GUI); - - _cur_dpi = old_dpi; - + if (this->crosshair) { + GfxDrawLine(x, 0, x, ir.Height() - 1, PC_WHITE, 1, 1); + GfxDrawLine(0, y, ir.Width() - 1, y, PC_WHITE, 1, 1); + } break; } @@ -902,11 +915,11 @@ struct SpriteAlignerWindow : Window { std::vector &list = _newgrf_debug_sprite_picker.sprites; int max = std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)list.size()); - int y = r.top + WD_FRAMERECT_TOP; + Rect ir = r.Shrink(WidgetDimensions::scaled.matrix); for (int i = this->vscroll->GetPosition(); i < max; i++) { SetDParam(0, list[i]); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); - y += step_size; + DrawString(ir, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE); + ir.top += step_size; } break; } @@ -994,6 +1007,18 @@ struct SpriteAlignerWindow : Window { this->offs_start_map.Erase(this->current_sprite); this->SetDirty(); break; + + case WID_SA_CENTRE: + SpriteAlignerWindow::centre = !SpriteAlignerWindow::centre; + this->SetWidgetLoweredState(widget, SpriteAlignerWindow::centre); + this->SetDirty(); + break; + + case WID_SA_CROSSHAIR: + SpriteAlignerWindow::crosshair = !SpriteAlignerWindow::crosshair; + this->SetWidgetLoweredState(widget, SpriteAlignerWindow::crosshair); + this->SetDirty(); + break; } } @@ -1030,6 +1055,9 @@ struct SpriteAlignerWindow : Window { } }; +bool SpriteAlignerWindow::centre = true; +bool SpriteAlignerWindow::crosshair = true; + static const NWidgetPart _nested_sprite_aligner_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), @@ -1047,34 +1075,34 @@ static const NWidgetPart _nested_sprite_aligner_widgets[] = { EndContainer(), NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10), NWidget(NWID_SPACER), SetFill(1, 1), - NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_UP), SetDataTip(SPR_ARROW_UP, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_UP), SetDataTip(SPR_ARROW_UP, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), SetMinimalSize(11, 11), NWidget(NWID_SPACER), SetFill(1, 1), EndContainer(), NWidget(NWID_HORIZONTAL_LTR), SetPIP(10, 5, 10), NWidget(NWID_VERTICAL), NWidget(NWID_SPACER), SetFill(1, 1), - NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_LEFT), SetDataTip(SPR_ARROW_LEFT, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_LEFT), SetDataTip(SPR_ARROW_LEFT, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), SetMinimalSize(11, 11), NWidget(NWID_SPACER), SetFill(1, 1), EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_BLUE, WID_SA_SPRITE), SetDataTip(STR_NULL, STR_SPRITE_ALIGNER_SPRITE_TOOLTIP), EndContainer(), NWidget(NWID_VERTICAL), NWidget(NWID_SPACER), SetFill(1, 1), - NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_RIGHT), SetDataTip(SPR_ARROW_RIGHT, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_RIGHT), SetDataTip(SPR_ARROW_RIGHT, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), SetMinimalSize(11, 11), NWidget(NWID_SPACER), SetFill(1, 1), EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10), NWidget(NWID_SPACER), SetFill(1, 1), - NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_SA_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SPRITE_ALIGNER_MOVE_TOOLTIP), SetResize(0, 0), SetMinimalSize(11, 11), NWidget(NWID_SPACER), SetFill(1, 1), EndContainer(), NWidget(WWT_LABEL, COLOUR_GREY, WID_SA_OFFSETS_ABS), SetDataTip(STR_SPRITE_ALIGNER_OFFSETS_ABS, STR_NULL), SetFill(1, 0), SetPadding(0, 10, 0, 10), NWidget(WWT_LABEL, COLOUR_GREY, WID_SA_OFFSETS_REL), SetDataTip(STR_SPRITE_ALIGNER_OFFSETS_REL, STR_NULL), SetFill(1, 0), SetPadding(0, 10, 0, 10), - NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10), - NWidget(NWID_SPACER), SetFill(1, 1), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_RESET_REL), SetDataTip(STR_SPRITE_ALIGNER_RESET_BUTTON, STR_SPRITE_ALIGNER_RESET_TOOLTIP), SetFill(0, 0), - NWidget(NWID_SPACER), SetFill(1, 1), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 5, 10), + NWidget(WWT_TEXTBTN_2, COLOUR_GREY, WID_SA_CENTRE), SetDataTip(STR_SPRITE_ALIGNER_CENTRE_OFFSET, STR_NULL), SetFill(1, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SA_RESET_REL), SetDataTip(STR_SPRITE_ALIGNER_RESET_BUTTON, STR_SPRITE_ALIGNER_RESET_TOOLTIP), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SA_CROSSHAIR), SetDataTip(STR_SPRITE_ALIGNER_CROSSHAIR, STR_NULL), SetFill(1, 0), EndContainer(), EndContainer(), NWidget(NWID_VERTICAL), SetPIP(10, 5, 10), diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 951c705ef27a7..7c4c78641f6cb 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -518,6 +518,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, { const Vehicle *w = v->Next(); + assert(w != nullptr); uint16 altitude = ClampToU16(v->z_pos - w->z_pos); // Aircraft height - shadow height byte airporttype = ATP_TTDP_LARGE; @@ -978,6 +979,8 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, case 0x92: return Clamp(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 0xFFFF); // Date of last service case 0x93: return GB(Clamp(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 0xFFFF), 8, 8); case 0xC4: return Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR; // Build year + case 0xC6: return Engine::Get(this->self_type)->grf_prop.local_id; + case 0xC7: return GB(Engine::Get(this->self_type)->grf_prop.local_id, 8, 8); case 0xDA: return INVALID_VEHICLE; // Next vehicle case 0xF2: return 0; // Cargo subtype } diff --git a/src/newgrf_engine.h b/src/newgrf_engine.h index eb6a51040e0e7..2b721ebcb1b7d 100644 --- a/src/newgrf_engine.h +++ b/src/newgrf_engine.h @@ -121,4 +121,6 @@ void CommitVehicleListOrderChanges(); EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id); +void FillNewGRFVehicleCache(const Vehicle *v); + #endif /* NEWGRF_ENGINE_H */ diff --git a/src/newgrf_generic.h b/src/newgrf_generic.h index 0d4c8c1411271..9837a3692c168 100644 --- a/src/newgrf_generic.h +++ b/src/newgrf_generic.h @@ -48,6 +48,7 @@ void ResetGenericCallbacks(); void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *group); uint16 GetAiPurchaseCallbackResult(uint8 feature, CargoID cargo_type, uint8 default_selection, IndustryType src_industry, IndustryType dst_industry, uint8 distance, AIConstructionEvent event, uint8 count, uint8 station_size, const GRFFile **file); +void AmbientSoundEffectCallback(TileIndex tile); /** Play an ambient sound effect for an empty tile. */ static inline void AmbientSoundEffect(TileIndex tile) @@ -55,7 +56,6 @@ static inline void AmbientSoundEffect(TileIndex tile) /* Only run callback if enabled. */ if (!HasGrfMiscBit(GMB_AMBIENT_SOUND_CALLBACK)) return; - extern void AmbientSoundEffectCallback(TileIndex tile); AmbientSoundEffectCallback(tile); } diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 1b7ab44f6cb27..bb671f1e2ab72 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -50,12 +50,13 @@ void ShowNewGRFError() /* Only show Fatal and Error level messages */ if (c->error == nullptr || (c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL && c->error->severity != STR_NEWGRF_ERROR_MSG_ERROR)) continue; - SetDParam (0, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING); - SetDParamStr(1, c->error->custom_message); - SetDParamStr(2, c->filename); - SetDParamStr(3, c->error->data); + SetDParamStr(0, c->GetName()); + SetDParam (1, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING); + SetDParamStr(2, c->error->custom_message); + SetDParamStr(3, c->filename); + SetDParamStr(4, c->error->data); for (uint i = 0; i < lengthof(c->error->param_value); i++) { - SetDParam(4 + i, c->error->param_value[i]); + SetDParam(5 + i, c->error->param_value[i]); } if (c->error->severity == STR_NEWGRF_ERROR_MSG_FATAL) { ShowErrorMessage(STR_NEWGRF_ERROR_FATAL_POPUP, INVALID_STRING_ID, WL_CRITICAL); @@ -66,8 +67,9 @@ void ShowNewGRFError() } } -static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint bottom, bool show_params) +static void ShowNewGRFInfo(const GRFConfig *c, const Rect &r, bool show_params) { + Rect tr = r.Shrink(WidgetDimensions::scaled.frametext); if (c->error != nullptr) { char message[512]; SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages @@ -79,34 +81,34 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint GetString(message, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message)); SetDParamStr(0, message); - y = DrawStringMultiLine(x, right, y, bottom, c->error->severity); + tr.top = DrawStringMultiLine(tr, c->error->severity); } /* Draw filename or not if it is not known (GRF sent over internet) */ if (c->filename != nullptr) { SetDParamStr(0, c->filename); - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_FILENAME); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_FILENAME); } /* Prepare and draw GRF ID */ char buff[256]; seprintf(buff, lastof(buff), "%08X", BSWAP32(c->ident.grfid)); SetDParamStr(0, buff); - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_GRF_ID); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_GRF_ID); if ((_settings_client.gui.newgrf_developer_tools || _settings_client.gui.newgrf_show_old_versions) && c->version != 0) { SetDParam(0, c->version); - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_VERSION); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_VERSION); } if ((_settings_client.gui.newgrf_developer_tools || _settings_client.gui.newgrf_show_old_versions) && c->min_loadable_version != 0) { SetDParam(0, c->min_loadable_version); - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_MIN_VERSION); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_MIN_VERSION); } /* Prepare and draw MD5 sum */ md5sumToString(buff, lastof(buff), c->ident.md5sum); SetDParamStr(0, buff); - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_MD5SUM); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_MD5SUM); /* Show GRF parameter list */ if (show_params) { @@ -117,7 +119,7 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint } else { SetDParam(0, STR_NEWGRF_SETTINGS_PARAMETER_NONE); } - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_PARAMETER); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_PARAMETER); /* Draw the palette of the NewGRF */ if (c->palette & GRFP_BLT_32BPP) { @@ -125,21 +127,21 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint } else { SetDParam(0, (c->palette & GRFP_USE_WINDOWS) ? STR_NEWGRF_SETTINGS_PALETTE_LEGACY : STR_NEWGRF_SETTINGS_PALETTE_DEFAULT); } - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_PALETTE); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_PALETTE); } /* Show flags */ - if (c->status == GCS_NOT_FOUND) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_NOT_FOUND); - if (c->status == GCS_DISABLED) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_DISABLED); - if (HasBit(c->flags, GCF_INVALID)) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_INCOMPATIBLE); - if (HasBit(c->flags, GCF_COMPATIBLE)) y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_COMPATIBLE_LOADED); + if (c->status == GCS_NOT_FOUND) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_NOT_FOUND); + if (c->status == GCS_DISABLED) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_DISABLED); + if (HasBit(c->flags, GCF_INVALID)) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_INCOMPATIBLE); + if (HasBit(c->flags, GCF_COMPATIBLE)) tr.top = DrawStringMultiLine(tr, STR_NEWGRF_COMPATIBLE_LOADED); /* Draw GRF info if it exists */ if (!StrEmpty(c->GetDescription())) { SetDParamStr(0, c->GetDescription()); - y = DrawStringMultiLine(x, right, y, bottom, STR_BLACK_RAW_STRING); + tr.top = DrawStringMultiLine(tr, STR_BLACK_RAW_STRING); } else { - y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_NO_INFO); + tr.top = DrawStringMultiLine(tr, STR_NEWGRF_SETTINGS_NO_INFO); } } @@ -212,7 +214,7 @@ struct NewGRFParametersWindow : public Window { } case WID_NP_BACKGROUND: - this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + padding.height; resize->width = 1; resize->height = this->line_height; @@ -221,14 +223,14 @@ struct NewGRFParametersWindow : public Window { case WID_NP_DESCRIPTION: /* Minimum size of 4 lines. The 500 is the default size of the window. */ - Dimension suggestion = {500 - WD_FRAMERECT_LEFT - WD_FRAMERECT_RIGHT, (uint)FONT_HEIGHT_NORMAL * 4 + WD_TEXTPANEL_TOP + WD_TEXTPANEL_BOTTOM}; + Dimension suggestion = {500U - WidgetDimensions::scaled.frametext.Horizontal(), (uint)FONT_HEIGHT_NORMAL * 4 + WidgetDimensions::scaled.frametext.Vertical()}; for (uint i = 0; i < this->grf_config->param_info.size(); i++) { const GRFParameterInfo *par_info = this->grf_config->param_info[i]; if (par_info == nullptr) continue; const char *desc = GetGRFStringFromGRFText(par_info->desc); if (desc == nullptr) continue; Dimension d = GetStringMultiLineBoundingBox(desc, suggestion); - d.height += WD_TEXTPANEL_TOP + WD_TEXTPANEL_BOTTOM; + d.height += WidgetDimensions::scaled.frametext.Vertical(); suggestion = maxdim(d, suggestion); } size->height = suggestion.height; @@ -252,18 +254,17 @@ struct NewGRFParametersWindow : public Window { if (par_info == nullptr) return; const char *desc = GetGRFStringFromGRFText(par_info->desc); if (desc == nullptr) return; - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_TEXTPANEL_TOP, r.bottom - WD_TEXTPANEL_BOTTOM, desc, TC_BLACK); + DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), desc, TC_BLACK); return; } else if (widget != WID_NP_BACKGROUND) { return; } + Rect ir = r.Shrink(WidgetDimensions::scaled.frametext, RectPadding::zero); bool rtl = _current_text_dir == TD_RTL; - uint buttons_left = rtl ? r.right - SETTING_BUTTON_WIDTH - 3 : r.left + 4; - uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8); - uint text_right = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT); + uint buttons_left = rtl ? ir.right - SETTING_BUTTON_WIDTH : ir.left; + Rect tr = ir.Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide, rtl); - int y = r.top; int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) { @@ -273,13 +274,13 @@ struct NewGRFParametersWindow : public Window { bool selected = (i == this->clicked_row); if (par_info->type == PTYPE_BOOL) { - DrawBoolButton(buttons_left, y + button_y_offset, current_value != 0, this->editable); + DrawBoolButton(buttons_left, ir.top + button_y_offset, current_value != 0, this->editable); SetDParam(2, par_info->GetValue(this->grf_config) == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON); } else if (par_info->type == PTYPE_UINT_ENUM) { if (par_info->complete_labels) { - DrawDropDownButton(buttons_left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && this->clicked_dropdown, this->editable); + DrawDropDownButton(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && this->clicked_dropdown, this->editable); } else { - DrawArrowButtons(buttons_left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, this->editable && current_value > par_info->min_value, this->editable && current_value < par_info->max_value); + DrawArrowButtons(buttons_left, ir.top + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, this->editable && current_value > par_info->min_value, this->editable && current_value < par_info->max_value); } SetDParam(2, STR_JUST_INT); SetDParam(3, current_value); @@ -301,8 +302,8 @@ struct NewGRFParametersWindow : public Window { SetDParam(1, i + 1); } - DrawString(text_left, text_right, y + text_y_offset, STR_NEWGRF_PARAMETERS_SETTING, selected ? TC_WHITE : TC_LIGHT_BLUE); - y += this->line_height; + DrawString(tr.left, tr.right, ir.top + text_y_offset, STR_NEWGRF_PARAMETERS_SETTING, selected ? TC_WHITE : TC_LIGHT_BLUE); + ir.top += this->line_height; } } @@ -347,10 +348,9 @@ struct NewGRFParametersWindow : public Window { this->clicked_dropdown = false; } - const NWidgetBase *wid = this->GetWidget(WID_NP_BACKGROUND); - int x = pt.x - wid->pos_x; - if (_current_text_dir == TD_RTL) x = wid->current_x - 1 - x; - x -= 4; + Rect r = this->GetWidget(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext, RectPadding::zero); + int x = pt.x - r.left; + if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x; GRFParameterInfo *par_info = (num < this->grf_config->param_info.size()) ? this->grf_config->param_info[num] : nullptr; if (par_info == nullptr) par_info = GetDummyParameterInfo(num); @@ -364,8 +364,7 @@ struct NewGRFParametersWindow : public Window { this->clicked_dropdown = false; this->closing_dropdown = false; } else { - const NWidgetBase *wid = this->GetWidget(WID_NP_BACKGROUND); - int rel_y = (pt.y - (int)wid->pos_y) % this->line_height; + int rel_y = (pt.y - r.top) % this->line_height; Rect wi_rect; wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);; @@ -730,26 +729,29 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { switch (widget) { case WID_NS_FILE_LIST: { - Dimension d = maxdim(GetSpriteSize(SPR_SQUARE), GetSpriteSize(SPR_WARNING_SIGN)); - resize->height = std::max(d.height + 2U, FONT_HEIGHT_NORMAL + 2U); - size->height = std::max(size->height, WD_FRAMERECT_TOP + 6 * resize->height + WD_FRAMERECT_BOTTOM); + Dimension d = maxdim(GetScaledSpriteSize(SPR_SQUARE), GetScaledSpriteSize(SPR_WARNING_SIGN)); + resize->height = std::max(d.height + 2U, FONT_HEIGHT_NORMAL); + size->height = std::max(size->height, padding.height + 6 * resize->height); break; } case WID_NS_AVAIL_LIST: - resize->height = std::max(12, FONT_HEIGHT_NORMAL + 2); - size->height = std::max(size->height, WD_FRAMERECT_TOP + 8 * resize->height + WD_FRAMERECT_BOTTOM); + { + Dimension d = maxdim(GetScaledSpriteSize(SPR_SQUARE), GetScaledSpriteSize(SPR_WARNING_SIGN)); + resize->height = std::max(d.height + 2U, FONT_HEIGHT_NORMAL); + size->height = std::max(size->height, padding.height + 8 * resize->height); break; + } case WID_NS_NEWGRF_INFO_TITLE: { Dimension dim = GetStringBoundingBox(STR_NEWGRF_SETTINGS_INFO_TITLE); - size->height = std::max(size->height, dim.height + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM); - size->width = std::max(size->width, dim.width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT); + size->height = std::max(size->height, dim.height + WidgetDimensions::scaled.frametext.Vertical()); + size->width = std::max(size->width, dim.width + WidgetDimensions::scaled.frametext.Horizontal()); break; } case WID_NS_NEWGRF_INFO: - size->height = std::max(size->height, WD_FRAMERECT_TOP + 10 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM + padding.height + 2); + size->height = std::max(size->height, WidgetDimensions::scaled.framerect.Vertical() + 10 * FONT_HEIGHT_NORMAL); break; case WID_NS_PRESET_LIST: { @@ -833,10 +835,11 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { { switch (widget) { case WID_NS_FILE_LIST: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); + const Rect br = r.Shrink(WidgetDimensions::scaled.bevel); + GfxFillRect(br, PC_BLACK); + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); uint step_height = this->GetWidget(WID_NS_FILE_LIST)->resize_y; - uint y = r.top + WD_FRAMERECT_TOP; Dimension square = GetSpriteSize(SPR_SQUARE); Dimension warning = GetSpriteSize(SPR_WARNING_SIGN); int square_offset_y = (step_height - square.height) / 2; @@ -844,10 +847,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; bool rtl = _current_text_dir == TD_RTL; - uint text_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.left + square.width + 15; - uint text_right = rtl ? r.right - square.width - 15 : r.right - WD_FRAMERECT_RIGHT; - uint square_left = rtl ? r.right - square.width - 5 : r.left + 5; - uint warning_left = rtl ? r.right - square.width - warning.width - 10 : r.left + square.width + 10; + uint text_left = rtl ? tr.left : tr.left + square.width + 13; + uint text_right = rtl ? tr.right - square.width - 13 : tr.right; + uint square_left = rtl ? tr.right - square.width - 3 : tr.left + 3; + uint warning_left = rtl ? tr.right - square.width - warning.width - 8 : tr.left + square.width + 8; int i = 0; for (const GRFConfig *c = this->actives; c != nullptr; c = c->next, i++) { @@ -857,35 +860,36 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { PaletteID pal = this->GetPalette(c); if (h) { - GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 1, PC_DARK_BLUE); + GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE); } else if (i == this->active_over) { /* Get index of current selection. */ int active_sel_pos = 0; for (GRFConfig *c = this->actives; c != nullptr && c != this->active_sel; c = c->next, active_sel_pos++) {} if (active_sel_pos != this->active_over) { - uint top = this->active_over < active_sel_pos ? y + 1 : y + step_height - 2; - GfxFillRect(r.left + WD_FRAMERECT_LEFT, top - 1, r.right - WD_FRAMERECT_RIGHT, top + 1, PC_GREY); + uint top = this->active_over < active_sel_pos ? tr.top + 1 : tr.top + step_height - 2; + GfxFillRect(tr.left, top - 1, tr.right, top + 1, PC_GREY); } } - DrawSprite(SPR_SQUARE, pal, square_left, y + square_offset_y); - if (c->error != nullptr) DrawSprite(SPR_WARNING_SIGN, 0, warning_left, y + warning_offset_y); + DrawSprite(SPR_SQUARE, pal, square_left, tr.top + square_offset_y); + if (c->error != nullptr) DrawSprite(SPR_WARNING_SIGN, 0, warning_left, tr.top + warning_offset_y); uint txtoffset = c->error == nullptr ? 0 : warning.width; - DrawString(text_left + (rtl ? 0 : txtoffset), text_right - (rtl ? txtoffset : 0), y + offset_y, text, h ? TC_WHITE : TC_ORANGE); - y += step_height; + DrawString(text_left + (rtl ? 0 : txtoffset), text_right - (rtl ? txtoffset : 0), tr.top + offset_y, text, h ? TC_WHITE : TC_ORANGE); + tr.top += step_height; } } if (i == this->active_over && this->vscroll->IsVisible(i)) { // Highlight is after the last GRF entry. - GfxFillRect(r.left + WD_FRAMERECT_LEFT, y, r.right - WD_FRAMERECT_RIGHT, y + 2, PC_GREY); + GfxFillRect(tr.left, tr.top, tr.right, tr.top + 2, PC_GREY); } break; } case WID_NS_AVAIL_LIST: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, this->active_over == -2 ? PC_DARK_GREY : PC_BLACK); + const Rect br = r.Shrink(WidgetDimensions::scaled.bevel); + GfxFillRect(br, this->active_over == -2 ? PC_DARK_GREY : PC_BLACK); + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); uint step_height = this->GetWidget(WID_NS_AVAIL_LIST)->resize_y; int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; - uint y = r.top + WD_FRAMERECT_TOP; uint min_index = this->vscroll2->GetPosition(); uint max_index = std::min(min_index + this->vscroll2->GetCapacity(), (uint)this->avails.size()); @@ -894,24 +898,25 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { bool h = (c == this->avail_sel); const char *text = c->GetName(); - if (h) GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 1, PC_DARK_BLUE); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y + offset_y, text, h ? TC_WHITE : TC_SILVER); - y += step_height; + if (h) GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE); + DrawString(tr.left, tr.right, tr.top + offset_y, text, h ? TC_WHITE : TC_SILVER); + tr.top += step_height; } break; } - case WID_NS_NEWGRF_INFO_TITLE: + case WID_NS_NEWGRF_INFO_TITLE: { /* Create the nice grayish rectangle at the details top. */ - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_DARK_BLUE); - DrawString(r.left, r.right, (r.top + r.bottom - FONT_HEIGHT_NORMAL) / 2, STR_NEWGRF_SETTINGS_INFO_TITLE, TC_FROMSTRING, SA_HOR_CENTER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), PC_DARK_BLUE); + DrawString(r.left, r.right, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), STR_NEWGRF_SETTINGS_INFO_TITLE, TC_FROMSTRING, SA_HOR_CENTER); break; + } case WID_NS_NEWGRF_INFO: { const GRFConfig *selected = this->active_sel; if (selected == nullptr) selected = this->avail_sel; if (selected != nullptr) { - ShowNewGRFInfo(selected, r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, r.right - WD_FRAMERECT_RIGHT, r.bottom - WD_FRAMERECT_BOTTOM, this->show_params); + ShowNewGRFInfo(selected, r, this->show_params); } break; } @@ -946,7 +951,6 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case WID_NS_OPEN_URL: { const GRFConfig *c = (this->avail_sel == nullptr) ? this->active_sel : this->avail_sel; - extern void OpenBrowser(const char *url); OpenBrowser(c->GetURL()); break; } @@ -1281,16 +1285,16 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { WIDGET_LIST_END ); - const GRFConfig *c = (this->avail_sel == nullptr) ? this->active_sel : this->avail_sel; + const GRFConfig *selected_config = (this->avail_sel == nullptr) ? this->active_sel : this->avail_sel; for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) { - this->SetWidgetDisabledState(WID_NS_NEWGRF_TEXTFILE + tft, c == nullptr || c->GetTextfile(tft) == nullptr); + this->SetWidgetDisabledState(WID_NS_NEWGRF_TEXTFILE + tft, selected_config == nullptr || selected_config->GetTextfile(tft) == nullptr); } - this->SetWidgetDisabledState(WID_NS_OPEN_URL, c == nullptr || StrEmpty(c->GetURL())); + this->SetWidgetDisabledState(WID_NS_OPEN_URL, selected_config == nullptr || StrEmpty(selected_config->GetURL())); this->SetWidgetDisabledState(WID_NS_SET_PARAMETERS, !this->show_params || this->active_sel == nullptr || this->active_sel->num_valid_params == 0); this->SetWidgetDisabledState(WID_NS_VIEW_PARAMETERS, !this->show_params || this->active_sel == nullptr || this->active_sel->num_valid_params == 0); this->SetWidgetDisabledState(WID_NS_TOGGLE_PALETTE, disable_all || - (!(_settings_client.gui.newgrf_developer_tools || _settings_client.gui.scenario_developer) && ((c->palette & GRFP_GRF_MASK) != GRFP_GRF_UNSET))); + (!(_settings_client.gui.newgrf_developer_tools || _settings_client.gui.scenario_developer) && ((selected_config->palette & GRFP_GRF_MASK) != GRFP_GRF_UNSET))); if (!disable_all) { /* All widgets are now enabled, so disable widgets we can't use */ @@ -1460,6 +1464,9 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { this->avails.push_back(c); } else { const GRFConfig *best = FindGRFConfig(c->ident.grfid, HasBit(c->flags, GCF_INVALID) ? FGCM_NEWEST : FGCM_NEWEST_VALID); + /* Never triggers; FindGRFConfig returns either c, or a newer version of c. */ + assert(best != nullptr); + /* * If the best version is 0, then all NewGRF with this GRF ID * have version 0, so for backward compatibility reasons we @@ -1611,13 +1618,13 @@ class NWidgetNewGRFDisplay : public NWidgetContainer { this->acs->SetupSmallestSize(w, init_array); this->inf->SetupSmallestSize(w, init_array); - uint min_avs_width = this->avs->smallest_x + this->avs->padding_left + this->avs->padding_right; - uint min_acs_width = this->acs->smallest_x + this->acs->padding_left + this->acs->padding_right; - uint min_inf_width = this->inf->smallest_x + this->inf->padding_left + this->inf->padding_right; + uint min_avs_width = this->avs->smallest_x + this->avs->padding.Horizontal(); + uint min_acs_width = this->acs->smallest_x + this->acs->padding.Horizontal(); + uint min_inf_width = this->inf->smallest_x + this->inf->padding.Horizontal(); - uint min_avs_height = this->avs->smallest_y + this->avs->padding_top + this->avs->padding_bottom; - uint min_acs_height = this->acs->smallest_y + this->acs->padding_top + this->acs->padding_bottom; - uint min_inf_height = this->inf->smallest_y + this->inf->padding_top + this->inf->padding_bottom; + uint min_avs_height = this->avs->smallest_y + this->avs->padding.Vertical(); + uint min_acs_height = this->acs->smallest_y + this->acs->padding.Vertical(); + uint min_inf_height = this->inf->smallest_y + this->inf->padding.Vertical(); /* Smallest window is in two column mode. */ this->smallest_x = std::max(min_avs_width, min_acs_width) + INTER_COLUMN_SPACING + min_inf_width; @@ -1647,9 +1654,9 @@ class NWidgetNewGRFDisplay : public NWidgetContainer { { this->StoreSizePosition(sizing, x, y, given_width, given_height); - uint min_avs_width = this->avs->smallest_x + this->avs->padding_left + this->avs->padding_right; - uint min_acs_width = this->acs->smallest_x + this->acs->padding_left + this->acs->padding_right; - uint min_inf_width = this->inf->smallest_x + this->inf->padding_left + this->inf->padding_right; + uint min_avs_width = this->avs->smallest_x + this->avs->padding.Horizontal(); + uint min_acs_width = this->acs->smallest_x + this->acs->padding.Horizontal(); + uint min_inf_width = this->inf->smallest_x + this->inf->padding.Horizontal(); uint min_list_width = std::max(min_avs_width, min_acs_width); // Smallest width of the lists such that they have equal width (incl padding). uint avs_extra_width = min_list_width - min_avs_width; // Additional width needed for avs to reach min_list_width. @@ -1685,10 +1692,10 @@ class NWidgetNewGRFDisplay : public NWidgetContainer { avs_width = ComputeMaxSize(this->avs->smallest_x, this->avs->smallest_x + avs_width, this->avs->GetHorizontalStepSize(sizing)); uint acs_width = given_width - // Remaining space, including horizontal padding. - inf_width - this->inf->padding_left - this->inf->padding_right - - avs_width - this->avs->padding_left - this->avs->padding_right - 2 * INTER_COLUMN_SPACING; + inf_width - this->inf->padding.Horizontal() - + avs_width - this->avs->padding.Horizontal() - 2 * INTER_COLUMN_SPACING; acs_width = ComputeMaxSize(min_acs_width, acs_width, this->acs->GetHorizontalStepSize(sizing)) - - this->acs->padding_left - this->acs->padding_right; + this->acs->padding.Horizontal(); /* Never use fill_y on these; the minimal size is chosen, so that the 3 column view looks nice */ uint avs_height = ComputeMaxSize(this->avs->smallest_y, given_height, this->avs->resize_y); @@ -1696,25 +1703,25 @@ class NWidgetNewGRFDisplay : public NWidgetContainer { /* Assign size and position to the children. */ if (rtl) { - x += this->inf->padding_left; - this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); - x += inf_width + this->inf->padding_right + INTER_COLUMN_SPACING; + x += this->inf->padding.left; + this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl); + x += inf_width + this->inf->padding.right + INTER_COLUMN_SPACING; } else { - x += this->avs->padding_left; - this->avs->AssignSizePosition(sizing, x, y + this->avs->padding_top, avs_width, avs_height, rtl); - x += avs_width + this->avs->padding_right + INTER_COLUMN_SPACING; + x += this->avs->padding.left; + this->avs->AssignSizePosition(sizing, x, y + this->avs->padding.top, avs_width, avs_height, rtl); + x += avs_width + this->avs->padding.right + INTER_COLUMN_SPACING; } - x += this->acs->padding_left; - this->acs->AssignSizePosition(sizing, x, y + this->acs->padding_top, acs_width, acs_height, rtl); - x += acs_width + this->acs->padding_right + INTER_COLUMN_SPACING; + x += this->acs->padding.left; + this->acs->AssignSizePosition(sizing, x, y + this->acs->padding.top, acs_width, acs_height, rtl); + x += acs_width + this->acs->padding.right + INTER_COLUMN_SPACING; if (rtl) { - x += this->avs->padding_left; - this->avs->AssignSizePosition(sizing, x, y + this->avs->padding_top, avs_width, avs_height, rtl); + x += this->avs->padding.left; + this->avs->AssignSizePosition(sizing, x, y + this->avs->padding.top, avs_width, avs_height, rtl); } else { - x += this->inf->padding_left; - this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); + x += this->inf->padding.left; + this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl); } } else { /* Two columns, all space in extra_width goes to both lists. Since the lists are underneath each other, @@ -1724,8 +1731,8 @@ class NWidgetNewGRFDisplay : public NWidgetContainer { uint acs_width = ComputeMaxSize(this->acs->smallest_x, this->acs->smallest_x + acs_extra_width + extra_width, this->acs->GetHorizontalStepSize(sizing)); - uint min_avs_height = (!this->editable) ? 0 : this->avs->smallest_y + this->avs->padding_top + this->avs->padding_bottom + INTER_LIST_SPACING; - uint min_acs_height = this->acs->smallest_y + this->acs->padding_top + this->acs->padding_bottom; + uint min_avs_height = (!this->editable) ? 0 : this->avs->smallest_y + this->avs->padding.Vertical() + INTER_LIST_SPACING; + uint min_acs_height = this->acs->smallest_y + this->acs->padding.Vertical(); uint extra_height = given_height - min_acs_height - min_avs_height; /* Never use fill_y on these; instead use the INTER_LIST_SPACING as filler */ @@ -1735,29 +1742,29 @@ class NWidgetNewGRFDisplay : public NWidgetContainer { /* Assign size and position to the children. */ if (rtl) { - x += this->inf->padding_left; - this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); - x += inf_width + this->inf->padding_right + INTER_COLUMN_SPACING; + x += this->inf->padding.left; + this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl); + x += inf_width + this->inf->padding.right + INTER_COLUMN_SPACING; - this->acs->AssignSizePosition(sizing, x + this->acs->padding_left, y + this->acs->padding_top, acs_width, acs_height, rtl); + this->acs->AssignSizePosition(sizing, x + this->acs->padding.left, y + this->acs->padding.top, acs_width, acs_height, rtl); if (this->editable) { - this->avs->AssignSizePosition(sizing, x + this->avs->padding_left, y + given_height - avs_height - this->avs->padding_bottom, avs_width, avs_height, rtl); + this->avs->AssignSizePosition(sizing, x + this->avs->padding.left, y + given_height - avs_height - this->avs->padding.bottom, avs_width, avs_height, rtl); } else { this->avs->AssignSizePosition(sizing, 0, 0, this->avs->smallest_x, this->avs->smallest_y, rtl); } } else { - this->acs->AssignSizePosition(sizing, x + this->acs->padding_left, y + this->acs->padding_top, acs_width, acs_height, rtl); + this->acs->AssignSizePosition(sizing, x + this->acs->padding.left, y + this->acs->padding.top, acs_width, acs_height, rtl); if (this->editable) { - this->avs->AssignSizePosition(sizing, x + this->avs->padding_left, y + given_height - avs_height - this->avs->padding_bottom, avs_width, avs_height, rtl); + this->avs->AssignSizePosition(sizing, x + this->avs->padding.left, y + given_height - avs_height - this->avs->padding.bottom, avs_width, avs_height, rtl); } else { this->avs->AssignSizePosition(sizing, 0, 0, this->avs->smallest_x, this->avs->smallest_y, rtl); } - uint dx = this->acs->current_x + this->acs->padding_left + this->acs->padding_right; + uint dx = this->acs->current_x + this->acs->padding.Horizontal(); if (this->editable) { - dx = std::max(dx, this->avs->current_x + this->avs->padding_left + this->avs->padding_right); + dx = std::max(dx, this->avs->current_x + this->avs->padding.Horizontal()); } - x += dx + INTER_COLUMN_SPACING + this->inf->padding_left; - this->inf->AssignSizePosition(sizing, x, y + this->inf->padding_top, inf_width, inf_height, rtl); + x += dx + INTER_COLUMN_SPACING + this->inf->padding.left; + this->inf->AssignSizePosition(sizing, x, y + this->inf->padding.top, inf_width, inf_height, rtl); } } } @@ -1780,8 +1787,8 @@ class NWidgetNewGRFDisplay : public NWidgetContainer { } }; -const uint NWidgetNewGRFDisplay::INTER_LIST_SPACING = WD_RESIZEBOX_WIDTH + 1; -const uint NWidgetNewGRFDisplay::INTER_COLUMN_SPACING = WD_RESIZEBOX_WIDTH; +const uint NWidgetNewGRFDisplay::INTER_COLUMN_SPACING = 12; +const uint NWidgetNewGRFDisplay::INTER_LIST_SPACING = NWidgetNewGRFDisplay::INTER_COLUMN_SPACING + 1; const uint NWidgetNewGRFDisplay::MAX_EXTRA_INFO_WIDTH = 150; const uint NWidgetNewGRFDisplay::MIN_EXTRA_FOR_3_COLUMNS = 50; @@ -1789,7 +1796,7 @@ static const NWidgetPart _nested_newgrf_actives_widgets[] = { /* Left side, presets. */ NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXT, COLOUR_MAUVE), SetDataTip(STR_NEWGRF_SETTINGS_SELECT_PRESET, STR_NULL), - SetPadding(0, WD_FRAMETEXT_RIGHT, 0, 0), + SetPadding(0, WidgetDimensions::unscaled.frametext.right, 0, 0), NWidget(WWT_DROPDOWN, COLOUR_YELLOW, WID_NS_PRESET_LIST), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_JUST_STRING, STR_NEWGRF_SETTINGS_PRESET_LIST_TOOLTIP), EndContainer(), @@ -1800,10 +1807,10 @@ static const NWidgetPart _nested_newgrf_actives_widgets[] = { SetDataTip(STR_NEWGRF_SETTINGS_PRESET_DELETE, STR_NEWGRF_SETTINGS_PRESET_DELETE_TOOLTIP), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, WD_RESIZEBOX_WIDTH), SetResize(1, 0), SetFill(1, 0), + NWidget(NWID_SPACER), SetMinimalSize(0, NWidgetNewGRFDisplay::INTER_COLUMN_SPACING), SetResize(1, 0), SetFill(1, 0), NWidget(WWT_PANEL, COLOUR_MAUVE), NWidget(WWT_LABEL, COLOUR_MAUVE), SetDataTip(STR_NEWGRF_SETTINGS_ACTIVE_LIST, STR_NULL), - SetFill(1, 0), SetResize(1, 0), SetPadding(3, WD_FRAMETEXT_RIGHT, 0, WD_FRAMETEXT_LEFT), + SetFill(1, 0), SetResize(1, 0), SetPadding(3, WidgetDimensions::unscaled.frametext.right, 0, WidgetDimensions::unscaled.frametext.left), /* Left side, active grfs. */ NWidget(NWID_HORIZONTAL), SetPadding(0, 2, 0, 2), NWidget(WWT_PANEL, COLOUR_MAUVE), @@ -1815,7 +1822,7 @@ static const NWidgetPart _nested_newgrf_actives_widgets[] = { EndContainer(), /* Buttons. */ NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NS_SHOW_REMOVE), - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPadding(2, 2, 2, 2), SetPIP(0, WD_RESIZEBOX_WIDTH, 0), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPadding(2, 2, 2, 2), SetPIP(0, NWidgetNewGRFDisplay::INTER_COLUMN_SPACING, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_REMOVE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_NEWGRF_SETTINGS_REMOVE, STR_NEWGRF_SETTINGS_REMOVE_TOOLTIP), NWidget(NWID_VERTICAL), @@ -1841,10 +1848,10 @@ static const NWidgetPart _nested_newgrf_actives_widgets[] = { static const NWidgetPart _nested_newgrf_availables_widgets[] = { NWidget(WWT_PANEL, COLOUR_MAUVE), NWidget(WWT_LABEL, COLOUR_MAUVE), SetDataTip(STR_NEWGRF_SETTINGS_INACTIVE_LIST, STR_NULL), - SetFill(1, 0), SetResize(1, 0), SetPadding(3, WD_FRAMETEXT_RIGHT, 0, WD_FRAMETEXT_LEFT), + SetFill(1, 0), SetResize(1, 0), SetPadding(3, WidgetDimensions::unscaled.frametext.right, 0, WidgetDimensions::unscaled.frametext.left), /* Left side, available grfs, filter edit box. */ - NWidget(NWID_HORIZONTAL), SetPadding(WD_TEXTPANEL_TOP, 0, WD_TEXTPANEL_BOTTOM, 0), - SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_RIGHT), + NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.frametext.top, 0, WidgetDimensions::unscaled.frametext.bottom, 0), + SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, WidgetDimensions::unscaled.frametext.right), NWidget(WWT_TEXT, COLOUR_MAUVE), SetFill(0, 1), SetDataTip(STR_NEWGRF_FILTER_TITLE, STR_NULL), NWidget(WWT_EDITBOX, COLOUR_MAUVE, WID_NS_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), @@ -1859,7 +1866,7 @@ static const NWidgetPart _nested_newgrf_availables_widgets[] = { NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_NS_SCROLL2BAR), EndContainer(), /* Left side, available grfs, buttons. */ - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPadding(2, 2, 2, 2), SetPIP(0, WD_RESIZEBOX_WIDTH, 0), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPadding(2, 2, 2, 2), SetPIP(0, NWidgetNewGRFDisplay::INTER_COLUMN_SPACING, 0), NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_ADD), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_NEWGRF_SETTINGS_ADD, STR_NEWGRF_SETTINGS_ADD_FILE_TOOLTIP), NWidget(NWID_VERTICAL), @@ -1892,7 +1899,7 @@ static const NWidgetPart _nested_newgrf_infopanel_widgets[] = { EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_NS_SHOW_APPLY), /* Right side, buttons. */ - NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, WD_RESIZEBOX_WIDTH, 0), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(0, NWidgetNewGRFDisplay::INTER_COLUMN_SPACING, 0), NWidget(NWID_VERTICAL), NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_NS_SET_PARAMETERS), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_NEWGRF_SETTINGS_SET_PARAMETERS, STR_NULL), @@ -1930,7 +1937,7 @@ static const NWidgetPart _nested_newgrf_widgets[] = { NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE), EndContainer(), NWidget(WWT_PANEL, COLOUR_MAUVE), - NWidgetFunction(NewGRFDisplay), SetPadding(WD_RESIZEBOX_WIDTH, WD_RESIZEBOX_WIDTH, 2, WD_RESIZEBOX_WIDTH), + NWidgetFunction(NewGRFDisplay), SetPadding(NWidgetNewGRFDisplay::INTER_COLUMN_SPACING, NWidgetNewGRFDisplay::INTER_COLUMN_SPACING, 2, NWidgetNewGRFDisplay::INTER_COLUMN_SPACING), /* Resize button. */ NWidget(NWID_HORIZONTAL), NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0), @@ -2007,11 +2014,13 @@ static const NWidgetPart _nested_save_preset_widgets[] = { EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY), NWidget(NWID_HORIZONTAL), - NWidget(WWT_INSET, COLOUR_GREY, WID_SVP_PRESET_LIST), SetPadding(2, 1, 0, 2), + NWidget(WWT_INSET, COLOUR_GREY, WID_SVP_PRESET_LIST), SetPadding(2, 1, 2, 2), SetDataTip(0x0, STR_SAVE_PRESET_LIST_TOOLTIP), SetResize(1, 10), SetScrollbar(WID_SVP_SCROLLBAR), EndContainer(), NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SVP_SCROLLBAR), EndContainer(), - NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SVP_EDITBOX), SetPadding(3, 2, 2, 2), SetFill(1, 0), SetResize(1, 0), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SVP_EDITBOX), SetPadding(2, 2, 2, 2), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_SAVE_PRESET_TITLE, STR_SAVE_PRESET_EDITBOX_TOOLTIP), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -2074,14 +2083,14 @@ struct SavePresetWindow : public Window { { switch (widget) { case WID_SVP_PRESET_LIST: { - resize->height = FONT_HEIGHT_NORMAL + 2U; + resize->height = FONT_HEIGHT_NORMAL; size->height = 0; for (uint i = 0; i < this->presets.size(); i++) { Dimension d = GetStringBoundingBox(this->presets[i].c_str()); - size->width = std::max(size->width, d.width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT); + size->width = std::max(size->width, d.width + padding.width); resize->height = std::max(resize->height, d.height); } - size->height = ClampU((uint)this->presets.size(), 5, 20) * resize->height + 1; + size->height = ClampU((uint)this->presets.size(), 5, 20) * resize->height + padding.height; break; } } @@ -2091,20 +2100,21 @@ struct SavePresetWindow : public Window { { switch (widget) { case WID_SVP_PRESET_LIST: { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK); + const Rect br = r.Shrink(WidgetDimensions::scaled.bevel); + GfxFillRect(br, PC_BLACK); uint step_height = this->GetWidget(WID_SVP_PRESET_LIST)->resize_y; int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; - uint y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); uint min_index = this->vscroll->GetPosition(); uint max_index = std::min(min_index + this->vscroll->GetCapacity(), (uint)this->presets.size()); for (uint i = min_index; i < max_index; i++) { - if ((int)i == this->selected) GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 2, PC_DARK_BLUE); + if ((int)i == this->selected) GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE); const char *text = this->presets[i].c_str(); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right, y + offset_y, text, ((int)i == this->selected) ? TC_WHITE : TC_SILVER); - y += step_height; + DrawString(tr.left, tr.right, tr.top + offset_y, text, ((int)i == this->selected) ? TC_WHITE : TC_SILVER); + tr.top += step_height; } break; } @@ -2158,12 +2168,10 @@ static void ShowSavePresetWindow(const char *initial_text) static const NWidgetPart _nested_scan_progress_widgets[] = { NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_NEWGRF_SCAN_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_PANEL, COLOUR_GREY), - NWidget(NWID_HORIZONTAL), SetPIP(20, 0, 20), - NWidget(NWID_VERTICAL), SetPIP(11, 8, 11), - NWidget(WWT_LABEL, INVALID_COLOUR), SetDataTip(STR_NEWGRF_SCAN_MESSAGE, STR_NULL), SetFill(1, 0), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SP_PROGRESS_BAR), SetFill(1, 0), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SP_PROGRESS_TEXT), SetFill(1, 0), - EndContainer(), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup), + NWidget(WWT_LABEL, INVALID_COLOUR), SetDataTip(STR_NEWGRF_SCAN_MESSAGE, STR_NULL), SetFill(1, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SP_PROGRESS_BAR), SetFill(1, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SP_PROGRESS_TEXT), SetFill(1, 0), SetMinimalSize(400, 0), EndContainer(), EndContainer(), }; @@ -2200,8 +2208,8 @@ struct ScanProgressWindow : public Window { SetDParamMaxValue(0, 100); *size = GetStringBoundingBox(STR_GENERATION_PROGRESS); /* We need some spacing for the 'border' */ - size->height += 8; - size->width += 8; + size->height += WidgetDimensions::scaled.frametext.Horizontal(); + size->width += WidgetDimensions::scaled.frametext.Vertical(); break; } @@ -2210,8 +2218,8 @@ struct ScanProgressWindow : public Window { SetDParamMaxDigits(1, 4); /* We really don't know the width. We could determine it by scanning the NewGRFs, * but this is the status window for scanning them... */ - size->width = std::max(400U, GetStringBoundingBox(STR_NEWGRF_SCAN_STATUS).width); - size->height = FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL; + size->width = std::max(size->width, GetStringBoundingBox(STR_NEWGRF_SCAN_STATUS).width); + size->height = FONT_HEIGHT_NORMAL * 2 + WidgetDimensions::scaled.vsep_normal; break; } } @@ -2221,11 +2229,12 @@ struct ScanProgressWindow : public Window { switch (widget) { case WID_SP_PROGRESS_BAR: { /* Draw the % complete with a bar and a text */ - DrawFrameRect(r.left, r.top, r.right, r.bottom, COLOUR_GREY, FR_BORDERONLY); + DrawFrameRect(r, COLOUR_GREY, FR_BORDERONLY | FR_LOWERED); + Rect ir = r.Shrink(WidgetDimensions::scaled.bevel); uint percent = scanned * 100 / std::max(1U, _settings_client.gui.last_newgrf_count); - DrawFrameRect(r.left + 1, r.top + 1, (int)((r.right - r.left - 2) * percent / 100) + r.left + 1, r.bottom - 1, COLOUR_MAUVE, FR_NONE); + DrawFrameRect(ir.WithWidth(ir.Width() * percent / 100, false), COLOUR_MAUVE, FR_NONE); SetDParam(0, percent); - DrawString(r.left, r.right, r.top + 5, STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(ir.left, ir.right, CenterBounds(ir.top, ir.bottom, FONT_HEIGHT_NORMAL), STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER); break; } @@ -2234,7 +2243,7 @@ struct ScanProgressWindow : public Window { SetDParam(1, _settings_client.gui.last_newgrf_count); DrawString(r.left, r.right, r.top, STR_NEWGRF_SCAN_STATUS, TC_FROMSTRING, SA_HOR_CENTER); - DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL, this->last_name == nullptr ? "" : this->last_name, TC_BLACK, SA_HOR_CENTER); + DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal, this->last_name == nullptr ? "" : this->last_name, TC_BLACK, SA_HOR_CENTER); break; } } diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index 6a7d191f72da7..53ff4b8f7234b 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -346,7 +346,7 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI /* Extract tile offset. */ int8 x_offs = GB(GetRegister(0x100), 0, 8); int8 y_offs = GB(GetRegister(0x100), 8, 8); - TileIndex testtile = TILE_MASK(this->tile + TileDiffXY(x_offs, y_offs)); + TileIndex testtile = Map::WrapToMap(this->tile + TileDiffXY(x_offs, y_offs)); StationFinder stations(TileArea(testtile, 1, 1)); const StationList *sl = stations.GetStations(); @@ -480,7 +480,7 @@ uint16 GetSimpleHouseCallback(CallbackID callback, uint32 param1, uint32 param2, } /** Helper class for animation control. */ -struct HouseAnimationBase : public AnimationBase { +struct HouseAnimationBase : public AnimationBase > { static const CallbackID cb_animation_speed = CBID_HOUSE_ANIMATION_SPEED; static const CallbackID cb_animation_next_frame = CBID_HOUSE_ANIMATION_NEXT_FRAME; diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 6d8601192f230..72241fb120736 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -257,7 +257,7 @@ uint16 GetSimpleIndustryCallback(CallbackID callback, uint32 param1, uint32 para } /** Helper class for animation control. */ -struct IndustryAnimationBase : public AnimationBase { +struct IndustryAnimationBase : public AnimationBase > { static const CallbackID cb_animation_speed = CBID_INDTILE_ANIMATION_SPEED; static const CallbackID cb_animation_next_frame = CBID_INDTILE_ANIM_NEXT_FRAME; diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index e69787c0ce94d..ccd46e2e92725 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -58,7 +58,7 @@ ObjectSpec _object_specs[NUM_OBJECTS]; */ bool ObjectSpec::IsEverAvailable() const { - return this->enabled && HasBit(this->climate, _settings_game.game_creation.landscape) && + return this->IsEnabled() && HasBit(this->climate, _settings_game.game_creation.landscape) && (this->flags & ((_game_mode != GM_EDITOR && !_generating_world) ? OBJECT_FLAG_ONLY_IN_SCENEDIT : OBJECT_FLAG_ONLY_IN_GAME)) == 0; } @@ -510,7 +510,7 @@ uint16 StubGetObjectCallback(CallbackID callback, uint32 param1, uint32 param2, } /** Helper class for animation control. */ -struct ObjectAnimationBase : public AnimationBase { +struct ObjectAnimationBase : public AnimationBase > { static const CallbackID cb_animation_speed = CBID_OBJECT_ANIMATION_SPEED; static const CallbackID cb_animation_next_frame = CBID_OBJECT_ANIMATION_NEXT_FRAME; diff --git a/src/newgrf_object.h b/src/newgrf_object.h index 1776b760ab1a1..a441d3ceec4bc 100644 --- a/src/newgrf_object.h +++ b/src/newgrf_object.h @@ -21,7 +21,7 @@ #include "newgrf_commons.h" /** Various object behaviours. */ -enum ObjectFlags { +enum ObjectFlags : uint16 { OBJECT_FLAG_NONE = 0, ///< Just nothing. OBJECT_FLAG_ONLY_IN_SCENEDIT = 1 << 0, ///< Object can only be constructed in the scenario editor. OBJECT_FLAG_CANNOT_REMOVE = 1 << 1, ///< Object can not be removed. @@ -40,10 +40,12 @@ enum ObjectFlags { }; DECLARE_ENUM_AS_BIT_SET(ObjectFlags) +static const uint8 OBJECT_SIZE_1X1 = 0x11; ///< The value of a NewGRF's size property when the object is 1x1 tiles: low nibble for X, high nibble for Y. + void ResetObjects(); /** Class IDs for objects. */ -enum ObjectClassID { +enum ObjectClassID : uint8 { OBJECT_CLASS_BEGIN = 0, ///< The lowest valid value OBJECT_CLASS_MAX = 0xFF, ///< Maximum number of classes. INVALID_OBJECT_CLASS = 0xFF, ///< Class for the less fortunate. @@ -58,6 +60,7 @@ DECLARE_POSTFIX_INCREMENT(ObjectClassID) struct ObjectSpec { /* 2 because of the "normal" and "buy" sprite stacks. */ GRFFilePropsBase<2> grf_prop; ///< Properties related the the grf file + AnimationInfo animation; ///< Information about the animation. ObjectClassID cls_id; ///< The class to which this spec belongs. StringID name; ///< The name for this object. @@ -68,12 +71,16 @@ struct ObjectSpec { Date introduction_date; ///< From when can this object be built. Date end_of_life_date; ///< When can't this object be built anymore. ObjectFlags flags; ///< Flags/settings related to the object. - AnimationInfo animation; ///< Information about the animation. uint16 callback_mask; ///< Bitmask of requested/allowed callbacks. uint8 height; ///< The height of this structure, in heightlevels; max MAX_TILE_HEIGHT. uint8 views; ///< The number of views. uint8 generate_amount; ///< Number of objects which are attempted to be generated per 256^2 map during world generation. - bool enabled; ///< Is this spec enabled? + + /** + * Test if this object is enabled. + * @return True iif this object is enabled. + */ + bool IsEnabled() const { return this->views > 0; } /** * Get the cost for building a structure of this type. diff --git a/src/newgrf_profiling.cpp b/src/newgrf_profiling.cpp index d2feb8273fe50..7f93e1d7650ba 100644 --- a/src/newgrf_profiling.cpp +++ b/src/newgrf_profiling.cpp @@ -109,7 +109,7 @@ uint32 NewGRFProfiler::Finish() fputs("Tick,Sprite,Feature,Item,CallbackID,Microseconds,Depth,Result\n", f); for (const Call &c : this->calls) { - fprintf(f, "%u,%u,0x%X,%u,0x%X,%u,%u,%u\n", c.tick, c.root_sprite, c.feat, c.item, (uint)c.cb, c.time, c.subs, c.result); + fprintf(f, OTTD_PRINTF64U ",%u,0x%X,%u,0x%X,%u,%u,%u\n", c.tick, c.root_sprite, c.feat, c.item, (uint)c.cb, c.time, c.subs, c.result); total_microseconds += c.time; } @@ -141,7 +141,7 @@ std::string NewGRFProfiler::GetOutputFilename() const uint32 NewGRFProfiler::FinishAll() { - uint32 max_ticks = 0; + uint64 max_ticks = 0; uint32 total_microseconds = 0; for (NewGRFProfiler &pr : _newgrf_profilers) { if (pr.active) { diff --git a/src/newgrf_profiling.h b/src/newgrf_profiling.h index 4dadc4b2ede7a..15adb87830f74 100644 --- a/src/newgrf_profiling.h +++ b/src/newgrf_profiling.h @@ -45,14 +45,14 @@ struct NewGRFProfiler { uint32 result; ///< Result of callback uint32 subs; ///< Sub-calls to other sprite groups uint32 time; ///< Time taken for resolution (microseconds) - uint32 tick; ///< Game tick + uint64 tick; ///< Game tick CallbackID cb; ///< Callback ID GrfSpecFeature feat; ///< GRF feature being resolved for }; const GRFFile *grffile; ///< Which GRF is being profiled bool active; ///< Is this profiler collecting data - uint32 start_tick; ///< Tick number this profiler was started on + uint64 start_tick; ///< Tick number this profiler was started on Call cur_call; ///< Data for current call in progress std::vector calls; ///< All calls collected so far }; diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp new file mode 100644 index 0000000000000..76b901d8f73b5 --- /dev/null +++ b/src/newgrf_roadstop.cpp @@ -0,0 +1,614 @@ +/* + * 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 command.cpp Handling of NewGRF road stops. */ + +#include "stdafx.h" +#include "debug.h" +#include "station_base.h" +#include "roadstop_base.h" +#include "newgrf_roadstop.h" +#include "newgrf_class_func.h" +#include "newgrf_cargo.h" +#include "newgrf_roadtype.h" +#include "gfx_type.h" +#include "company_func.h" +#include "road.h" +#include "window_type.h" +#include "date_func.h" +#include "town.h" +#include "viewport_func.h" +#include "newgrf_animation_base.h" +#include "newgrf_sound.h" + +#include "safeguards.h" + +template +void NewGRFClass::InsertDefaults() +{ + /* Set up initial data */ + classes[0].global_id = 'DFLT'; + classes[0].name = STR_STATION_CLASS_DFLT; + classes[0].Insert(nullptr); + + classes[1].global_id = 'WAYP'; + classes[1].name = STR_STATION_CLASS_WAYP; + classes[1].Insert(nullptr); +} + +template +bool NewGRFClass::IsUIAvailable(uint index) const +{ + return true; +} + +INSTANTIATE_NEWGRF_CLASS_METHODS(RoadStopClass, RoadStopSpec, RoadStopClassID, ROADSTOP_CLASS_MAX) + +static const uint NUM_ROADSTOPSPECS_PER_STATION = 63; ///< Maximum number of parts per station. + +uint32 RoadStopScopeResolver::GetRandomBits() const +{ + if (this->st == nullptr) return 0; + + uint32 bits = this->st->random_bits; + if (this->tile != INVALID_TILE && Station::IsExpected(this->st)) { + bits |= Station::From(this->st)->GetRoadStopRandomBits(this->tile) << 16; + } + return bits; +} + +uint32 RoadStopScopeResolver::GetTriggers() const +{ + return this->st == nullptr ? 0 : this->st->waiting_triggers; +} + +uint32 RoadStopScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const +{ + auto get_road_type_variable = [&](RoadTramType rtt) -> uint32 { + RoadType rt; + if (this->tile == INVALID_TILE) { + rt = (GetRoadTramType(this->roadtype) == rtt) ? this->roadtype : INVALID_ROADTYPE; + } else { + rt = GetRoadType(this->tile, rtt); + } + if (rt == INVALID_ROADTYPE) { + return 0xFFFFFFFF; + } else { + return GetReverseRoadTypeTranslation(rt, this->roadstopspec->grf_prop.grffile); + } + }; + + switch (variable) { + /* View/rotation */ + case 0x40: return this->view; + + /* Stop type: 0: bus, 1: truck, 2: waypoint */ + case 0x41: + if (this->type == STATION_BUS) return 0; + if (this->type == STATION_TRUCK) return 1; + return 2; + + /* Terrain type */ + case 0x42: return this->tile == INVALID_TILE ? 0 : GetTerrainType(this->tile, TCX_NORMAL); // terrain_type + + /* Road type */ + case 0x43: return get_road_type_variable(RTT_ROAD); + + /* Tram type */ + case 0x44: return get_road_type_variable(RTT_TRAM); + + /* Town zone and Manhattan distance of closest town */ + case 0x45: { + if (this->tile == INVALID_TILE) return HZB_TOWN_EDGE << 16; + const Town *t = (this->st == nullptr) ? ClosestTownFromTile(this->tile, UINT_MAX) : this->st->town; + return t != nullptr ? (GetTownRadiusGroup(t, this->tile) << 16 | std::min(DistanceManhattan(this->tile, t->xy), 0xFFFFu)) : HZB_TOWN_EDGE << 16; + } + + /* Get square of Euclidian distance of closest town */ + case 0x46: { + if (this->tile == INVALID_TILE) return 0; + const Town *t = (this->st == nullptr) ? ClosestTownFromTile(this->tile, UINT_MAX) : this->st->town; + return t != nullptr ? DistanceSquare(this->tile, t->xy) : 0; + } + + /* Company information */ + case 0x47: return GetCompanyInfo(this->st == nullptr ? _current_company : this->st->owner); + + /* Animation frame */ + case 0x49: return this->tile == INVALID_TILE ? 0 : this->st->GetRoadStopAnimationFrame(this->tile); + + /* Variables which use the parameter */ + /* Variables 0x60 to 0x65 and 0x69 are handled separately below */ + + /* Animation frame of nearby tile */ + case 0x66: { + if (this->tile == INVALID_TILE) return UINT_MAX; + TileIndex tile = this->tile; + if (parameter != 0) tile = GetNearbyTile(parameter, tile); + return (IsRoadStopTile(tile) && GetStationIndex(tile) == this->st->index) ? this->st->GetRoadStopAnimationFrame(tile) : UINT_MAX; + } + + /* Land info of nearby tile */ + case 0x67: { + if (this->tile == INVALID_TILE) return 0; + TileIndex tile = this->tile; + if (parameter != 0) tile = GetNearbyTile(parameter, tile); // only perform if it is required + return GetNearbyTileInformation(tile, this->ro.grffile->grf_version >= 8); + } + + /* Road stop info of nearby tiles */ + case 0x68: { + if (this->tile == INVALID_TILE) return 0xFFFFFFFF; + TileIndex nearby_tile = GetNearbyTile(parameter, this->tile); + + if (!IsRoadStopTile(nearby_tile)) return 0xFFFFFFFF; + + uint32 grfid = this->st->roadstop_speclist[GetCustomRoadStopSpecIndex(this->tile)].grfid; + bool same_orientation = GetStationGfx(this->tile) == GetStationGfx(nearby_tile); + bool same_station = GetStationIndex(nearby_tile) == this->st->index; + uint32 res = GetStationGfx(nearby_tile) << 12 | !same_orientation << 11 | !!same_station << 10; + StationType type = GetStationType(nearby_tile); + if (type == STATION_TRUCK) res |= (1 << 16); + if (type == this->type) SetBit(res, 20); + + if (IsCustomRoadStopSpecIndex(nearby_tile)) { + const RoadStopSpecList ssl = BaseStation::GetByTile(nearby_tile)->roadstop_speclist[GetCustomRoadStopSpecIndex(nearby_tile)]; + res |= 1 << (ssl.grfid != grfid ? 9 : 8) | ssl.localidx; + } + return res; + } + + /* GRFID of nearby road stop tiles */ + case 0x6A: { + if (this->tile == INVALID_TILE) return 0xFFFFFFFF; + TileIndex nearby_tile = GetNearbyTile(parameter, this->tile); + + if (!IsRoadStopTile(nearby_tile)) return 0xFFFFFFFF; + if (!IsCustomRoadStopSpecIndex(nearby_tile)) return 0; + + const RoadStopSpecList ssl = BaseStation::GetByTile(nearby_tile)->roadstop_speclist[GetCustomRoadStopSpecIndex(nearby_tile)]; + return ssl.grfid; + } + + case 0xF0: return this->st == nullptr ? 0 : this->st->facilities; // facilities + + case 0xFA: return Clamp((this->st == nullptr ? _date : this->st->build_date) - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // build date + } + + if (this->st != nullptr) return this->st->GetNewGRFVariable(this->ro, variable, parameter, available); + + *available = false; + return UINT_MAX; +} + +const SpriteGroup *RoadStopResolverObject::ResolveReal(const RealSpriteGroup *group) const +{ + if (group == nullptr) return nullptr; + + return group->loading[0]; +} + +RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, RoadType roadtype, StationType type, uint8 view, + CallbackID callback, uint32 param1, uint32 param2) + : ResolverObject(roadstopspec->grf_prop.grffile, callback, param1, param2), roadstop_scope(*this, st, roadstopspec, tile, roadtype, type, view) + { + + this->town_scope = nullptr; + + CargoID ctype = CT_DEFAULT_NA; + + if (st == nullptr) { + /* No station, so we are in a purchase list */ + ctype = CT_PURCHASE; + } else if (Station::IsExpected(st)) { + const Station *station = Station::From(st); + /* Pick the first cargo that we have waiting */ + for (const CargoSpec *cs : CargoSpec::Iterate()) { + if (roadstopspec->grf_prop.spritegroup[cs->Index()] != nullptr && + station->goods[cs->Index()].cargo.TotalCount() > 0) { + ctype = cs->Index(); + break; + } + } + } + + if (roadstopspec->grf_prop.spritegroup[ctype] == nullptr) { + ctype = CT_DEFAULT; + } + + /* Remember the cargo type we've picked */ + this->roadstop_scope.cargo_type = ctype; + this->root_spritegroup = roadstopspec->grf_prop.spritegroup[ctype]; +} + +RoadStopResolverObject::~RoadStopResolverObject() +{ + delete this->town_scope; +} + +TownScopeResolver* RoadStopResolverObject::GetTown() +{ + if (this->town_scope == nullptr) { + Town *t; + if (this->roadstop_scope.st != nullptr) { + t = this->roadstop_scope.st->town; + } else { + t = ClosestTownFromTile(this->roadstop_scope.tile, UINT_MAX); + } + if (t == nullptr) return nullptr; + this->town_scope = new TownScopeResolver(*this, t, this->roadstop_scope.st == nullptr); + } + return this->town_scope; +} + +uint16 GetRoadStopCallback(CallbackID callback, uint32 param1, uint32 param2, const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, RoadType roadtype, StationType type, uint8 view) +{ + RoadStopResolverObject object(roadstopspec, st, tile, roadtype, type, view, callback, param1, param2); + return object.ResolveCallback(); +} + +/** + * Draw representation of a road stop tile for GUI purposes. + * @param x position x of image. + * @param y position y of image. + * @param image an int offset for the sprite. + * @param roadtype the RoadType of the underlying road. + * @param spec the RoadStop's spec. + * @return true of the tile was drawn (allows for fallback to default graphics) + */ +void DrawRoadStopTile(int x, int y, RoadType roadtype, const RoadStopSpec *spec, StationType type, int view) +{ + assert(roadtype != INVALID_ROADTYPE); + assert(spec != nullptr); + + const RoadTypeInfo *rti = GetRoadTypeInfo(roadtype); + RoadStopResolverObject object(spec, nullptr, INVALID_TILE, roadtype, type, view); + const SpriteGroup *group = object.Resolve(); + if (group == nullptr || group->type != SGT_TILELAYOUT) return; + const DrawTileSprites *dts = ((const TileLayoutSpriteGroup *)group)->ProcessRegisters(nullptr); + + PaletteID palette = COMPANY_SPRITE_COLOUR(_local_company); + + SpriteID image = dts->ground.sprite; + PaletteID pal = dts->ground.pal; + + if (GB(image, 0, SPRITE_WIDTH) != 0) { + DrawSprite(image, GroundSpritePaletteTransform(image, pal, palette), x, y); + } + + if (view >= 4) { + /* Drive-through stop */ + uint sprite_offset = 5 - view; + + /* Road underlay takes precedence over tram */ + if (spec->draw_mode & ROADSTOP_DRAW_MODE_OVERLAY) { + if (rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_GROUND); + DrawSprite(ground + sprite_offset, PAL_NONE, x, y); + + SpriteID overlay = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_OVERLAY); + if (overlay) DrawSprite(overlay + sprite_offset, PAL_NONE, x, y); + } else if (RoadTypeIsTram(roadtype)) { + DrawSprite(SPR_TRAMWAY_TRAM + sprite_offset, PAL_NONE, x, y); + } + } + } else { + /* Drive-in stop */ + if ((spec->draw_mode & ROADSTOP_DRAW_MODE_ROAD) && rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_ROADSTOP); + DrawSprite(ground + view, PAL_NONE, x, y); + } + } + + DrawCommonTileSeqInGUI(x, y, dts, 0, 0, palette, true); +} + +/** Wrapper for animation control, see GetRoadStopCallback. */ +uint16 GetAnimRoadStopCallback(CallbackID callback, uint32 param1, uint32 param2, const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, int extra_data) +{ + return GetRoadStopCallback(callback, param1, param2, roadstopspec, st, tile, INVALID_ROADTYPE, GetStationType(tile), GetStationGfx(tile)); +} + +struct RoadStopAnimationFrameAnimationHelper { + static byte Get(BaseStation *st, TileIndex tile) { return st->GetRoadStopAnimationFrame(tile); } + static void Set(BaseStation *st, TileIndex tile, byte frame) { st->SetRoadStopAnimationFrame(tile, frame); } +}; + +/** Helper class for animation control. */ +struct RoadStopAnimationBase : public AnimationBase { + static const CallbackID cb_animation_speed = CBID_STATION_ANIMATION_SPEED; + static const CallbackID cb_animation_next_frame = CBID_STATION_ANIM_NEXT_FRAME; + + static const RoadStopCallbackMask cbm_animation_speed = CBM_ROAD_STOP_ANIMATION_SPEED; + static const RoadStopCallbackMask cbm_animation_next_frame = CBM_ROAD_STOP_ANIMATION_NEXT_FRAME; +}; + +void AnimateRoadStopTile(TileIndex tile) +{ + const RoadStopSpec *ss = GetRoadStopSpec(tile); + if (ss == nullptr) return; + + RoadStopAnimationBase::AnimateTile(ss, BaseStation::GetByTile(tile), tile, HasBit(ss->flags, RSF_CB141_RANDOM_BITS)); +} + +void TriggerRoadStopAnimation(BaseStation *st, TileIndex trigger_tile, StationAnimationTrigger trigger, CargoID cargo_type) +{ + /* Get Station if it wasn't supplied */ + 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_roadstop_anim_triggers, trigger)) return; + + uint16 random_bits = Random(); + auto process_tile = [&](TileIndex cur_tile) { + const RoadStopSpec *ss = GetRoadStopSpec(cur_tile); + if (ss != nullptr && HasBit(ss->animation.triggers, trigger)) { + CargoID cargo; + if (cargo_type == CT_INVALID) { + cargo = CT_INVALID; + } else { + cargo = ss->grf_prop.grffile->cargo_map[cargo_type]; + } + RoadStopAnimationBase::ChangeAnimationFrame(CBID_STATION_ANIM_START_STOP, ss, st, cur_tile, (random_bits << 16) | Random(), (uint8)trigger | (cargo << 8)); + } + }; + + if (trigger == SAT_NEW_CARGO || trigger == SAT_CARGO_TAKEN || trigger == SAT_250_TICKS) { + for (const RoadStopTileData &tile_data : st->custom_roadstop_tile_data) { + process_tile(tile_data.tile); + } + } else { + process_tile(trigger_tile); + } +} + +/** + * Trigger road stop randomisation + * + * @param st the station being triggered + * @param tile the exact tile of the station that should be triggered + * @param trigger trigger type + * @param cargo_type cargo type causing the trigger + */ +void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTrigger trigger, CargoID cargo_type) +{ + if (st == nullptr) st = Station::GetByTile(tile); + + /* Check the cached cargo trigger bitmask to see if we need + * to bother with any further processing. */ + if (st->cached_roadstop_cargo_triggers == 0) return; + if (cargo_type != CT_INVALID && !HasBit(st->cached_roadstop_cargo_triggers, cargo_type)) return; + + SetBit(st->waiting_triggers, trigger); + + uint32 whole_reseed = 0; + + CargoTypes empty_mask = 0; + if (trigger == RSRT_CARGO_TAKEN) { + /* Create a bitmask of completely empty cargo types to be matched */ + for (CargoID i = 0; i < NUM_CARGO; i++) { + if (st->goods[i].cargo.TotalCount() == 0) { + SetBit(empty_mask, i); + } + } + } + + uint32 used_triggers = 0; + auto process_tile = [&](TileIndex cur_tile) { + const RoadStopSpec *ss = GetRoadStopSpec(cur_tile); + if (ss == nullptr) return; + + /* Cargo taken "will only be triggered if all of those + * cargo types have no more cargo waiting." */ + if (trigger == RSRT_CARGO_TAKEN) { + if ((ss->cargo_triggers & ~empty_mask) != 0) return; + } + + if (cargo_type == CT_INVALID || HasBit(ss->cargo_triggers, cargo_type)) { + RoadStopResolverObject object(ss, st, cur_tile, INVALID_ROADTYPE, GetStationType(cur_tile), GetStationGfx(cur_tile)); + object.waiting_triggers = st->waiting_triggers; + + const SpriteGroup *group = object.Resolve(); + if (group == nullptr) return; + + used_triggers |= object.used_triggers; + + uint32 reseed = object.GetReseedSum(); + if (reseed != 0) { + whole_reseed |= reseed; + reseed >>= 16; + + /* Set individual tile random bits */ + uint8 random_bits = st->GetRoadStopRandomBits(cur_tile); + random_bits &= ~reseed; + random_bits |= Random() & reseed; + st->SetRoadStopRandomBits(cur_tile, random_bits); + + MarkTileDirtyByTile(cur_tile); + } + } + }; + if (trigger == RSRT_NEW_CARGO || trigger == RSRT_CARGO_TAKEN) { + for (const RoadStopTileData &tile_data : st->custom_roadstop_tile_data) { + process_tile(tile_data.tile); + } + } else { + process_tile(tile); + } + + /* Update whole station random bits */ + st->waiting_triggers &= ~used_triggers; + if ((whole_reseed & 0xFFFF) != 0) { + st->random_bits &= ~whole_reseed; + st->random_bits |= Random() & whole_reseed; + } +} + +/** + * Checks if there's any new stations by a specific RoadStopType + * @param rs the RoadStopType to check. + * @param roadtype the RoadType to check. + * @return true if there was any new RoadStopSpec's found for the given RoadStopType and RoadType, else false. + */ +bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype) +{ + if (!(RoadStopClass::GetClassCount() > 1 || RoadStopClass::Get(ROADSTOP_CLASS_DFLT)->GetSpecCount() > 1)) return false; + for (uint i = 0; i < RoadStopClass::GetClassCount(); i++) { + // We don't want to check the default or waypoint classes. These classes are always available. + if (i == ROADSTOP_CLASS_DFLT || i == ROADSTOP_CLASS_WAYP) continue; + RoadStopClass *roadstopclass = RoadStopClass::Get((RoadStopClassID)i); + if (GetIfClassHasNewStopsByType(roadstopclass, rs, roadtype)) return true; + } + return false; +} + +/** + * Checks if the given RoadStopClass has any specs assigned to it, compatible with the given RoadStopType. + * @param roadstopclass the RoadStopClass to check. + * @param rs the RoadStopType to check. + * @param roadtype the RoadType to check. + * @return true if the RoadStopSpec has any specs compatible with the given RoadStopType and RoadType. + */ +bool GetIfClassHasNewStopsByType(RoadStopClass *roadstopclass, RoadStopType rs, RoadType roadtype) +{ + for (uint j = 0; j < roadstopclass->GetSpecCount(); j++) { + if (GetIfStopIsForType(roadstopclass->GetSpec(j), rs, roadtype)) return true; + } + return false; +} + +/** + * Checks if the given RoadStopSpec is compatible with the given RoadStopType. + * @param roadstopspec the RoadStopSpec to check. + * @param rs the RoadStopType to check. + * @param roadtype the RoadType to check. + * @return true if the RoadStopSpec is compatible with the given RoadStopType and RoadType. + */ +bool GetIfStopIsForType(const RoadStopSpec *roadstopspec, RoadStopType rs, RoadType roadtype) +{ + // The roadstopspec is nullptr, must be the default station, always return true. + if (roadstopspec == nullptr) return true; + + if (HasBit(roadstopspec->flags, RSF_BUILD_MENU_ROAD_ONLY) && !RoadTypeIsRoad(roadtype)) return false; + if (HasBit(roadstopspec->flags, RSF_BUILD_MENU_TRAM_ONLY) && !RoadTypeIsTram(roadtype)) return false; + + if (roadstopspec->stop_type == ROADSTOPTYPE_ALL) return true; + + switch (rs) { + case ROADSTOP_BUS: + if (roadstopspec->stop_type == ROADSTOPTYPE_PASSENGER) return true; + break; + + case ROADSTOP_TRUCK: + if (roadstopspec->stop_type == ROADSTOPTYPE_FREIGHT) return true; + break; + + default: + NOT_REACHED(); + } + return false; +} + +const RoadStopSpec *GetRoadStopSpec(TileIndex t) +{ + if (!IsCustomRoadStopSpecIndex(t)) return nullptr; + + const BaseStation *st = BaseStation::GetByTile(t); + uint specindex = GetCustomRoadStopSpecIndex(t); + return specindex < st->roadstop_speclist.size() ? st->roadstop_speclist[specindex].spec : nullptr; +} + +int AllocateSpecToRoadStop(const RoadStopSpec *statspec, BaseStation *st, bool exec) +{ + uint i; + + if (statspec == nullptr || st == nullptr) return 0; + + /* Try to find the same spec and return that one */ + for (i = 1; i < st->roadstop_speclist.size() && i < NUM_ROADSTOPSPECS_PER_STATION; i++) { + if (st->roadstop_speclist[i].spec == statspec) return i; + } + + /* Try to find an unused spec slot */ + for (i = 1; i < st->roadstop_speclist.size() && i < NUM_ROADSTOPSPECS_PER_STATION; i++) { + if (st->roadstop_speclist[i].spec == nullptr && st->roadstop_speclist[i].grfid == 0) break; + } + + if (i == NUM_ROADSTOPSPECS_PER_STATION) { + /* Full, give up */ + return -1; + } + + if (exec) { + if (i >= st->roadstop_speclist.size()) st->roadstop_speclist.resize(i + 1); + st->roadstop_speclist[i].spec = statspec; + st->roadstop_speclist[i].grfid = statspec->grf_prop.grffile->grfid; + st->roadstop_speclist[i].localidx = statspec->grf_prop.local_id; + + RoadStopUpdateCachedTriggers(st); + } + + return i; +} + +void DeallocateSpecFromRoadStop(BaseStation *st, byte specindex) +{ + /* specindex of 0 (default) is never freeable */ + if (specindex == 0) return; + + /* Check custom road stop tiles if the specindex is still in use */ + for (const RoadStopTileData &tile_data : st->custom_roadstop_tile_data) { + if (GetCustomRoadStopSpecIndex(tile_data.tile) == specindex) { + return; + } + } + + /* This specindex is no longer in use, so deallocate it */ + st->roadstop_speclist[specindex].spec = nullptr; + st->roadstop_speclist[specindex].grfid = 0; + st->roadstop_speclist[specindex].localidx = 0; + + /* If this was the highest spec index, reallocate */ + if (specindex == st->roadstop_speclist.size() - 1) { + size_t num_specs; + for (num_specs = st->roadstop_speclist.size() - 1; num_specs > 0; num_specs--) { + if (st->roadstop_speclist[num_specs].grfid != 0) break; + } + + if (num_specs > 0) { + st->roadstop_speclist.resize(num_specs + 1); + } else { + st->roadstop_speclist.clear(); + st->cached_roadstop_anim_triggers = 0; + st->cached_roadstop_cargo_triggers = 0; + return; + } + } + + RoadStopUpdateCachedTriggers(st); +} + +/** + * Update the cached animation trigger bitmask for a station. + * @param st Station to update. + */ +void RoadStopUpdateCachedTriggers(BaseStation *st) +{ + st->cached_roadstop_anim_triggers = 0; + st->cached_roadstop_cargo_triggers = 0; + + /* Combine animation trigger bitmask for all road stop specs + * of this station. */ + for (uint i = 0; i < st->roadstop_speclist.size(); i++) { + const RoadStopSpec *ss = st->roadstop_speclist[i].spec; + if (ss != nullptr) { + st->cached_roadstop_anim_triggers |= ss->animation.triggers; + st->cached_roadstop_cargo_triggers |= ss->cargo_triggers; + } + } +} diff --git a/src/newgrf_roadstop.h b/src/newgrf_roadstop.h new file mode 100644 index 0000000000000..fa05c30ba1734 --- /dev/null +++ b/src/newgrf_roadstop.h @@ -0,0 +1,189 @@ +/* + * 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 newgrf_roadstop.h NewGRF definitions and structures for road stops. + */ + +#ifndef NEWGRF_ROADSTATION_H +#define NEWGRF_ROADSTATION_H + +#include "newgrf_animation_type.h" +#include "newgrf_spritegroup.h" +#include "newgrf_class.h" +#include "newgrf_commons.h" +#include "newgrf_town.h" +#include "road.h" + +/** The maximum amount of roadstops a single GRF is allowed to add */ +static const int NUM_ROADSTOPS_PER_GRF = 255; + +enum RoadStopClassID : byte { + ROADSTOP_CLASS_BEGIN = 0, ///< The lowest valid value + ROADSTOP_CLASS_DFLT = 0, ///< Default road stop class. + ROADSTOP_CLASS_WAYP, ///< Waypoint class (unimplemented: this is reserved for future use with road waypoints). + ROADSTOP_CLASS_MAX = 255, ///< Maximum number of classes. +}; +DECLARE_POSTFIX_INCREMENT(RoadStopClassID) + +/* Some Triggers etc. */ +enum RoadStopRandomTrigger { + RSRT_NEW_CARGO, ///< Trigger roadstop on arrival of new cargo. + RSRT_CARGO_TAKEN, ///< Trigger roadstop when cargo is completely taken. + RSRT_VEH_ARRIVES, ///< Trigger roadstop when road vehicle arrives. + RSRT_VEH_DEPARTS, ///< Trigger roadstop when road vehicle leaves. + RSRT_VEH_LOADS, ///< Trigger roadstop when road vehicle loads. +}; + +/** + * Various different options for availability, restricting + * the roadstop to be only for busses or for trucks. + */ +enum RoadStopAvailabilityType : byte { + ROADSTOPTYPE_PASSENGER, ///< This RoadStop is for passenger (bus) stops. + ROADSTOPTYPE_FREIGHT, ///< This RoadStop is for freight (truck) stops. + ROADSTOPTYPE_ALL, ///< This RoadStop is for both types of station road stops. + + ROADSTOPTYPE_END, +}; + +/** + * Different draw modes to disallow rendering of some parts of the stop + * or road. + */ +enum RoadStopDrawMode : byte { + ROADSTOP_DRAW_MODE_NONE = 0, + ROADSTOP_DRAW_MODE_ROAD = 1 << 0, ///< Bay stops: Draw the road itself + ROADSTOP_DRAW_MODE_OVERLAY = 1 << 1, ///< Drive-through stops: Draw the road overlay, e.g. pavement +}; +DECLARE_ENUM_AS_BIT_SET(RoadStopDrawMode) + +enum RoadStopSpecFlags { + RSF_CB141_RANDOM_BITS = 0, ///< Callback 141 needs random bits. + RSF_NO_CATENARY = 2, ///< Do not show catenary. + RSF_DRIVE_THROUGH_ONLY = 3, ///< Stop is drive-through only. + RSF_NO_AUTO_ROAD_CONNECTION = 4, ///< No auto road connection. + RSF_BUILD_MENU_ROAD_ONLY = 5, ///< Only show in the road build menu (not tram). + RSF_BUILD_MENU_TRAM_ONLY = 6, ///< Only show in the tram build menu (not road). +}; + +/** Scope resolver for road stops. */ +struct RoadStopScopeResolver : public ScopeResolver { + TileIndex tile; ///< %Tile of the station. + struct BaseStation *st; ///< Instance of the station. + const struct RoadStopSpec *roadstopspec; ///< Station (type) specification. + CargoID cargo_type; ///< Type of cargo of the station. + StationType type; ///< Station type. + uint8 view; ///< Station axis. + RoadType roadtype; ///< Road type (used when no tile) + + RoadStopScopeResolver(ResolverObject& ro, BaseStation* st, const RoadStopSpec *roadstopspec, TileIndex tile, RoadType roadtype, StationType type, uint8 view = 0) + : ScopeResolver(ro), tile(tile), st(st), roadstopspec(roadstopspec), type(type), view(view), roadtype(roadtype) + { + } + + uint32 GetRandomBits() const override; + uint32 GetTriggers() const override; + + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; +}; + +/** Road stop resolver. */ +struct RoadStopResolverObject : public ResolverObject { + RoadStopScopeResolver roadstop_scope; ///< The stop scope resolver. + TownScopeResolver *town_scope; ///< The town scope resolver (created on the first call). + + RoadStopResolverObject(const RoadStopSpec* roadstopspec, BaseStation* st, TileIndex tile, RoadType roadtype, StationType type, uint8 view, CallbackID callback = CBID_NO_CALLBACK, uint32 param1 = 0, uint32 param2 = 0); + ~RoadStopResolverObject(); + + ScopeResolver* GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override + { + switch (scope) { + case VSG_SCOPE_SELF: return &this->roadstop_scope; + case VSG_SCOPE_PARENT: { + TownScopeResolver *tsr = this->GetTown(); + if (tsr != nullptr) return tsr; + FALLTHROUGH; + } + default: return ResolverObject::GetScope(scope, relative); + } + } + + TownScopeResolver *GetTown(); + + const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override; +}; + +/** Road stop specification. */ +struct RoadStopSpec { + /** + * Properties related the the grf file. + * NUM_CARGO real cargo plus three pseudo cargo sprite groups. + * Used for obtaining the sprite offset of custom sprites, and for + * evaluating callbacks. + */ + GRFFilePropsBase grf_prop; + RoadStopClassID cls_id; ///< The class to which this spec belongs. + int spec_id; ///< The ID of this spec inside the class. + StringID name; ///< Name of this stop + + RoadStopAvailabilityType stop_type = ROADSTOPTYPE_ALL; + RoadStopDrawMode draw_mode = ROADSTOP_DRAW_MODE_ROAD | ROADSTOP_DRAW_MODE_OVERLAY; + uint8 callback_mask = 0; + uint8 flags = 0; + + CargoTypes cargo_triggers = 0; ///< Bitmask of cargo types which cause trigger re-randomizing + + AnimationInfo animation; + + byte bridge_height[6]; ///< Minimum height for a bridge above, 0 for none + byte bridge_disallowed_pillars[6]; ///< Disallowed pillar flags for a bridge above + + uint8 build_cost_multiplier = 16; ///< Build cost multiplier per tile. + uint8 clear_cost_multiplier = 16; ///< Clear cost multiplier per tile. + + /** + * Get the cost for building a road stop of this type. + * @return The cost for building. + */ + Money GetBuildCost(Price category) const { return GetPrice(category, this->build_cost_multiplier, this->grf_prop.grffile, -4); } + + /** + * Get the cost for clearing a road stop of this type. + * @return The cost for clearing. + */ + Money GetClearCost(Price category) const { return GetPrice(category, this->clear_cost_multiplier, this->grf_prop.grffile, -4); } + + static const RoadStopSpec *Get(uint16 index); +}; + +template <> +struct EnumPropsT : MakeEnumPropsT {}; + +typedef NewGRFClass RoadStopClass; + +void DrawRoadStopTile(int x, int y, RoadType roadtype, const RoadStopSpec *spec, StationType type, int view); + +uint16 GetRoadStopCallback(CallbackID callback, uint32 param1, uint32 param2, const RoadStopSpec *roadstopspec, BaseStation *st, TileIndex tile, RoadType roadtype, StationType type, uint8 view); + +void AnimateRoadStopTile(TileIndex tile); +uint8 GetRoadStopTileAnimationSpeed(TileIndex tile); +void TriggerRoadStopAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoID cargo_type = CT_INVALID); +void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTrigger trigger, CargoID cargo_type = CT_INVALID); + +bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype); +bool GetIfClassHasNewStopsByType(RoadStopClass *roadstopclass, RoadStopType rs, RoadType roadtype); +bool GetIfStopIsForType(const RoadStopSpec *roadstopspec, RoadStopType rs, RoadType roadtype); + +uint GetCountOfCompatibleStopsByType(RoadStopClass *roadstopclass, RoadStopType rs); + +const RoadStopSpec *GetRoadStopSpec(TileIndex t); +int AllocateSpecToRoadStop(const RoadStopSpec *statspec, BaseStation *st, bool exec); +void DeallocateSpecFromRoadStop(BaseStation *st, byte specindex); +void RoadStopUpdateCachedTriggers(BaseStation *st); + +#endif /* NEWGRF_ROADSTATION_H */ diff --git a/src/newgrf_sound.cpp b/src/newgrf_sound.cpp index 48f21055176ad..fce0ba9e111f4 100644 --- a/src/newgrf_sound.cpp +++ b/src/newgrf_sound.cpp @@ -181,11 +181,12 @@ SoundID GetNewGRFSoundID(const GRFFile *file, SoundID sound_id) * Checks whether a NewGRF wants to play a different vehicle sound effect. * @param v Vehicle to play sound effect for. * @param event Trigger for the sound effect. + * @param force Should we play the sound effect even if vehicle sound effects are muted? * @return false if the default sound effect shall be played instead. */ -bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event) +bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event, bool force) { - if (!_settings_client.sound.vehicle) return true; + if (!_settings_client.sound.vehicle && !force) return true; const GRFFile *file = v->GetGRF(); uint16 callback; diff --git a/src/newgrf_sound.h b/src/newgrf_sound.h index d908173ac89a5..5b1d1cbc5702d 100644 --- a/src/newgrf_sound.h +++ b/src/newgrf_sound.h @@ -34,7 +34,7 @@ bool LoadNewGRFSound(SoundEntry *sound); SoundID GetNewGRFSoundID(const struct GRFFile *file, SoundID sound_id); SoundEntry *GetSound(SoundID sound_id); uint GetNumSounds(); -bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event); +bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event, bool force = false); void PlayTileSound(const struct GRFFile *file, SoundID sound_id, TileIndex tile); #endif /* NEWGRF_SOUND_H */ diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index b17266761242a..af28950a88202 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -50,7 +50,7 @@ struct ResolverObject; /* SPRITE_WIDTH is 24. ECS has roughly 30 sprite groups per real sprite. * Adding an 'extra' margin would be assuming 64 sprite groups per real * sprite. 64 = 2^6, so 2^30 should be enough (for now) */ -typedef Pool SpriteGroupPool; +typedef Pool SpriteGroupPool; extern SpriteGroupPool _spritegroup_pool; /* Common wrapper for all the different sprite group types */ diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 5fd5d6ad3ca1d..671104fe23b3b 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -683,7 +683,7 @@ int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exe if (statspec == nullptr || st == nullptr) return 0; - for (i = 1; i < st->num_specs && i < NUM_STATIONSSPECS_PER_STATION; i++) { + for (i = 1; i < st->speclist.size() && i < NUM_STATIONSSPECS_PER_STATION; i++) { if (st->speclist[i].spec == nullptr && st->speclist[i].grfid == 0) break; } @@ -693,7 +693,7 @@ int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exe * result in slightly "wrong" (as per specs) looking stations, * but it's fairly unlikely that one reaches the limit anyways. */ - for (i = 1; i < st->num_specs && i < NUM_STATIONSSPECS_PER_STATION; i++) { + for (i = 1; i < st->speclist.size() && i < NUM_STATIONSSPECS_PER_STATION; i++) { if (st->speclist[i].spec == statspec) return i; } @@ -701,18 +701,7 @@ int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exe } if (exec) { - if (i >= st->num_specs) { - st->num_specs = i + 1; - st->speclist = ReallocT(st->speclist, st->num_specs); - - if (st->num_specs == 2) { - /* Initial allocation */ - st->speclist[0].spec = nullptr; - st->speclist[0].grfid = 0; - st->speclist[0].localidx = 0; - } - } - + if (i >= st->speclist.size()) st->speclist.resize(i + 1); st->speclist[i].spec = statspec; st->speclist[i].grfid = statspec->grf_prop.grffile->grfid; st->speclist[i].localidx = statspec->grf_prop.local_id; @@ -749,15 +738,16 @@ void DeallocateSpecFromStation(BaseStation *st, byte specindex) st->speclist[specindex].localidx = 0; /* If this was the highest spec index, reallocate */ - if (specindex == st->num_specs - 1) { - for (; st->speclist[st->num_specs - 1].grfid == 0 && st->num_specs > 1; st->num_specs--) {} + if (specindex == st->speclist.size() - 1) { + size_t num_specs; + for (num_specs = st->speclist.size() - 1; num_specs > 0; num_specs--) { + if (st->speclist[num_specs].grfid != 0) break; + } - if (st->num_specs > 1) { - st->speclist = ReallocT(st->speclist, st->num_specs); + if (num_specs > 0) { + st->speclist.resize(num_specs + 1); } else { - free(st->speclist); - st->num_specs = 0; - st->speclist = nullptr; + st->speclist.clear(); st->cached_anim_triggers = 0; st->cached_cargo_triggers = 0; return; @@ -788,8 +778,8 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID if (statspec == nullptr) return false; if (HasBit(statspec->callback_mask, CBM_STATION_SPRITE_LAYOUT)) { - uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0x2110000, 0, statspec, nullptr, INVALID_TILE); - if (callback != CALLBACK_FAILED) tile = callback; + uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, nullptr, INVALID_TILE); + if (callback != CALLBACK_FAILED) tile = callback & ~1; } uint32 total_offset = rti->GetRailtypeSpriteOffset(); @@ -854,7 +844,7 @@ const StationSpec *GetStationSpec(TileIndex t) const BaseStation *st = BaseStation::GetByTile(t); uint specindex = GetCustomStationSpecIndex(t); - return specindex < st->num_specs ? st->speclist[specindex].spec : nullptr; + return specindex < st->speclist.size() ? st->speclist[specindex].spec : nullptr; } @@ -904,7 +894,7 @@ uint16 GetAnimStationCallback(CallbackID callback, uint32 param1, uint32 param2, } /** Helper class for animation control. */ -struct StationAnimationBase : public AnimationBase { +struct StationAnimationBase : public AnimationBase > { static const CallbackID cb_animation_speed = CBID_STATION_ANIMATION_SPEED; static const CallbackID cb_animation_next_frame = CBID_STATION_ANIM_NEXT_FRAME; @@ -948,7 +938,7 @@ void TriggerStationAnimation(BaseStation *st, TileIndex trigger_tile, StationAni } else { cargo = ss->grf_prop.grffile->cargo_map[cargo_type]; } - StationAnimationBase::ChangeAnimationFrame(CBID_STATION_ANIM_START_STOP, ss, st, tile, (random_bits << 16) | Random(), (uint8)trigger | (cargo << 8)); + StationAnimationBase::ChangeAnimationFrame(CBID_STATION_ANIM_START_STOP, ss, st, tile, (random_bits << 16) | GB(Random(), 0, 16), (uint8)trigger | (cargo << 8)); } } } @@ -1050,7 +1040,7 @@ void StationUpdateCachedTriggers(BaseStation *st) /* Combine animation trigger bitmask for all station specs * of this station. */ - for (uint i = 0; i < st->num_specs; i++) { + for (uint i = 0; i < st->speclist.size(); i++) { const StationSpec *ss = st->speclist[i].spec; if (ss != nullptr) { st->cached_anim_triggers |= ss->animation.triggers; diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index 6617365f9c4ed..3c2d2294689ff 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.cpp @@ -860,6 +860,7 @@ uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const switch (scc) { default: break; + /* These control codes take one string parameter, check there are at least that many available. */ case SCC_NEWGRF_PRINT_DWORD_SIGNED: case SCC_NEWGRF_PRINT_WORD_SIGNED: case SCC_NEWGRF_PRINT_BYTE_SIGNED: @@ -889,6 +890,7 @@ uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const } break; + /* These string code take two string parameters, check there are at least that many available. */ case SCC_NEWGRF_PRINT_WORD_CARGO_LONG: case SCC_NEWGRF_PRINT_WORD_CARGO_SHORT: case SCC_NEWGRF_PRINT_WORD_CARGO_TINY: @@ -900,6 +902,8 @@ uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const } if (_newgrf_textrefstack.used && modify_argv) { + /* There is data on the NewGRF text stack, and we want to move them to OpenTTD's string stack. + * After this call, a new call is made with `modify_argv` set to false when the string is finally formatted. */ switch (scc) { default: NOT_REACHED(); case SCC_NEWGRF_PRINT_BYTE_SIGNED: *argv = _newgrf_textrefstack.PopSignedByte(); break; @@ -927,6 +931,7 @@ uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const case SCC_NEWGRF_PRINT_DWORD_DATE_SHORT: case SCC_NEWGRF_PRINT_DWORD_HEX: *argv = _newgrf_textrefstack.PopUnsignedDWord(); break; + /* Dates from NewGRFs have 1920-01-01 as their zero point, convert it to OpenTTD's epoch. */ case SCC_NEWGRF_PRINT_WORD_DATE_LONG: case SCC_NEWGRF_PRINT_WORD_DATE_SHORT: *argv = _newgrf_textrefstack.PopUnsignedWord() + DAYS_TILL_ORIGINAL_BASE_YEAR; break; @@ -954,7 +959,7 @@ uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const } } } else { - /* Consume additional parameter characters */ + /* Consume additional parameter characters that follow the NewGRF string code. */ switch (scc) { default: break; @@ -965,6 +970,7 @@ uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const } } + /* Emit OpenTTD's internal string code for the different NewGRF variants. */ switch (scc) { default: NOT_REACHED(); case SCC_NEWGRF_PRINT_DWORD_SIGNED: @@ -1027,6 +1033,7 @@ uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const case SCC_NEWGRF_PRINT_WORD_STATION_NAME: return SCC_STATION_NAME; + /* These NewGRF string codes modify the NewGRF stack or otherwise do not map to OpenTTD string codes. */ case SCC_NEWGRF_DISCARD_WORD: case SCC_NEWGRF_ROTATE_TOP_4_WORDS: case SCC_NEWGRF_PUSH_WORD: diff --git a/src/news_gui.cpp b/src/news_gui.cpp index ee0e17fac03c1..ab3bfadb927c3 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -267,6 +267,7 @@ struct NewsWindow : Window { const NewsItem *ni; ///< News item to display. static int duration; ///< Remaining time for showing the current news message (may only be access while a news item is displayed). + static const uint TIMER_INTERVAL = 210; ///< Scrolling interval, scaled by line text line height. This value chosen to maintain the 15ms at normal zoom. GUITimer timer; NewsWindow(WindowDesc *desc, const NewsItem *ni) : Window(desc), ni(ni) @@ -278,8 +279,6 @@ struct NewsWindow : Window { this->flags |= WF_DISABLE_VP_SCROLL; - this->timer.SetInterval(15); - this->CreateNestedTree(); /* For company news with a face we have a separate headline in param[0] */ @@ -311,7 +310,7 @@ struct NewsWindow : Window { /* Initialize viewport if it exists. */ NWidgetViewport *nvp = this->GetWidget(WID_N_VIEWPORT); if (nvp != nullptr) { - nvp->InitializeViewport(this, ni->reftype1 == NR_VEHICLE ? 0x80000000 | ni->ref1 : (uint32)GetReferenceTile(ni->reftype1, ni->ref1), ZOOM_LVL_NEWS); + nvp->InitializeViewport(this, ni->reftype1 == NR_VEHICLE ? 0x80000000 | ni->ref1 : (uint32)GetReferenceTile(ni->reftype1, ni->ref1),ScaleZoomGUI(ZOOM_LVL_NEWS)); if (this->ni->flags & NF_NO_TRANSPARENT) nvp->disp_flags |= ND_NO_TRANSPARENCY; if ((this->ni->flags & NF_INCOLOUR) == 0) { nvp->disp_flags |= ND_SHADE_GREY; @@ -323,14 +322,21 @@ struct NewsWindow : Window { PositionNewsMessage(this); } - void DrawNewsBorder(const Rect &r) const + void OnInit() override { - GfxFillRect(r.left, r.top, r.right, r.bottom, PC_WHITE); + this->timer.SetInterval(TIMER_INTERVAL / FONT_HEIGHT_NORMAL); + } - GfxFillRect(r.left, r.top, r.left, r.bottom, PC_BLACK); - GfxFillRect(r.right, r.top, r.right, r.bottom, PC_BLACK); - GfxFillRect(r.left, r.top, r.right, r.top, PC_BLACK); - GfxFillRect(r.left, r.bottom, r.right, r.bottom, PC_BLACK); + void DrawNewsBorder(const Rect &r) const + { + Rect ir = r.Shrink(WidgetDimensions::scaled.bevel); + GfxFillRect(ir, PC_WHITE); + + ir = ir.Expand(1); + GfxFillRect( r.left, r.top, ir.left, r.bottom, PC_BLACK); + GfxFillRect(ir.right, r.top, r.right, r.bottom, PC_BLACK); + GfxFillRect( r.left, r.top, r.right, ir.top, PC_BLACK); + GfxFillRect( r.left, ir.bottom, r.right, r.bottom, PC_BLACK); } Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override @@ -347,7 +353,7 @@ struct NewsWindow : Window { /* Caption is not a real caption (so that the window cannot be moved) * thus it doesn't get the default sizing of a caption. */ Dimension d2 = GetStringBoundingBox(STR_NEWS_MESSAGE_CAPTION); - d2.height += WD_CAPTIONTEXT_TOP + WD_CAPTIONTEXT_BOTTOM; + d2.height += WidgetDimensions::scaled.captiontext.Vertical(); *size = maxdim(*size, d2); return; } @@ -385,8 +391,8 @@ struct NewsWindow : Window { case WID_N_SHOW_GROUP: if (this->ni->reftype1 == NR_VEHICLE) { Dimension d2 = GetStringBoundingBox(this->GetWidget(WID_N_SHOW_GROUP)->widget_data); - d2.height += WD_CAPTIONTEXT_TOP + WD_CAPTIONTEXT_BOTTOM; - d2.width += WD_CAPTIONTEXT_LEFT + WD_CAPTIONTEXT_RIGHT; + d2.height += WidgetDimensions::scaled.captiontext.Vertical(); + d2.width += WidgetDimensions::scaled.captiontext.Horizontal(); *size = d2; } else { /* Hide 'Show group window' button if this news is not about a vehicle. */ @@ -462,7 +468,7 @@ struct NewsWindow : Window { case WID_N_VEH_SPR: { assert(this->ni->reftype1 == NR_ENGINE); EngineID engine = this->ni->ref1; - DrawVehicleEngine(r.left, r.right, (r.left + r.right) / 2, (r.top + r.bottom) / 2, engine, GetEnginePalette(engine, _local_company), EIT_PREVIEW); + DrawVehicleEngine(r.left, r.right, CenterBounds(r.left, r.right, 0), CenterBounds(r.top, r.bottom, 0), engine, GetEnginePalette(engine, _local_company), EIT_PREVIEW); GfxFillRect(r.left, r.top, r.right, r.bottom, PALETTE_NEWSPAPER, FILLRECT_RECOLOUR); break; } @@ -520,6 +526,18 @@ struct NewsWindow : Window { } } + void OnResize() override + { + if (this->viewport != nullptr) { + NWidgetViewport *nvp = this->GetWidget(WID_N_VIEWPORT); + nvp->UpdateViewportCoordinates(this); + + if (ni->reftype1 != NR_VEHICLE) { + ScrollWindowToTile(GetReferenceTile(ni->reftype1, ni->ref1), this, true); // Re-center viewport. + } + } + } + /** * Some data on this window has become invalid. * @param data Information about the changed data. @@ -583,7 +601,7 @@ struct NewsWindow : Window { return STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE; case WID_N_VEH_NAME: - SetDParam(0, engine); + SetDParam(0, PackEngineNameDParam(engine, EngineNameContext::PreviewNews)); return STR_NEWS_NEW_VEHICLE_TYPE; default: @@ -1119,9 +1137,6 @@ static void DrawNewsString(uint left, uint right, int y, TextColour colour, cons } struct MessageHistoryWindow : Window { - static const int top_spacing; ///< Additional spacing at the top of the #WID_MH_BACKGROUND widget. - static const int bottom_spacing; ///< Additional spacing at the bottom of the #WID_MH_BACKGROUND widget. - int line_height; /// < Height of a single line in the news history window including spacing. int date_width; /// < Width needed for the date part. @@ -1138,15 +1153,15 @@ struct MessageHistoryWindow : Window { void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_MH_BACKGROUND) { - this->line_height = FONT_HEIGHT_NORMAL + 2; + this->line_height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; resize->height = this->line_height; /* Months are off-by-one, so it's actually 8. Not using * month 12 because the 1 is usually less wide. */ SetDParam(0, ConvertYMDToDate(ORIGINAL_MAX_YEAR, 7, 30)); - this->date_width = GetStringBoundingBox(STR_SHORT_DATE).width; + this->date_width = GetStringBoundingBox(STR_SHORT_DATE).width + WidgetDimensions::scaled.hsep_wide; - size->height = 4 * resize->height + this->top_spacing + this->bottom_spacing; // At least 4 lines are visible. + size->height = 4 * resize->height + WidgetDimensions::scaled.framerect.Vertical(); // At least 4 lines are visible. size->width = std::max(200u, size->width); // At least 200 pixels wide. } } @@ -1169,17 +1184,15 @@ struct MessageHistoryWindow : Window { } /* Fill the widget with news items. */ - int y = r.top + this->top_spacing; bool rtl = _current_text_dir == TD_RTL; - uint date_left = rtl ? r.right - WD_FRAMERECT_RIGHT - this->date_width : r.left + WD_FRAMERECT_LEFT; - uint date_right = rtl ? r.right - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT + this->date_width; - uint news_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.left + WD_FRAMERECT_LEFT + this->date_width + WD_FRAMERECT_RIGHT + ScaleFontTrad(5); - uint news_right = rtl ? r.right - WD_FRAMERECT_RIGHT - this->date_width - WD_FRAMERECT_RIGHT - ScaleFontTrad(5) : r.right - WD_FRAMERECT_RIGHT; + Rect news = r.Shrink(WidgetDimensions::scaled.framerect).Indent(this->date_width + WidgetDimensions::scaled.hsep_wide, rtl); + Rect date = r.Shrink(WidgetDimensions::scaled.framerect).WithWidth(this->date_width, rtl); + int y = news.top; for (int n = this->vscroll->GetCapacity(); n > 0; n--) { SetDParam(0, ni->date); - DrawString(date_left, date_right, y, STR_SHORT_DATE); + DrawString(date.left, date.right, y, STR_SHORT_DATE); - DrawNewsString(news_left, news_right, y, TC_WHITE, ni); + DrawNewsString(news.left, news.right, y, TC_WHITE, ni); y += this->line_height; ni = ni->prev; @@ -1204,7 +1217,7 @@ struct MessageHistoryWindow : Window { NewsItem *ni = _latest_news; if (ni == nullptr) return; - for (int n = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_MH_BACKGROUND, WD_FRAMERECT_TOP); n > 0; n--) { + for (int n = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_MH_BACKGROUND, WidgetDimensions::scaled.framerect.top); n > 0; n--) { ni = ni->prev; if (ni == nullptr) return; } @@ -1219,9 +1232,6 @@ struct MessageHistoryWindow : Window { } }; -const int MessageHistoryWindow::top_spacing = WD_FRAMERECT_TOP + 4; -const int MessageHistoryWindow::bottom_spacing = WD_FRAMERECT_BOTTOM; - static const NWidgetPart _nested_message_history[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index b6ea0b40844e9..5f37b6d1c7b15 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -61,7 +61,7 @@ uint16 Object::counts[NUM_OBJECTS]; * @pre IsTileType(t, MP_OBJECT) * @return the type. */ -ObjectType GetObjectType(TileIndex t) +ObjectType GetObjectType(Tile t) { assert(IsTileType(t, MP_OBJECT)); return Object::GetByTile(t)->type; @@ -311,6 +311,7 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, ObjectType type, } int hq_score = 0; + uint build_object_size = 1; switch (type) { case OBJECT_TRANSMITTER: case OBJECT_LIGHTHOUSE: @@ -328,6 +329,8 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, ObjectType type, case OBJECT_HQ: { Company *c = Company::Get(_current_company); if (c->location_of_HQ != INVALID_TILE) { + /* Don't relocate HQ on the same location. */ + if (c->location_of_HQ == tile) return_cmd_error(STR_ERROR_ALREADY_BUILT); /* We need to persuade a bit harder to remove the old HQ. */ _current_company = OWNER_WATER; cost.AddCost(ClearTile_Object(c->location_of_HQ, flags)); @@ -347,20 +350,84 @@ CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, ObjectType type, return CMD_ERROR; default: // i.e. NewGRF provided. + build_object_size = size_x * size_y; break; } + /* Don't allow building more objects if the company has reached its limit. */ + Company *c = Company::GetIfValid(_current_company); + if (c != nullptr && GB(c->build_object_limit, 16, 16) < build_object_size) { + return_cmd_error(STR_ERROR_BUILD_OBJECT_LIMIT_REACHED); + } + if (flags & DC_EXEC) { BuildObject(type, tile, _current_company == OWNER_DEITY ? OWNER_NONE : _current_company, nullptr, view); /* Make sure the HQ starts at the right size. */ if (type == OBJECT_HQ) UpdateCompanyHQ(tile, hq_score); + + /* Subtract the tile from the build limit. */ + if (c != nullptr) c->build_object_limit -= build_object_size << 16; } - cost.AddCost(ObjectSpec::Get(type)->GetBuildCost() * size_x * size_y); + cost.AddCost(spec->GetBuildCost() * build_object_size); return cost; } +/** + * Construct multiple objects in an area + * @param flags of operation to conduct + * @param tile end tile of area dragging + * @param start_tile start tile of area dragging + * @param type the object type to build + * @param view the view for the object + * @param diagonal Whether to use the Orthogonal (0) or Diagonal (1) iterator. + * @return the cost of this operation or an error + */ +CommandCost CmdBuildObjectArea(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, ObjectType type, uint8 view, bool diagonal) +{ + if (start_tile >= Map::Size()) return CMD_ERROR; + + if (type >= NUM_OBJECTS) return CMD_ERROR; + const ObjectSpec *spec = ObjectSpec::Get(type); + if (view >= spec->views) return CMD_ERROR; + + if (spec->size != OBJECT_SIZE_1X1) return CMD_ERROR; + + Money money = GetAvailableMoneyForCommand(); + CommandCost cost(EXPENSES_CONSTRUCTION); + CommandCost last_error = CMD_ERROR; + bool had_success = false; + + const Company *c = Company::GetIfValid(_current_company); + int limit = (c == nullptr ? INT32_MAX : GB(c->build_object_limit, 16, 16)); + + std::unique_ptr iter = TileIterator::Create(tile, start_tile, diagonal); + for (; *iter != INVALID_TILE; ++(*iter)) { + TileIndex t = *iter; + CommandCost ret = Command::Do(flags & ~DC_EXEC, t, type, view); + + /* If we've reached the limit, stop building (or testing). */ + if (c != nullptr && limit-- <= 0) break; + + if (ret.Failed()) { + last_error = ret; + continue; + } + + had_success = true; + if (flags & DC_EXEC) { + money -= ret.GetCost(); + + /* If we run out of money, stop building. */ + if (ret.GetCost() > 0 && money < 0) break; + Command::Do(flags, t, type, view); + } + cost.AddCost(ret); + } + + return had_success ? cost : last_error; +} static Foundation GetFoundation_Object(TileIndex tile, Slope tileh); @@ -370,7 +437,7 @@ static void DrawTile_Object(TileInfo *ti) const ObjectSpec *spec = ObjectSpec::Get(type); /* Fall back for when the object doesn't exist anymore. */ - if (!spec->enabled) type = OBJECT_TRANSMITTER; + if (!spec->IsEnabled()) type = OBJECT_TRANSMITTER; if ((spec->flags & OBJECT_FLAG_HAS_NO_FOUNDATION) == 0) DrawFoundation(ti, GetFoundation_Object(ti->tile, ti->tileh)); @@ -668,8 +735,8 @@ static bool HasTransmitter(TileIndex tile, void *user) */ static bool TryBuildLightHouse() { - uint maxx = MapMaxX(); - uint maxy = MapMaxY(); + uint maxx = Map::MaxX(); + uint maxy = Map::MaxY(); uint r = Random(); /* Scatter the lighthouses more evenly around the perimeter */ @@ -695,7 +762,7 @@ static bool TryBuildLightHouse() int h; if (IsTileType(tile, MP_CLEAR) && IsTileFlat(tile, &h) && h <= 2 && !IsBridgeAbove(tile)) { BuildObject(OBJECT_LIGHTHOUSE, tile); - assert(tile < MapSize()); + assert(tile < Map::Size()); return true; } tile += TileOffsByDiagDir(dir); @@ -730,13 +797,13 @@ void GenerateObjects() /* Determine number of water tiles at map border needed for freeform_edges */ uint num_water_tiles = 0; if (_settings_game.construction.freeform_edges) { - for (uint x = 0; x < MapMaxX(); x++) { + for (uint x = 0; x < Map::MaxX(); x++) { if (IsTileType(TileXY(x, 1), MP_WATER)) num_water_tiles++; - if (IsTileType(TileXY(x, MapMaxY() - 1), MP_WATER)) num_water_tiles++; + if (IsTileType(TileXY(x, Map::MaxY() - 1), MP_WATER)) num_water_tiles++; } - for (uint y = 1; y < MapMaxY() - 1; y++) { + for (uint y = 1; y < Map::MaxY() - 1; y++) { if (IsTileType(TileXY(1, y), MP_WATER)) num_water_tiles++; - if (IsTileType(TileXY(MapMaxX() - 1, y), MP_WATER)) num_water_tiles++; + if (IsTileType(TileXY(Map::MaxX() - 1, y), MP_WATER)) num_water_tiles++; } } @@ -754,15 +821,15 @@ void GenerateObjects() /* Scale the amount of lighthouses with the amount of land at the borders. * The -6 is because the top borders are MP_VOID (-2) and all corners * are counted twice (-4). */ - amount = ScaleByMapSize1D(amount * num_water_tiles) / (2 * MapMaxY() + 2 * MapMaxX() - 6); + amount = Map::ScaleBySize1D(amount * num_water_tiles) / (2 * Map::MaxY() + 2 * Map::MaxX() - 6); } else if (spec->flags & OBJECT_FLAG_SCALE_BY_WATER) { - amount = ScaleByMapSize1D(amount); + amount = Map::ScaleBySize1D(amount); } else { - amount = ScaleByMapSize(amount); + amount = Map::ScaleBySize(amount); } /* Now try to place the requested amount of this object */ - for (uint j = ScaleByMapSize(1000); j != 0 && amount != 0 && Object::CanAllocateItem(); j--) { + for (uint j = Map::ScaleBySize(1000); j != 0 && amount != 0 && Object::CanAllocateItem(); j--) { switch (i) { case OBJECT_TRANSMITTER: if (TryBuildTransmitter()) amount--; @@ -839,7 +906,7 @@ static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlag flags, int /* If the callback fails, allow autoslope. */ uint16 res = GetObjectCallback(CBID_OBJECT_AUTOSLOPE, 0, 0, spec, Object::GetByTile(tile), tile); if (res == CALLBACK_FAILED || !ConvertBooleanCallback(spec->grf_prop.grffile, CBID_OBJECT_AUTOSLOPE, res)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); - } else if (spec->enabled) { + } else if (spec->IsEnabled()) { /* allow autoslope */ return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); } diff --git a/src/object_cmd.h b/src/object_cmd.h index ea7412544c001..43ba0459259ce 100644 --- a/src/object_cmd.h +++ b/src/object_cmd.h @@ -14,7 +14,9 @@ #include "object_type.h" CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, ObjectType type, uint8 view); +CommandCost CmdBuildObjectArea(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, ObjectType type, uint8 view, bool diagonal); DEF_CMD_TRAIT(CMD_BUILD_OBJECT, CmdBuildObject, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_BUILD_OBJECT_AREA, CmdBuildObjectArea, CMD_DEITY | CMD_NO_WATER | CMD_NO_TEST | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) #endif /* OBJECT_CMD_H */ diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 9726aae667848..f45f2ae42690a 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -48,8 +48,8 @@ class BuildObjectWindow : public Window { typedef GUIList GUIObjectClassList; ///< Type definition for the list to hold available object classes. static const uint EDITBOX_MAX_SIZE = 16; ///< The maximum number of characters for the filter edit box. - static const int OBJECT_MARGIN = 4; ///< The margin (in pixels) around an object. + int object_margin; ///< The margin (in pixels) around an object. int line_height; ///< The height of a single line. int info_height; ///< The height of the info box. Scrollbar *vscroll; ///< The scrollbar. @@ -119,6 +119,7 @@ class BuildObjectWindow : public Window { NWidgetMatrix *matrix = this->GetWidget(WID_BO_SELECT_MATRIX); matrix->SetScrollbar(this->GetScrollbar(WID_BO_SELECT_SCROLL)); + matrix->SetCount(ObjectClass::Get(_selected_object_class)->GetUISpecCount()); this->GetWidget(WID_BO_OBJECT_MATRIX)->SetCount(4); @@ -229,6 +230,11 @@ class BuildObjectWindow : public Window { } } + void OnInit() override + { + this->object_margin = ScaleGUITrad(4); + } + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { @@ -239,7 +245,7 @@ class BuildObjectWindow : public Window { size->width = std::max(size->width, GetStringBoundingBox(objclass->name).width); } size->width += padding.width; - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = FONT_HEIGHT_NORMAL + padding.height; resize->height = this->line_height; size->height = 5 * this->line_height; break; @@ -266,7 +272,7 @@ class BuildObjectWindow : public Window { case WID_BO_OBJECT_SPRITE: { bool two_wide = false; // Whether there will be two widgets next to each other in the matrix or not. - int height[2] = {0, 0}; // The height for the different views; in this case views 1/2 and 4. + uint height[2] = {0, 0}; // The height for the different views; in this case views 1/2 and 4. /* Get the height and view information. */ for (int i = 0; i < NUM_OBJECTS; i++) { @@ -279,26 +285,28 @@ class BuildObjectWindow : public Window { /* Determine the pixel heights. */ for (size_t i = 0; i < lengthof(height); i++) { height[i] *= ScaleGUITrad(TILE_HEIGHT); - height[i] += ScaleGUITrad(TILE_PIXELS) + 2 * OBJECT_MARGIN; + height[i] += ScaleGUITrad(TILE_PIXELS) + 2 * this->object_margin; } /* Now determine the size of the minimum widgets. When there are two columns, then * we want these columns to be slightly less wide. When there are two rows, then * determine the size of the widgets based on the maximum size for a single row * of widgets, or just the twice the widget height of the two row ones. */ - size->height = std::max(height[0], height[1] * 2 + 2); + size->height = std::max(height[0], height[1] * 2); if (two_wide) { - size->width = (3 * ScaleGUITrad(TILE_PIXELS) + 2 * OBJECT_MARGIN) * 2 + 2; + size->width = (3 * ScaleGUITrad(TILE_PIXELS) + 2 * this->object_margin) * 2; } else { - size->width = 4 * ScaleGUITrad(TILE_PIXELS) + 2 * OBJECT_MARGIN; + size->width = 4 * ScaleGUITrad(TILE_PIXELS) + 2 * this->object_margin; } /* Get the right size for the single widget based on the current spec. */ ObjectClass *objclass = ObjectClass::Get(_selected_object_class); const ObjectSpec *spec = objclass->GetSpec(_selected_object_index); if (spec != nullptr) { - if (spec->views >= 2) size->width = size->width / 2 - 1; - if (spec->views >= 4) size->height = size->height / 2 - 1; + if (spec->views <= 1) size->width += WidgetDimensions::scaled.hsep_normal; + if (spec->views <= 2) size->height += WidgetDimensions::scaled.vsep_normal; + if (spec->views >= 2) size->width /= 2; + if (spec->views >= 4) size->height /= 2; } break; } @@ -313,8 +321,8 @@ class BuildObjectWindow : public Window { break; case WID_BO_SELECT_IMAGE: - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(58) + 2; + size->width = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Horizontal(); + size->height = ScaleGUITrad(58) + WidgetDimensions::scaled.fullbevel.Vertical(); break; default: break; @@ -325,15 +333,15 @@ class BuildObjectWindow : public Window { { switch (GB(widget, 0, 16)) { case WID_BO_CLASS_LIST: { - int y = r.top; + Rect mr = r.Shrink(WidgetDimensions::scaled.matrix); uint pos = 0; for (auto object_class_id : this->object_classes) { ObjectClass *objclass = ObjectClass::Get(object_class_id); if (objclass->GetUISpecCount() == 0) continue; if (!this->vscroll->IsVisible(pos++)) continue; - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, objclass->name, + DrawString(mr, objclass->name, (object_class_id == _selected_object_class) ? TC_WHITE : TC_BLACK); - y += this->line_height; + mr.top += this->line_height; } break; } @@ -354,17 +362,15 @@ class BuildObjectWindow : public Window { DrawPixelInfo tmp_dpi; /* Set up a clipping area for the preview. */ - if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); if (spec->grf_prop.grffile == nullptr) { extern const DrawTileSprites _objects[]; const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; - DrawOrigTileSeqInGUI((r.right - r.left) / 2 - 1, (r.bottom - r.top + matrix_height / 2) / 2 - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), dts, PAL_NONE); + DrawOrigTileSeqInGUI(r.Width() / 2 - 1, (r.Height() + matrix_height / 2) / 2 - this->object_margin - ScaleSpriteTrad(TILE_PIXELS), dts, PAL_NONE); } else { - DrawNewObjectTileInGUI((r.right - r.left) / 2 - 1, (r.bottom - r.top + matrix_height / 2) / 2 - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), spec, GB(widget, 16, 16)); + DrawNewObjectTileInGUI(r.Width() / 2 - 1, (r.Height() + matrix_height / 2) / 2 - this->object_margin - ScaleSpriteTrad(TILE_PIXELS), spec, GB(widget, 16, 16)); } - _cur_dpi = old_dpi; } break; } @@ -377,22 +383,20 @@ class BuildObjectWindow : public Window { if (spec == nullptr) break; if (!spec->IsAvailable()) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), PC_BLACK, FILLRECT_CHECKER); } DrawPixelInfo tmp_dpi; /* Set up a clipping area for the preview. */ - if (FillDrawPixelInfo(&tmp_dpi, r.left + 1, r.top, (r.right - 1) - (r.left + 1) + 1, r.bottom - r.top + 1)) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); if (spec->grf_prop.grffile == nullptr) { extern const DrawTileSprites _objects[]; const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; - DrawOrigTileSeqInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), dts, PAL_NONE); + DrawOrigTileSeqInGUI(r.Width() / 2 - 1, r.Height() - this->object_margin - ScaleSpriteTrad(TILE_PIXELS), dts, PAL_NONE); } else { - DrawNewObjectTileInGUI((r.right - r.left) / 2 - 1, r.bottom - r.top - OBJECT_MARGIN - ScaleGUITrad(TILE_PIXELS), spec, + DrawNewObjectTileInGUI(r.Width() / 2 - 1, r.Height() - this->object_margin - ScaleSpriteTrad(TILE_PIXELS), spec, std::min(_selected_object_view, spec->views - 1)); } - _cur_dpi = old_dpi; } break; } @@ -415,11 +419,11 @@ class BuildObjectWindow : public Window { /* Use all the available space left from where we stand up to the * end of the window. We ALSO enlarge the window if needed, so we * can 'go' wild with the bottom of the window. */ - int y = DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, message, TC_ORANGE) - r.top; + int y = DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, message, TC_ORANGE) - r.top - 1; StopTextRefStackUsage(); if (y > this->info_height) { BuildObjectWindow *bow = const_cast(this); - bow->info_height = y + 2; + bow->info_height = y; bow->ReInit(); } } @@ -458,7 +462,7 @@ class BuildObjectWindow : public Window { } if (_selected_object_index != -1) { - SetObjectToPlaceWnd(SPR_CURSOR_TRANSMITTER, PAL_NONE, HT_RECT, this); + SetObjectToPlaceWnd(SPR_CURSOR_TRANSMITTER, PAL_NONE, HT_RECT | HT_DIAGONAL, this); } this->UpdateButtons(_selected_object_class, _selected_object_index, _selected_object_view); @@ -543,9 +547,38 @@ class BuildObjectWindow : public Window { void OnPlaceObject(Point pt, TileIndex tile) override { - ObjectClass *objclass = ObjectClass::Get(_selected_object_class); - Command::Post(STR_ERROR_CAN_T_BUILD_OBJECT, CcPlaySound_CONSTRUCTION_OTHER, - tile, objclass->GetSpec(_selected_object_index)->Index(), _selected_object_view); + const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index); + + if (spec->size == OBJECT_SIZE_1X1) { + VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_BUILD_OBJECT); + } else { + Command::Post(STR_ERROR_CAN_T_BUILD_OBJECT, CcPlaySound_CONSTRUCTION_OTHER, tile, spec->Index(), _selected_object_view); + } + } + + void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override + { + VpSelectTilesWithMethod(pt.x, pt.y, select_method); + } + + void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override + { + if (pt.x == -1) return; + + switch (select_proc) { + default: NOT_REACHED(); + case DDSP_BUILD_OBJECT: + if (!_settings_game.construction.freeform_edges) { + /* When end_tile is MP_VOID, the error tile will not be visible to the + * user. This happens when terraforming at the southern border. */ + if (TileX(end_tile) == Map::MaxX()) end_tile += TileDiffXY(-1, 0); + if (TileY(end_tile) == Map::MaxY()) end_tile += TileDiffXY(0, -1); + } + const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index); + Command::Post(STR_ERROR_CAN_T_BUILD_OBJECT, CcPlaySound_CONSTRUCTION_OTHER, + end_tile, start_tile, spec->Index(), _selected_object_view, (_ctrl_pressed ? true : false)); + break; + } } void OnPlaceObjectAbort() override @@ -659,7 +692,9 @@ static const NWidgetPart _nested_build_object_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_OBJECT_BUILD_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN), NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN), + NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), NWidget(NWID_HORIZONTAL), SetPadding(2, 0, 0, 2), @@ -693,7 +728,7 @@ static const NWidgetPart _nested_build_object_widgets[] = { EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BO_INFO), SetPadding(0, 5, 0, 1), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BO_INFO), SetPadding(0, 5, 2, 2), SetFill(1, 0), SetResize(1, 0), NWidget(NWID_VERTICAL), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(0, 1), EndContainer(), NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN), diff --git a/src/object_map.h b/src/object_map.h index d86bf0690ee48..1a1af934442db 100644 --- a/src/object_map.h +++ b/src/object_map.h @@ -13,7 +13,7 @@ #include "water_map.h" #include "object_type.h" -ObjectType GetObjectType(TileIndex t); +ObjectType GetObjectType(Tile t); /** * Check whether the object on a tile is of a specific type. @@ -22,7 +22,7 @@ ObjectType GetObjectType(TileIndex t); * @pre IsTileType(t, MP_OBJECT) * @return True if type matches. */ -static inline bool IsObjectType(TileIndex t, ObjectType type) +static inline bool IsObjectType(Tile t, ObjectType type) { return GetObjectType(t) == type; } @@ -33,7 +33,7 @@ static inline bool IsObjectType(TileIndex t, ObjectType type) * @param type Type to test. * @return True if type matches. */ -static inline bool IsObjectTypeTile(TileIndex t, ObjectType type) +static inline bool IsObjectTypeTile(Tile t, ObjectType type) { return IsTileType(t, MP_OBJECT) && GetObjectType(t) == type; } @@ -44,10 +44,10 @@ static inline bool IsObjectTypeTile(TileIndex t, ObjectType type) * @pre IsTileType(t, MP_OBJECT) * @return The ObjectID of the object. */ -static inline ObjectID GetObjectIndex(TileIndex t) +static inline ObjectID GetObjectIndex(Tile t) { assert(IsTileType(t, MP_OBJECT)); - return _m[t].m2 | _m[t].m5 << 16; + return t.m2() | t.m5() << 16; } /** @@ -56,10 +56,10 @@ static inline ObjectID GetObjectIndex(TileIndex t) * @pre IsTileType(t, MP_OBJECT) * @return The random bits. */ -static inline byte GetObjectRandomBits(TileIndex t) +static inline byte GetObjectRandomBits(Tile t) { assert(IsTileType(t, MP_OBJECT)); - return _m[t].m3; + return t.m3(); } @@ -71,17 +71,17 @@ static inline byte GetObjectRandomBits(TileIndex t) * @param wc Water class for this object. * @param random Random data to store on the tile */ -static inline void MakeObject(TileIndex t, Owner o, ObjectID index, WaterClass wc, byte random) +static inline void MakeObject(Tile t, Owner o, ObjectID index, WaterClass wc, byte random) { SetTileType(t, MP_OBJECT); SetTileOwner(t, o); SetWaterClass(t, wc); - _m[t].m2 = index; - _m[t].m3 = random; - _m[t].m4 = 0; - _m[t].m5 = index >> 16; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; + t.m2() = index; + t.m3() = random; + t.m4() = 0; + t.m5() = index >> 16; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; } #endif /* OBJECT_MAP_H */ diff --git a/src/openttd.cpp b/src/openttd.cpp index 638e851e702de..4a7806384a595 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -13,6 +13,7 @@ #include "sound/sound_driver.hpp" #include "music/music_driver.hpp" #include "video/video_driver.hpp" +#include "mixer.h" #include "fontcache.h" #include "error.h" @@ -88,7 +89,10 @@ void ResetMusic(); void CallWindowGameTickEvent(); bool HandleBootstrap(); +extern void AfterLoadCompanyStats(); extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY); +extern void OSOpenBrowser(const char *url); +extern void RebuildTownCaches(); extern void ShowOSErrorBox(const char *buf, bool system); extern std::string _config_file; @@ -176,7 +180,7 @@ static void ShowHelp() "\n" "Command line options:\n" " -v drv = Set video driver (see below)\n" - " -s drv = Set sound driver (see below) (param bufsize,hz)\n" + " -s drv = Set sound driver (see below)\n" " -m drv = Set music driver (see below)\n" " -b drv = Set the blitter to use (see below)\n" " -r res = Set resolution (for instance 800x600)\n" @@ -227,12 +231,14 @@ static void ShowHelp() /* We need to initialize the AI, so it finds the AIs */ AI::Initialize(); - p = AI::GetConsoleList(p, lastof(buf), true); + const std::string ai_list = AI::GetConsoleList(true); + p = strecpy(p, ai_list.c_str(), lastof(buf)); AI::Uninitialize(true); /* We need to initialize the GameScript, so it finds the GSs */ Game::Initialize(); - p = Game::GetConsoleList(p, lastof(buf), true); + const std::string game_list = Game::GetConsoleList(true); + p = strecpy(p, game_list.c_str(), lastof(buf)); Game::Uninitialize(true); /* ShowInfo put output to stderr, but version information should go @@ -329,7 +335,7 @@ static void ShutdownGame() /* No NewGRFs were loaded when it was still bootstrapping. */ if (_game_mode != GM_BOOTSTRAP) ResetNewGRFData(); - UninitFreeType(); + UninitFontCache(); } /** @@ -399,7 +405,6 @@ void OpenBrowser(const char *url) /* Make sure we only accept urls that are sure to open a browser. */ if (strstr(url, "http://") != url && strstr(url, "https://") != url) return; - extern void OSOpenBrowser(const char *url); OSOpenBrowser(url); } @@ -450,8 +455,9 @@ struct AfterNewGRFScan : NewGRFScanCallback { /* We have loaded the config, so we may possibly save it. */ _save_config = save_config; - /* restore saved music volume */ + /* restore saved music and effects volumes */ MusicDriver::GetInstance()->SetVolume(_settings_client.music.music_vol); + SetEffectVolume(_settings_client.music.effect_vol); if (startyear != INVALID_YEAR) IConsoleSetSetting("game_creation.starting_year", startyear); if (generation_seed != GENERATE_NEW_SEED) _settings_newgame.game_creation.generation_seed = generation_seed; @@ -564,7 +570,7 @@ int openttd_main(int argc, char *argv[]) videodriver = "dedicated"; blitter = "null"; dedicated = true; - SetDebugString("net=4"); + SetDebugString("net=4", ShowInfo); if (mgo.opt != nullptr) { scanner->dedicated_host = ParseFullConnectionString(mgo.opt, scanner->dedicated_port); } @@ -588,7 +594,7 @@ int openttd_main(int argc, char *argv[]) #if defined(_WIN32) CreateConsole(); #endif - if (mgo.opt != nullptr) SetDebugString(mgo.opt); + if (mgo.opt != nullptr) SetDebugString(mgo.opt, ShowInfo); break; } case 'e': _switch_mode = (_switch_mode == SM_LOAD_GAME || _switch_mode == SM_LOAD_SCENARIO ? SM_LOAD_SCENARIO : SM_EDITOR); break; @@ -705,8 +711,8 @@ int openttd_main(int argc, char *argv[]) /* enumerate language files */ InitializeLanguagePacks(); - /* Initialize the regular font for FreeType */ - InitFreeType(false); + /* Initialize the font cache */ + InitFontCache(false); /* This must be done early, since functions use the SetWindowDirty* calls */ InitWindowSystem(); @@ -752,7 +758,9 @@ int openttd_main(int argc, char *argv[]) /* Initialize the zoom level of the screen to normal */ _screen.zoom = ZOOM_LVL_NORMAL; - UpdateGUIZoom(); + + /* The video driver is now selected, now initialise GUI zoom */ + AdjustGUIZoom(false); NetworkStartUp(); // initialize network-core @@ -961,37 +969,51 @@ bool SafeLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileTy _game_mode = newgm; - switch (lf == nullptr ? SaveOrLoad(filename, fop, dft, subdir) : LoadWithFilter(lf)) { - case SL_OK: return true; - - case SL_REINIT: - if (_network_dedicated) { - /* - * We need to reinit a network map... - * We can't simply load the intro game here as that game has many - * special cases which make clients desync immediately. So we fall - * back to just generating a new game with the current settings. - */ - Debug(net, 0, "Loading game failed, so a new (random) game will be started"); - MakeNewGame(false, true); - return false; - } - if (_network_server) { - /* We can't load the intro game as server, so disconnect first. */ - NetworkDisconnect(); - } + SaveOrLoadResult result = (lf == nullptr) ? SaveOrLoad(filename, fop, dft, subdir) : LoadWithFilter(lf); + if (result == SL_OK) return true; + + if (_network_dedicated && ogm == GM_MENU) { + /* + * If we are a dedicated server *and* we just were in the menu, then we + * are loading the first savegame. If that fails, not starting the + * server is a better reaction than starting the server with a newly + * generated map as it is quite likely to be started from a script. + */ + Debug(net, 0, "Loading requested map failed; closing server."); + _exit_game = true; + return false; + } - switch (ogm) { - default: - case GM_MENU: LoadIntroGame(); break; - case GM_EDITOR: MakeNewEditorWorld(); break; - } - return false; + if (result != SL_REINIT) { + _game_mode = ogm; + return false; + } + + if (_network_dedicated) { + /* + * If we are a dedicated server, have already loaded/started a game, + * and then loading the savegame fails in a manner that we need to + * reinitialize everything. We must not fall back into the menu mode + * with the intro game, as that is unjoinable by clients. So there is + * nothing else to do than start a new game, as it might have failed + * trying to reload the originally loaded savegame/scenario. + */ + Debug(net, 0, "Loading game failed, so a new (random) game will be started"); + MakeNewGame(false, true); + return false; + } + + if (_network_server) { + /* We can't load the intro game as server, so disconnect first. */ + NetworkDisconnect(); + } + switch (ogm) { default: - _game_mode = ogm; - return false; + case GM_MENU: LoadIntroGame(); break; + case GM_EDITOR: MakeNewEditorWorld(); break; } + return false; } void SwitchToMode(SwitchMode new_mode) @@ -1155,7 +1177,6 @@ static void CheckCaches() old_town_caches.push_back(t->cache); } - extern void RebuildTownCaches(); RebuildTownCaches(); RebuildSubsidisedSourceAndDestinationCache(); @@ -1171,7 +1192,6 @@ static void CheckCaches() std::vector old_infrastructure; for (const Company *c : Company::Iterate()) old_infrastructure.push_back(c->infrastructure); - extern void AfterLoadCompanyStats(); AfterLoadCompanyStats(); i = 0; @@ -1192,7 +1212,6 @@ static void CheckCaches() } for (Vehicle *v : Vehicle::Iterate()) { - extern void FillNewGRFVehicleCache(const Vehicle *v); if (v != v->First() || v->vehstatus & VS_CRASHED || !v->IsPrimaryVehicle()) continue; uint length = 0; @@ -1397,7 +1416,7 @@ void StateGameLoop() #ifndef DEBUG_DUMP_COMMANDS { - PerformanceMeasurer framerate(PFE_ALLSCRIPTS); + PerformanceMeasurer script_framerate(PFE_ALLSCRIPTS); AI::GameLoop(); Game::GameLoop(); } diff --git a/src/openttd.h b/src/openttd.h index 6473168ee1951..1534016fd6428 100644 --- a/src/openttd.h +++ b/src/openttd.h @@ -79,10 +79,13 @@ void AskExitGame(); void AskExitToGameMenu(); int openttd_main(int argc, char *argv[]); +void StateGameLoop(); void HandleExitGameRequest(); void SwitchToMode(SwitchMode new_mode); bool RequestNewGRFScan(struct NewGRFScanCallback *callback = nullptr); +void OpenBrowser(const char *url); + #endif /* OPENTTD_H */ diff --git a/src/order_backup.h b/src/order_backup.h index c92adbb411774..2795eba69faf8 100644 --- a/src/order_backup.h +++ b/src/order_backup.h @@ -26,9 +26,6 @@ typedef Pool OrderBackupPool; /** The pool with order backups. */ extern OrderBackupPool _order_backup_pool; -/** Flag to pass to the vehicle construction command when an order should be preserved. */ -static const uint32 MAKE_ORDER_BACKUP_FLAG = 1U << 31; - /** * Data for backing up an order of a vehicle so it can be * restored after a vehicle is rebuilt in the same depot. diff --git a/src/order_base.h b/src/order_base.h index 836ceb4b048eb..78b4b1ff60f2b 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -262,8 +262,6 @@ struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> { friend void AfterLoadVehicles(bool part_of_load); ///< For instantiating the shared vehicle chain friend SaveLoadTable GetOrderListDescription(); ///< Saving and loading of order lists. - StationID GetBestLoadableNext(const Vehicle *v, const Order *o1, const Order *o2) const; - Order *first; ///< First order of the order list. VehicleOrderID num_orders; ///< NOSAVE: How many orders there are in the list. VehicleOrderID num_manual_orders; ///< NOSAVE: How many manually added orders are there in the list. diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 474a68d09a2cb..3b0d6a1f3c14d 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -656,7 +656,7 @@ void OrderList::DebugCheckSanity() const static inline bool OrderGoesToStation(const Vehicle *v, const Order *o) { return o->IsType(OT_GOTO_STATION) || - (v->type == VEH_AIRCRAFT && o->IsType(OT_GOTO_DEPOT) && !(o->GetDepotActionType() & ODATFB_NEAREST_DEPOT)); + (v->type == VEH_AIRCRAFT && o->IsType(OT_GOTO_DEPOT) && o->GetDestination() != INVALID_STATION); } /** @@ -690,7 +690,7 @@ TileIndex Order::GetLocation(const Vehicle *v, bool airport) const return BaseStation::Get(this->GetDestination())->xy; case OT_GOTO_DEPOT: - if ((this->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) return INVALID_TILE; + if (this->GetDestination() == INVALID_DEPOT) return INVALID_TILE; return (v->type == VEH_AIRCRAFT) ? Station::Get(this->GetDestination())->xy : Depot::Get(this->GetDestination())->xy; default: @@ -754,13 +754,13 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se if (st == nullptr) return CMD_ERROR; if (st->owner != OWNER_NONE) { - CommandCost ret = CheckOwnership(st->owner); + ret = CheckOwnership(st->owner); if (ret.Failed()) return ret; } - if (!CanVehicleUseStation(v, st)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER); + if (!CanVehicleUseStation(v, st)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, GetVehicleCannotUseStationReason(v, st)); for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) { - if (!CanVehicleUseStation(u, st)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER_SHARED); + if (!CanVehicleUseStation(u, st)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER_SHARED, GetVehicleCannotUseStationReason(u, st)); } /* Non stop only allowed for ground vehicles. */ @@ -800,7 +800,7 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se if (st == nullptr) return CMD_ERROR; - CommandCost ret = CheckOwnership(st->owner); + ret = CheckOwnership(st->owner); if (ret.Failed()) return ret; if (!CanVehicleUseStation(v, st) || !st->airport.HasHangar()) { @@ -811,7 +811,7 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se if (dp == nullptr) return CMD_ERROR; - CommandCost ret = CheckOwnership(GetTileOwner(dp->xy)); + ret = CheckOwnership(GetTileOwner(dp->xy)); if (ret.Failed()) return ret; switch (v->type) { @@ -847,17 +847,17 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se default: return CMD_ERROR; case VEH_TRAIN: { - if (!(wp->facilities & FACIL_TRAIN)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER); + if (!(wp->facilities & FACIL_TRAIN)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_RAIL_WAYPOINT); - CommandCost ret = CheckOwnership(wp->owner); + ret = CheckOwnership(wp->owner); if (ret.Failed()) return ret; break; } case VEH_SHIP: - if (!(wp->facilities & FACIL_DOCK)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER); + if (!(wp->facilities & FACIL_DOCK)) return CommandCost(STR_ERROR_CAN_T_ADD_ORDER, STR_ERROR_NO_BUOY); if (wp->owner != OWNER_NONE) { - CommandCost ret = CheckOwnership(wp->owner); + ret = CheckOwnership(wp->owner); if (ret.Failed()) return ret; } break; @@ -1251,6 +1251,7 @@ CommandCost CmdModifyOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se if (sel_ord >= v->GetNumOrders()) return CMD_ERROR; Order *order = v->GetOrder(sel_ord); + assert(order != nullptr); switch (order->GetType()) { case OT_GOTO_STATION: if (mof != MOF_NON_STOP && mof != MOF_STOP_LOCATION && mof != MOF_UNLOAD && mof != MOF_LOAD) return CMD_ERROR; @@ -1513,7 +1514,7 @@ CommandCost CmdCloneOrder(DoCommandFlag flags, CloneOptions action, VehicleID ve /* Sanity checks */ if (src == nullptr || !src->IsPrimaryVehicle() || dst->type != src->type || dst == src) return CMD_ERROR; - CommandCost ret = CheckOwnership(src->owner); + ret = CheckOwnership(src->owner); if (ret.Failed()) return ret; /* Trucks can't share orders with busses (and visa versa) */ @@ -1532,7 +1533,7 @@ CommandCost CmdCloneOrder(DoCommandFlag flags, CloneOptions action, VehicleID ve * are temporarily invalid due to reconstruction. */ const Station *st = Station::Get(order->GetDestination()); if (CanVehicleUseStation(src, st) && !CanVehicleUseStation(dst, st)) { - return_cmd_error(STR_ERROR_CAN_T_COPY_SHARE_ORDER); + return CommandCost(STR_ERROR_CAN_T_COPY_SHARE_ORDER, GetVehicleCannotUseStationReason(dst, st)); } } @@ -1570,15 +1571,16 @@ CommandCost CmdCloneOrder(DoCommandFlag flags, CloneOptions action, VehicleID ve /* Sanity checks */ if (src == nullptr || !src->IsPrimaryVehicle() || dst->type != src->type || dst == src) return CMD_ERROR; - CommandCost ret = CheckOwnership(src->owner); + ret = CheckOwnership(src->owner); if (ret.Failed()) return ret; /* Trucks can't copy all the orders from busses (and visa versa), * and neither can helicopters and aircraft. */ for (const Order *order : src->Orders()) { - if (OrderGoesToStation(dst, order) && - !CanVehicleUseStation(dst, Station::Get(order->GetDestination()))) { - return_cmd_error(STR_ERROR_CAN_T_COPY_SHARE_ORDER); + if (!OrderGoesToStation(dst, order)) continue; + Station *st = Station::Get(order->GetDestination()); + if (!CanVehicleUseStation(dst, st)) { + return CommandCost(STR_ERROR_CAN_T_COPY_SHARE_ORDER, GetVehicleCannotUseStationReason(dst, st)); } } @@ -1771,12 +1773,9 @@ void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool /* Go through all vehicles */ for (Vehicle *v : Vehicle::Iterate()) { - Order *order; - - order = &v->current_order; - if ((v->type == VEH_AIRCRAFT && order->IsType(OT_GOTO_DEPOT) && !hangar ? OT_GOTO_STATION : order->GetType()) == type && + if ((v->type == VEH_AIRCRAFT && v->current_order.IsType(OT_GOTO_DEPOT) && !hangar ? OT_GOTO_STATION : v->current_order.GetType()) == type && (!hangar || v->type == VEH_AIRCRAFT) && v->current_order.GetDestination() == destination) { - order->MakeDummy(); + v->current_order.MakeDummy(); SetWindowDirty(WC_VEHICLE_VIEW, v->index); } @@ -1983,25 +1982,22 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) { /* We need to search for the nearest depot (hangar). */ - TileIndex location; - DestinationID destination; - bool reverse; + ClosestDepot closestDepot = v->FindClosestDepot(); - if (v->FindClosestDepot(&location, &destination, &reverse)) { + if (closestDepot.found) { /* PBS reservations cannot reverse */ - if (pbs_look_ahead && reverse) return false; + if (pbs_look_ahead && closestDepot.reverse) return false; - v->SetDestTile(location); - v->current_order.MakeGoToDepot(destination, v->current_order.GetDepotOrderType(), v->current_order.GetNonStopType(), (OrderDepotActionFlags)(v->current_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT), v->current_order.GetRefitCargo()); + v->SetDestTile(closestDepot.location); + v->current_order.SetDestination(closestDepot.destination); /* If there is no depot in front, reverse automatically (trains only) */ - if (v->type == VEH_TRAIN && reverse) Command::Do(DC_EXEC, v->index, false); + if (v->type == VEH_TRAIN && closestDepot.reverse) Command::Do(DC_EXEC, v->index, false); if (v->type == VEH_AIRCRAFT) { Aircraft *a = Aircraft::From(v); - if (a->state == FLYING && a->targetairport != destination) { + if (a->state == FLYING && a->targetairport != closestDepot.destination) { /* The aircraft is now heading for a different hangar than the next in the orders */ - extern void AircraftNextAirportPos_and_Order(Aircraft *a); AircraftNextAirportPos_and_Order(a); } } @@ -2143,7 +2139,6 @@ bool ProcessOrders(Vehicle *v) if (order == nullptr || (v->type == VEH_AIRCRAFT && !CheckForValidOrders(v))) { if (v->type == VEH_AIRCRAFT) { /* Aircraft do something vastly different here, so handle separately */ - extern void HandleMissingAircraftOrders(Aircraft *v); HandleMissingAircraftOrders(Aircraft::From(v)); return false; } diff --git a/src/order_cmd.h b/src/order_cmd.h index aeb42b624060a..5faf871056434 100644 --- a/src/order_cmd.h +++ b/src/order_cmd.h @@ -23,13 +23,13 @@ CommandCost CmdCloneOrder(DoCommandFlag flags, CloneOptions action, VehicleID ve CommandCost CmdMoveOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID moving_order, VehicleOrderID target_order); CommandCost CmdClearOrderBackup(DoCommandFlag flags, TileIndex tile, ClientID user_id); -DEF_CMD_TRAIT(CMD_MODIFY_ORDER, CmdModifyOrder, 0, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SKIP_TO_ORDER, CmdSkipToOrder, 0, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_DELETE_ORDER, CmdDeleteOrder, 0, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_INSERT_ORDER, CmdInsertOrder, 0, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_ORDER_REFIT, CmdOrderRefit, 0, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_CLONE_ORDER, CmdCloneOrder, 0, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_MOVE_ORDER, CmdMoveOrder, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_MODIFY_ORDER, CmdModifyOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SKIP_TO_ORDER, CmdSkipToOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_DELETE_ORDER, CmdDeleteOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_INSERT_ORDER, CmdInsertOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_ORDER_REFIT, CmdOrderRefit, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CLONE_ORDER, CmdCloneOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_MOVE_ORDER, CmdMoveOrder, CMD_LOCATION, CMDT_ROUTE_MANAGEMENT) DEF_CMD_TRAIT(CMD_CLEAR_ORDER_BACKUP, CmdClearOrderBackup, CMD_CLIENT_ID, CMDT_SERVER_SETTING) template diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 982c8f7b29269..db9074784bdf6 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -29,6 +29,9 @@ #include "aircraft.h" #include "engine_func.h" #include "vehicle_func.h" +#include "vehiclelist.h" +#include "vehicle_func.h" +#include "error.h" #include "order_cmd.h" #include "company_cmd.h" @@ -220,9 +223,11 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int SpriteID sprite = rtl ? SPR_ARROW_LEFT : SPR_ARROW_RIGHT; Dimension sprite_size = GetSpriteSize(sprite); if (v->cur_real_order_index == order_index) { + /* Draw two arrows before the next real order. */ DrawSprite(sprite, PAL_NONE, rtl ? right - sprite_size.width : left, y + ((int)FONT_HEIGHT_NORMAL - (int)sprite_size.height) / 2); DrawSprite(sprite, PAL_NONE, rtl ? right - 2 * sprite_size.width : left + sprite_size.width, y + ((int)FONT_HEIGHT_NORMAL - (int)sprite_size.height) / 2); } else if (v->cur_implicit_order_index == order_index) { + /* Draw one arrow before the next implicit order; the next real order will still get two arrows. */ DrawSprite(sprite, PAL_NONE, rtl ? right - sprite_size.width : left, y + ((int)FONT_HEIGHT_NORMAL - (int)sprite_size.height) / 2); } @@ -268,6 +273,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int SetDParam(2, order->GetDestination()); if (timetable) { + /* Show only wait time in the timetable window. */ SetDParam(3, STR_EMPTY); if (order->GetWaitTime() > 0) { @@ -275,6 +281,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int SetTimetableParams(6, 7, order->GetWaitTime()); } } else { + /* Show non-stop, refit and stop location only in the order window. */ SetDParam(3, (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) ? STR_EMPTY : _station_load_types[order->IsRefit()][unload][load]); if (order->IsRefit()) { SetDParam(4, order->IsAutoRefit() ? STR_ORDER_AUTO_REFIT_ANY : CargoSpec::Get(order->GetRefitCargo())->name); @@ -288,6 +295,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int case OT_GOTO_DEPOT: if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) { + /* Going to the nearest depot. */ SetDParam(0, STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT); if (v->type == VEH_AIRCRAFT) { SetDParam(2, STR_ORDER_NEAREST_HANGAR); @@ -297,6 +305,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int SetDParam(3, STR_ORDER_TRAIN_DEPOT + v->type); } } else { + /* Going to a specific depot. */ SetDParam(0, STR_ORDER_GO_TO_DEPOT_FORMAT); SetDParam(2, v->type); SetDParam(3, order->GetDestination()); @@ -308,10 +317,12 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int SetDParam(1, (order->GetNonStopType() & ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS) ? STR_ORDER_GO_NON_STOP_TO : STR_ORDER_GO_TO); } + /* Do not show stopping in the depot in the timetable window. */ if (!timetable && (order->GetDepotActionType() & ODATFB_HALT)) { SetDParam(5, STR_ORDER_STOP_ORDER); } + /* Do not show refitting in the depot in the timetable window. */ if (!timetable && order->IsRefit()) { SetDParam(5, (order->GetDepotActionType() & ODATFB_HALT) ? STR_ORDER_REFIT_STOP_ORDER : STR_ORDER_REFIT_ORDER); SetDParam(6, CargoSpec::Get(order->GetRefitCargo())->name); @@ -550,7 +561,7 @@ struct OrdersWindow : public Window { VehicleOrderID GetOrderFromPt(int y) { NWidgetBase *nwid = this->GetWidget(WID_O_ORDER_LIST); - uint sel = (y - nwid->pos_y - WD_FRAMERECT_TOP) / nwid->resize_y; // Selected line in the WID_O_ORDER_LIST panel. + uint sel = (y - nwid->pos_y - WidgetDimensions::scaled.framerect.top) / nwid->resize_y; // Selected line in the WID_O_ORDER_LIST panel. if (sel >= this->vscroll->GetCapacity()) return INVALID_VEH_ORDER_ID; @@ -619,7 +630,7 @@ struct OrdersWindow : public Window { Order order; order.next = nullptr; order.index = 0; - order.MakeGoToDepot(0, ODTFB_PART_OF_ORDERS, + order.MakeGoToDepot(INVALID_DEPOT, ODTFB_PART_OF_ORDERS, _settings_client.gui.new_nonstop && this->vehicle->IsGroundVehicle() ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); order.SetDepotActionType(ODATFB_NEAREST_DEPOT); @@ -793,7 +804,7 @@ struct OrdersWindow : public Window { switch (widget) { case WID_O_ORDER_LIST: resize->height = FONT_HEIGHT_NORMAL; - size->height = 6 * resize->height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + size->height = 6 * resize->height + padding.height; break; case WID_O_COND_VARIABLE: { @@ -1074,12 +1085,13 @@ struct OrdersWindow : public Window { { if (widget != WID_O_ORDER_LIST) return; + Rect ir = r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect); bool rtl = _current_text_dir == TD_RTL; SetDParamMaxValue(0, this->vehicle->GetNumOrders(), 2); - int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + 3; - int middle = rtl ? r.right - WD_FRAMETEXT_RIGHT - index_column_width : r.left + WD_FRAMETEXT_LEFT + index_column_width; + int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal; + int middle = rtl ? ir.right - index_column_width : ir.left + index_column_width; - int y = r.top + WD_FRAMERECT_TOP; + int y = ir.top; int line_height = this->GetWidget(WID_O_ORDER_LIST)->resize_y; int i = this->vscroll->GetPosition(); @@ -1092,10 +1104,10 @@ struct OrdersWindow : public Window { if (i != this->selected_order && i == this->order_over) { /* Highlight dragged order destination. */ - int top = (this->order_over < this->selected_order ? y : y + line_height) - WD_FRAMERECT_TOP; - int bottom = std::min(top + 2, r.bottom - WD_FRAMERECT_BOTTOM); - top = std::max(top - 3, r.top + WD_FRAMERECT_TOP); - GfxFillRect(r.left + WD_FRAMETEXT_LEFT, top, r.right - WD_FRAMETEXT_RIGHT, bottom, _colour_gradient[COLOUR_GREY][7]); + int top = (this->order_over < this->selected_order ? y : y + line_height) - WidgetDimensions::scaled.framerect.top; + int bottom = std::min(top + 2, ir.bottom); + top = std::max(top - 3, ir.top); + GfxFillRect(ir.left, top, ir.right, bottom, _colour_gradient[COLOUR_GREY][7]); break; } y += line_height; @@ -1105,7 +1117,7 @@ struct OrdersWindow : public Window { } /* Reset counters for drawing the orders. */ - y = r.top + WD_FRAMERECT_TOP; + y = ir.top; i = this->vscroll->GetPosition(); order = this->vehicle->GetOrder(i); } @@ -1115,7 +1127,7 @@ struct OrdersWindow : public Window { /* Don't draw anything if it extends past the end of the window. */ if (!this->vscroll->IsVisible(i)) break; - DrawOrderString(this->vehicle, order, i, y, i == this->selected_order, false, r.left + WD_FRAMETEXT_LEFT, middle, r.right - WD_FRAMETEXT_RIGHT); + DrawOrderString(this->vehicle, order, i, y, i == this->selected_order, false, ir.left, middle, ir.right); y += line_height; i++; @@ -1124,7 +1136,7 @@ struct OrdersWindow : public Window { if (this->vscroll->IsVisible(i)) { StringID str = this->vehicle->IsOrderListShared() ? STR_ORDERS_END_OF_SHARED_ORDERS : STR_ORDERS_END_OF_ORDERS; - DrawString(rtl ? r.left + WD_FRAMETEXT_LEFT : middle, rtl ? middle : r.right - WD_FRAMETEXT_RIGHT, y, str, (i == this->selected_order) ? TC_WHITE : TC_BLACK); + DrawString(rtl ? ir.left : middle, rtl ? middle : ir.right, y, str, (i == this->selected_order) ? TC_WHITE : TC_BLACK); } } @@ -1219,6 +1231,7 @@ struct OrdersWindow : public Window { this->OrderClick_Nonstop(-1); } else { const Order *o = this->vehicle->GetOrder(this->OrderGetSel()); + assert(o != nullptr); ShowDropDownMenu(this, _order_non_stop_drowdown, o->GetNonStopType(), WID_O_NON_STOP, 0, o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12)); } @@ -1295,12 +1308,14 @@ struct OrdersWindow : public Window { case WID_O_COND_COMPARATOR: { const Order *o = this->vehicle->GetOrder(this->OrderGetSel()); + assert(o != nullptr); ShowDropDownMenu(this, _order_conditional_condition, o->GetConditionComparator(), WID_O_COND_COMPARATOR, 0, (o->GetConditionVariable() == OCV_REQUIRES_SERVICE) ? 0x3F : 0xC0); break; } case WID_O_COND_VALUE: { const Order *order = this->vehicle->GetOrder(this->OrderGetSel()); + assert(order != nullptr); uint value = order->GetConditionValue(); if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value); SetDParam(0, value); @@ -1465,6 +1480,40 @@ struct OrdersWindow : public Window { return true; } + /** + * Clones an order list from a vehicle list. If this doesn't make sense (because not all vehicles in the list have the same orders), then it displays an error. + * @return This always returns true, which indicates that the contextual action handled the mouse click. + * Note that it's correct behaviour to always handle the click even though an error is displayed, + * because users aren't going to expect the default action to be performed just because they overlooked that cloning doesn't make sense. + */ + bool OnVehicleSelect(VehicleList::const_iterator begin, VehicleList::const_iterator end) override + { + bool share_order = _ctrl_pressed || this->goto_type == OPOS_SHARE; + if (this->vehicle->GetNumOrders() != 0 && !share_order) return false; + + if (!share_order) { + /* If CTRL is not pressed: If all the vehicles in this list have the same orders, then copy orders */ + if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) { + return VehiclesHaveSameOrderList(v1, v2); + })) { + OnVehicleSelect(*begin); + } else { + ShowErrorMessage(STR_ERROR_CAN_T_COPY_ORDER_LIST, STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST, WL_INFO); + } + } else { + /* If CTRL is pressed: If all the vehicles in this list share orders, then copy orders */ + if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) { + return v1->FirstShared() == v2->FirstShared(); + })) { + OnVehicleSelect(*begin); + } else { + ShowErrorMessage(STR_ERROR_CAN_T_SHARE_ORDER_LIST, STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST, WL_INFO); + } + } + + return true; + } + void OnPlaceObjectAbort() override { this->goto_type = OPOS_NONE; diff --git a/src/os/macosx/G5_detector.cpp b/src/os/macosx/G5_detector.cpp deleted file mode 100644 index cf2aeab0d5477..0000000000000 --- a/src/os/macosx/G5_detector.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 G5_detector.cpp Detection for G5 machines (PowerPC). */ - -#include -#include -#include -#include -#include - - -#ifndef CPU_SUBTYPE_POWERPC_970 -#define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100) -#endif - -/* this function is a lightly modified version of some code from Apple's developer homepage to detect G5 CPUs at runtime */ -int main() -{ - host_basic_info_data_t hostInfo; - mach_msg_type_number_t infoCount; - boolean_t is_G5; - - infoCount = HOST_BASIC_INFO_COUNT; - host_info(mach_host_self(), HOST_BASIC_INFO, - (host_info_t)&hostInfo, &infoCount); - - is_G5 = ((hostInfo.cpu_type == CPU_TYPE_POWERPC) && - (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970)); - if (is_G5) - printf("1"); -} diff --git a/src/os/macosx/crashlog_osx.cpp b/src/os/macosx/crashlog_osx.cpp index 682ed6d073ac8..68e2e5633d4ba 100644 --- a/src/os/macosx/crashlog_osx.cpp +++ b/src/os/macosx/crashlog_osx.cpp @@ -80,7 +80,7 @@ class CrashLogOSX : public CrashLog { " Message: %s\n\n", strsignal(this->signum), this->signum, - message == nullptr ? "" : message + message ); } diff --git a/src/os/macosx/font_osx.cpp b/src/os/macosx/font_osx.cpp index b931e7407bf3b..4152c7da0f40b 100644 --- a/src/os/macosx/font_osx.cpp +++ b/src/os/macosx/font_osx.cpp @@ -57,7 +57,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) } if (os_err == noErr) { - Debug(freetype, 3, "Font path for {}: {}", font_name, file_path); + Debug(fontcache, 3, "Font path for {}: {}", font_name, file_path); err = FT_New_Face(_library, (const char *)file_path, 0, face); } @@ -67,7 +67,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) #endif /* WITH_FREETYPE */ -bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) +bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) { /* Determine fallback font using CoreText. This uses the language isocode * to find a suitable font. CoreText is available from 10.5 onwards. */ @@ -134,7 +134,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i /* Save result. */ callback->SetFontNames(settings, name); if (!callback->FindMissingGlyphs()) { - Debug(freetype, 2, "CT-Font for {}: {}", language_isocode, name); + Debug(fontcache, 2, "CT-Font for {}: {}", language_isocode, name); result = true; break; } @@ -173,7 +173,7 @@ void CoreTextFontCache::SetFontSize(int pixels) { if (pixels == 0) { /* Try to determine a good height based on the height recommended by the font. */ - int scaled_height = ScaleFontTrad(this->GetDefaultFontHeight(this->fs)); + int scaled_height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs)); pixels = scaled_height; CFAutoRelease font(CTFontCreateWithFontDescriptor(this->font_desc.get(), 0.0f, nullptr)); @@ -197,11 +197,12 @@ void CoreTextFontCache::SetFontSize(int pixels) /* Font height is minimum height plus the difference between the default * height for this font size and the small size. */ - int diff = scaled_height - ScaleFontTrad(this->GetDefaultFontHeight(FS_SMALL)); - pixels = Clamp(std::min(min_size, MAX_FONT_MIN_REC_SIZE) + diff, scaled_height, MAX_FONT_SIZE); + int diff = scaled_height - ScaleGUITrad(FontCache::GetDefaultFontHeight(FS_SMALL)); + /* Clamp() is not used as scaled_height could be greater than MAX_FONT_SIZE, which is not permitted in Clamp(). */ + pixels = std::min(std::max(std::min(min_size, MAX_FONT_MIN_REC_SIZE) + diff, scaled_height), MAX_FONT_SIZE); } } else { - pixels = ScaleFontTrad(pixels); + pixels = ScaleGUITrad(pixels); } this->used_size = pixels; @@ -221,7 +222,7 @@ void CoreTextFontCache::SetFontSize(int pixels) CFStringGetCString(font_name.get(), name, lengthof(name), kCFStringEncodingUTF8); this->font_name = name; - Debug(freetype, 2, "Loaded font '{}' with size {}", this->font_name, pixels); + Debug(fontcache, 2, "Loaded font '{}' with size {}", this->font_name, pixels); } GlyphID CoreTextFontCache::MapCharToGlyph(WChar key) @@ -276,9 +277,10 @@ const Sprite *CoreTextFontCache::InternalGetGlyph(GlyphID key, bool use_aa) uint bb_width = (uint)std::ceil(bounds.size.width) + 1; // Sometimes the glyph bounds are too tight and cut of the last pixel after rounding. uint bb_height = (uint)std::ceil(bounds.size.height); - /* Add 1 pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel. */ - uint width = std::max(1U, bb_width + (this->fs == FS_NORMAL ? 1 : 0)); - uint height = std::max(1U, bb_height + (this->fs == FS_NORMAL ? 1 : 0)); + /* Add 1 scaled pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel. */ + uint shadow = (this->fs == FS_NORMAL) ? ScaleGUITrad(1) : 0; + uint width = std::max(1U, bb_width + shadow); + uint height = std::max(1U, bb_height + shadow); /* Limit glyph size to prevent overflows later on. */ if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) usererror("Font glyph is too large"); @@ -314,8 +316,8 @@ const Sprite *CoreTextFontCache::InternalGetGlyph(GlyphID key, bool use_aa) for (uint y = 0; y < bb_height; y++) { for (uint x = 0; x < bb_width; x++) { if (bmp[y * pitch + x] > 0) { - sprite.data[1 + x + (1 + y) * sprite.width].m = SHADOW_COLOUR; - sprite.data[1 + x + (1 + y) * sprite.width].a = use_aa ? bmp[x + y * pitch] : 0xFF; + sprite.data[shadow + x + (shadow + y) * sprite.width].m = SHADOW_COLOUR; + sprite.data[shadow + x + (shadow + y) * sprite.width].a = use_aa ? bmp[x + y * pitch] : 0xFF; } } } @@ -348,16 +350,7 @@ const Sprite *CoreTextFontCache::InternalGetGlyph(GlyphID key, bool use_aa) */ void LoadCoreTextFont(FontSize fs) { - static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" }; - - FreeTypeSubSetting *settings = nullptr; - switch (fs) { - default: NOT_REACHED(); - case FS_SMALL: settings = &_freetype.small; break; - case FS_NORMAL: settings = &_freetype.medium; break; - case FS_LARGE: settings = &_freetype.large; break; - case FS_MONO: settings = &_freetype.mono; break; - } + FontCacheSubSetting *settings = GetFontCacheSubSetting(fs); if (settings->font.empty()) return; @@ -393,7 +386,7 @@ 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.c_str(), SIZE_TO_NAME[fs]); + ShowInfoF("Unable to load file '%s' for %s font, using default OS font selection instead", settings->font.c_str(), FontSizeToName(fs)); } } } @@ -417,7 +410,7 @@ void LoadCoreTextFont(FontSize fs) } if (!font_ref) { - ShowInfoF("Unable to use '%s' for %s font, using sprite font instead", settings->font.c_str(), SIZE_TO_NAME[fs]); + ShowInfoF("Unable to use '%s' for %s font, using sprite font instead", settings->font.c_str(), FontSizeToName(fs)); return; } diff --git a/src/os/macosx/font_osx.h b/src/os/macosx/font_osx.h index bdfd7316d0770..7b58bc772cdd4 100644 --- a/src/os/macosx/font_osx.h +++ b/src/os/macosx/font_osx.h @@ -10,7 +10,7 @@ #ifndef FONT_OSX_H #define FONT_OSX_H -#include "../../fontcache_internal.h" +#include "../../fontcache/truetypefontcache.h" #include "os/macosx/macos.h" #include diff --git a/src/os/macosx/string_osx.cpp b/src/os/macosx/string_osx.cpp index 5cd14e8e1e280..89ff8c6bb3a3f 100644 --- a/src/os/macosx/string_osx.cpp +++ b/src/os/macosx/string_osx.cpp @@ -13,7 +13,9 @@ #include "../../strings_func.h" #include "../../table/control_codes.h" #include "../../fontcache.h" +#include "../../zoom_func.h" #include "macos.h" +#include #include @@ -245,14 +247,14 @@ CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font if (buff[this->glyph_to_char[i]] >= SCC_SPRITE_START && buff[this->glyph_to_char[i]] <= SCC_SPRITE_END) { this->glyphs[i] = font->fc->MapCharToGlyph(buff[this->glyph_to_char[i]]); this->positions[i * 2 + 0] = pts[i].x; - this->positions[i * 2 + 1] = font->fc->GetAscender() - font->fc->GetGlyph(this->glyphs[i])->height - 1; // Align sprite glyphs to font baseline. + this->positions[i * 2 + 1] = (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2; // Align sprite font to centre } else { this->glyphs[i] = gl[i]; this->positions[i * 2 + 0] = pts[i].x; this->positions[i * 2 + 1] = pts[i].y; } } - this->total_advance = (int)CTRunGetTypographicBounds(run, CFRangeMake(0, 0), nullptr, nullptr, nullptr); + this->total_advance = (int)std::ceil(CTRunGetTypographicBounds(run, CFRangeMake(0, 0), nullptr, nullptr, nullptr)); this->positions[this->glyphs.size() * 2] = this->positions[0] + this->total_advance; } @@ -442,9 +444,9 @@ int MacOSStringCompare(const char *s1, const char *s2) return this->utf16_to_utf8[this->cur_pos]; } -/* static */ StringIterator *OSXStringIterator::Create() +/* static */ std::unique_ptr OSXStringIterator::Create() { if (!MacOSVersionIsAtLeast(10, 5, 0)) return nullptr; - return new OSXStringIterator(); + return std::make_unique(); } diff --git a/src/os/macosx/string_osx.h b/src/os/macosx/string_osx.h index 88e5924e8c931..fc737b1639866 100644 --- a/src/os/macosx/string_osx.h +++ b/src/os/macosx/string_osx.h @@ -33,7 +33,7 @@ class OSXStringIterator : public StringIterator { size_t Next(IterType what) override; size_t Prev(IterType what) override; - static StringIterator *Create(); + static std::unique_ptr Create(); }; /** diff --git a/src/os/unix/crashlog_unix.cpp b/src/os/unix/crashlog_unix.cpp index fc3682d024640..cb4103e693f43 100644 --- a/src/os/unix/crashlog_unix.cpp +++ b/src/os/unix/crashlog_unix.cpp @@ -66,7 +66,7 @@ class CrashLogUnix : public CrashLog { " Message: %s\n\n", strsignal(this->signum), this->signum, - message == nullptr ? "" : message + message ); } diff --git a/src/os/unix/font_unix.cpp b/src/os/unix/font_unix.cpp index 246d65e63f344..98543c1bdc752 100644 --- a/src/os/unix/font_unix.cpp +++ b/src/os/unix/font_unix.cpp @@ -94,7 +94,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) #endif /* WITH_FREETYPE */ -bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) +bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) { if (!FcInit()) return false; @@ -148,7 +148,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i callback->SetFontNames(settings, (const char *)file); bool missing = callback->FindMissingGlyphs(); - Debug(freetype, 1, "Font \"{}\" misses{} glyphs", file, missing ? "" : " no"); + Debug(fontcache, 1, "Font \"{}\" misses{} glyphs", file, missing ? "" : " no"); if (!missing) { best_weight = value; @@ -159,7 +159,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i if (best_font != nullptr) { ret = true; callback->SetFontNames(settings, best_font); - InitFreeType(callback->Monospace()); + InitFontCache(callback->Monospace()); } /* Clean up the list of filenames. */ diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp index e1a05a8aaffe8..90792673581aa 100644 --- a/src/os/windows/crashlog_win.cpp +++ b/src/os/windows/crashlog_win.cpp @@ -114,7 +114,7 @@ class CrashLogWindows : public CrashLog { " Message: %s\n\n", (int)ep->ExceptionRecord->ExceptionCode, (size_t)ep->ExceptionRecord->ExceptionAddress, - message == nullptr ? "" : message + message ); } diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp index c93e95e6973ec..aa81a654667ef 100644 --- a/src/os/windows/font_win32.cpp +++ b/src/os/windows/font_win32.cpp @@ -9,16 +9,17 @@ #include "../../stdafx.h" #include "../../debug.h" -#include "font_win32.h" #include "../../blitter/factory.hpp" #include "../../core/alloc_func.hpp" #include "../../core/math_func.hpp" #include "../../fileio_func.h" #include "../../fontdetection.h" #include "../../fontcache.h" +#include "../../fontcache/truetypefontcache.h" #include "../../string_func.h" #include "../../strings_func.h" #include "../../zoom_func.h" +#include "font_win32.h" #include "../../table/control_codes.h" @@ -78,7 +79,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, FONT_DIR_NT, 0, KEY_READ, &hKey); if (ret != ERROR_SUCCESS) { - Debug(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"); + Debug(fontcache, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"); return err; } @@ -113,7 +114,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) } if (!SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_FONTS, nullptr, SHGFP_TYPE_CURRENT, vbuffer))) { - Debug(freetype, 0, "SHGetFolderPath cannot return fonts directory"); + Debug(fontcache, 0, "SHGetFolderPath cannot return fonts directory"); goto folder_error; } @@ -161,7 +162,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) * @param logfont the font information to get the english name of. * @return the English name (if it could be found). */ -static const char *GetEnglishFontName(const ENUMLOGFONTEX *logfont) +static std::string GetEnglishFontName(const ENUMLOGFONTEX *logfont) { static char font_name[MAX_PATH]; const char *ret_font_name = nullptr; @@ -228,58 +229,33 @@ static const char *GetEnglishFontName(const ENUMLOGFONTEX *logfont) ReleaseDC(nullptr, dc); DeleteObject(font); err1: - return ret_font_name == nullptr ? FS2OTTD((const wchar_t *)logfont->elfFullName) : ret_font_name; + return ret_font_name == nullptr ? FS2OTTD((const wchar_t *)logfont->elfFullName) : std::string(ret_font_name); } #endif /* WITH_FREETYPE */ -class FontList { -protected: - wchar_t **fonts; - uint items; - uint capacity; - -public: - FontList() : fonts(nullptr), items(0), capacity(0) { }; - - ~FontList() { - if (this->fonts == nullptr) return; - - for (uint i = 0; i < this->items; i++) { - free(this->fonts[i]); - } - - free(this->fonts); - } - - bool Add(const wchar_t *font) { - for (uint i = 0; i < this->items; i++) { - if (wcscmp(this->fonts[i], font) == 0) return false; - } +struct EFCParam { + FontCacheSettings *settings; + LOCALESIGNATURE locale; + MissingGlyphSearcher *callback; + std::vector fonts; - if (this->items == this->capacity) { - this->capacity += 10; - this->fonts = ReallocT(this->fonts, this->capacity); + bool Add(const std::wstring_view &font) { + for (const auto &entry : this->fonts) { + if (font.compare(entry) == 0) return false; } - this->fonts[this->items++] = wcsdup(font); + this->fonts.emplace_back(font); return true; } }; -struct EFCParam { - FreeTypeSettings *settings; - LOCALESIGNATURE locale; - MissingGlyphSearcher *callback; - FontList fonts; -}; - static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXTMETRICEX *metric, DWORD type, LPARAM lParam) { EFCParam *info = (EFCParam *)lParam; /* Skip duplicates */ - if (!info->fonts.Add((const wchar_t *)logfont->elfFullName)) return 1; + if (!info->Add(logfont->elfFullName)) return 1; /* Only use TrueType fonts */ if (!(type & TRUETYPE_FONTTYPE)) return 1; /* Don't use SYMBOL fonts */ @@ -309,8 +285,8 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT #ifdef WITH_FREETYPE /* Add english name after font name */ - const char *english_name = GetEnglishFontName(logfont); - strecpy(font_name + strlen(font_name) + 1, english_name, lastof(font_name)); + std::string english_name = GetEnglishFontName(logfont); + strecpy(font_name + strlen(font_name) + 1, english_name.c_str(), lastof(font_name)); /* Check whether we can actually load the font. */ bool ft_init = _library != nullptr; @@ -334,17 +310,17 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT info->callback->SetFontNames(info->settings, font_name, &logfont->elfLogFont); if (info->callback->FindMissingGlyphs()) return 1; - Debug(freetype, 1, "Fallback font: {} ({})", font_name, english_name); + Debug(fontcache, 1, "Fallback font: {} ({})", font_name, english_name); return 0; // stop enumerating } -bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) +bool SetFallbackFont(FontCacheSettings *settings, const char *language_isocode, int winlangid, MissingGlyphSearcher *callback) { - Debug(freetype, 1, "Trying fallback fonts"); + Debug(fontcache, 1, "Trying fallback fonts"); EFCParam langInfo; if (GetLocaleInfo(MAKELCID(winlangid, SORT_DEFAULT), LOCALE_FONTSIGNATURE, (LPTSTR)&langInfo.locale, sizeof(langInfo.locale) / sizeof(wchar_t)) == 0) { /* Invalid langid or some other mysterious error, can't determine fallback font. */ - Debug(freetype, 1, "Can't get locale info for fallback font (langid=0x{:x})", winlangid); + Debug(fontcache, 1, "Can't get locale info for fallback font (langid=0x{:x})", winlangid); return false; } langInfo.settings = settings; @@ -377,7 +353,6 @@ Win32FontCache::Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels) { this->dc = CreateCompatibleDC(nullptr); this->SetFontSize(fs, pixels); - this->fontname = FS2OTTD(this->logfont.lfFaceName); } Win32FontCache::~Win32FontCache() @@ -391,7 +366,7 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels) { if (pixels == 0) { /* Try to determine a good height based on the minimal height recommended by the font. */ - int scaled_height = ScaleFontTrad(this->GetDefaultFontHeight(this->fs)); + int scaled_height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs)); pixels = scaled_height; HFONT temp = CreateFontIndirect(&this->logfont); @@ -404,14 +379,15 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels) /* Font height is minimum height plus the difference between the default * height for this font size and the small size. */ - int diff = scaled_height - ScaleFontTrad(this->GetDefaultFontHeight(FS_SMALL)); - pixels = Clamp(std::min(otm->otmusMinimumPPEM, MAX_FONT_MIN_REC_SIZE) + diff, scaled_height, MAX_FONT_SIZE); + int diff = scaled_height - ScaleGUITrad(FontCache::GetDefaultFontHeight(FS_SMALL)); + /* Clamp() is not used as scaled_height could be greater than MAX_FONT_SIZE, which is not permitted in Clamp(). */ + pixels = std::min(std::max(std::min(otm->otmusMinimumPPEM, MAX_FONT_MIN_REC_SIZE) + diff, scaled_height), MAX_FONT_SIZE); SelectObject(dc, old); DeleteObject(temp); } } else { - pixels = ScaleFontTrad(pixels); + pixels = ScaleGUITrad(pixels); } this->used_size = pixels; @@ -439,7 +415,9 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels) this->glyph_size.cx = otm->otmTextMetrics.tmMaxCharWidth; this->glyph_size.cy = otm->otmTextMetrics.tmHeight; - Debug(freetype, 2, "Loaded font '{}' with size {}", FS2OTTD((LPWSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)), pixels); + this->fontname = FS2OTTD((LPWSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFaceName)); + + Debug(fontcache, 2, "Loaded font '{}' with size {}", this->fontname, pixels); } /** @@ -458,30 +436,22 @@ void Win32FontCache::ClearFontCache() GLYPHMETRICS gm; MAT2 mat = { {0, 1}, {0, 0}, {0, 0}, {0, 1} }; - /* Make a guess for the needed memory size. */ - DWORD size = this->glyph_size.cy * Align(aa ? this->glyph_size.cx : std::max(this->glyph_size.cx / 8l, 1l), 4); // Bitmap data is DWORD-aligned rows. - byte *bmp = AllocaM(byte, size); - size = GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, size, bmp, &mat); - - if (size == GDI_ERROR) { - /* No dice with the guess. First query size of needed glyph memory, then allocate the - * memory and query again. This dance is necessary as some glyphs will only render with - * the exact matching size; e.g. the space glyph has no pixels and must be requested - * with size == 0, anything else fails. Unfortunately, a failed call doesn't return any - * info about the size and thus the triple GetGlyphOutline()-call. */ - size = GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, 0, nullptr, &mat); - if (size == GDI_ERROR) usererror("Unable to render font glyph"); - bmp = AllocaM(byte, size); - GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, size, bmp, &mat); - } + /* Call GetGlyphOutline with zero size initially to get required memory size. */ + DWORD size = GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, 0, nullptr, &mat); + if (size == GDI_ERROR) usererror("Unable to render font glyph"); - /* Add 1 pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel. */ - uint width = std::max(1U, (uint)gm.gmBlackBoxX + (this->fs == FS_NORMAL)); - uint height = std::max(1U, (uint)gm.gmBlackBoxY + (this->fs == FS_NORMAL)); + /* Add 1 scaled pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel. */ + uint shadow = (this->fs == FS_NORMAL) ? ScaleGUITrad(1) : 0; + uint width = std::max(1U, (uint)gm.gmBlackBoxX + shadow); + uint height = std::max(1U, (uint)gm.gmBlackBoxY + shadow); /* Limit glyph size to prevent overflows later on. */ if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) usererror("Font glyph is too large"); + /* Call GetGlyphOutline again with size to actually render the glyph. */ + byte *bmp = AllocaM(byte, size); + GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, size, bmp, &mat); + /* GDI has rendered the glyph, now we allocate a sprite and copy the image into it. */ SpriteLoader::Sprite sprite; sprite.AllocateData(ZOOM_LVL_NORMAL, width * height); @@ -505,8 +475,8 @@ void Win32FontCache::ClearFontCache() for (uint y = 0; y < gm.gmBlackBoxY; y++) { for (uint x = 0; x < gm.gmBlackBoxX; x++) { if (aa ? (bmp[x + y * pitch] > 0) : HasBit(bmp[(x / 8) + y * pitch], 7 - (x % 8))) { - sprite.data[1 + x + (1 + y) * sprite.width].m = SHADOW_COLOUR; - sprite.data[1 + x + (1 + y) * sprite.width].a = aa ? (bmp[x + y * pitch] << 2) - 1 : 0xFF; + sprite.data[shadow + x + (shadow + y) * sprite.width].m = SHADOW_COLOUR; + sprite.data[shadow + x + (shadow + y) * sprite.width].a = aa ? (bmp[x + y * pitch] << 2) - 1 : 0xFF; } } } @@ -577,16 +547,7 @@ void Win32FontCache::ClearFontCache() */ void LoadWin32Font(FontSize fs) { - static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" }; - - FreeTypeSubSetting *settings = nullptr; - switch (fs) { - case FS_SMALL: settings = &_freetype.small; break; - case FS_NORMAL: settings = &_freetype.medium; break; - case FS_LARGE: settings = &_freetype.large; break; - case FS_MONO: settings = &_freetype.mono; break; - default: NOT_REACHED(); - } + FontCacheSubSetting *settings = GetFontCacheSubSetting(fs); if (settings->font.empty()) return; @@ -644,7 +605,7 @@ void LoadWin32Font(FontSize fs) 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", font_name, SIZE_TO_NAME[fs]); + ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", font_name, FontSizeToName(fs)); } } } @@ -656,7 +617,7 @@ void LoadWin32Font(FontSize fs) HFONT font = CreateFontIndirect(&logfont); if (font == nullptr) { - ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", font_name, SIZE_TO_NAME[fs], GetLastError()); + ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", font_name, FontSizeToName(fs), GetLastError()); return; } DeleteObject(font); diff --git a/src/os/windows/font_win32.h b/src/os/windows/font_win32.h index 6ab304c89ce08..b83b2c5f359c4 100644 --- a/src/os/windows/font_win32.h +++ b/src/os/windows/font_win32.h @@ -10,7 +10,7 @@ #ifndef FONT_WIN32_H #define FONT_WIN32_H -#include "../../fontcache_internal.h" +#include "../../fontcache/truetypefontcache.h" #include "win32.h" /** Font cache for fonts that are based on a Win32 font. */ @@ -21,7 +21,7 @@ class Win32FontCache : public TrueTypeFontCache { HDC dc = nullptr; ///< Cached GDI device context. HGDIOBJ old_font; ///< Old font selected into the GDI context. SIZE glyph_size; ///< Maximum size of regular glyphs. - std::string fontname; ///< Cached copy of this->logfont.lfFaceName + std::string fontname; ///< Cached copy of loaded font facename void SetFontSize(FontSize fs, int pixels); diff --git a/src/os/windows/string_uniscribe.cpp b/src/os/windows/string_uniscribe.cpp index 7c70557b61129..d4b122346a776 100644 --- a/src/os/windows/string_uniscribe.cpp +++ b/src/os/windows/string_uniscribe.cpp @@ -14,6 +14,7 @@ #include "../../strings_func.h" #include "../../string_func.h" #include "../../table/control_codes.h" +#include "../../zoom_func.h" #include "win32.h" #include @@ -195,7 +196,7 @@ static bool UniscribeShapeRun(const UniscribeParagraphLayoutFactory::CharType *b if (buff[range.pos + i] >= SCC_SPRITE_START && buff[range.pos + i] <= SCC_SPRITE_END) { auto pos = range.char_to_glyph[i]; range.ft_glyphs[pos] = range.font->fc->MapCharToGlyph(buff[range.pos + i]); - range.offsets[pos].dv = range.font->fc->GetAscender() - range.font->fc->GetGlyph(range.ft_glyphs[pos])->height - 1; // Align sprite glyphs to font baseline. + range.offsets[pos].dv = (range.font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(range.font->fc->GetSize()))) / 2; // Align sprite font to centre range.advances[pos] = range.font->fc->GetGlyphWidth(range.ft_glyphs[pos]); } } diff --git a/src/pace_factor_gui.cpp b/src/pace_factor_gui.cpp index 578dfad5c5924..90bc6eec91c59 100644 --- a/src/pace_factor_gui.cpp +++ b/src/pace_factor_gui.cpp @@ -133,7 +133,7 @@ struct SetPaceFactorWindow : Window { // SLOWPACE: stolen from QueryString::DrawEditBox bool rtl = _current_text_dir == TD_RTL; Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); - int clearbtn_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; + int clearbtn_width = sprite_size.width + WidgetDimensions::scaled.imgbtn.Horizontal(); return clearbtn_width; } @@ -147,17 +147,17 @@ struct SetPaceFactorWindow : Window { d = maxdim(d, GetStringBoundingBox(STR_JUST_INT)); break; - case WID_SPF_HOUR: - SetDParamMaxValue(0, 4369); - d = maxdim(d, GetStringBoundingBox(STR_JUST_INT)); - d.width += GetClearButtonSize().width; - break; + case WID_SPF_HOUR: + SetDParamMaxValue(0, 4369); + d = maxdim(d, GetStringBoundingBox(STR_JUST_INT)); + d.width += GetClearButtonSize().width; + break; - case WID_SPF_DAY: - SetDParamMaxValue(0, 183); - d = maxdim(d, GetStringBoundingBox(STR_JUST_INT)); - d.width += GetClearButtonSize().width; - break; + case WID_SPF_DAY: + SetDParamMaxValue(0, 183); + d = maxdim(d, GetStringBoundingBox(STR_JUST_INT)); + d.width += GetClearButtonSize().width; + break; } d.width += padding.width; diff --git a/src/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp index a9a51da68afff..d50ae13d264da 100644 --- a/src/pathfinder/follow_track.hpp +++ b/src/pathfinder/follow_track.hpp @@ -86,11 +86,11 @@ struct CFollowTrackT m_railtypes = railtype_override; } - inline static TransportType TT() { return Ttr_type_; } - inline static bool IsWaterTT() { return TT() == TRANSPORT_WATER; } - inline static bool IsRailTT() { return TT() == TRANSPORT_RAIL; } + debug_inline static TransportType TT() { return Ttr_type_; } + debug_inline static bool IsWaterTT() { return TT() == TRANSPORT_WATER; } + debug_inline static bool IsRailTT() { return TT() == TRANSPORT_RAIL; } inline bool IsTram() { return IsRoadTT() && RoadTypeIsTram(RoadVehicle::From(m_veh)->roadtype); } - inline static bool IsRoadTT() { return TT() == TRANSPORT_ROAD; } + debug_inline static bool IsRoadTT() { return TT() == TRANSPORT_ROAD; } inline static bool Allow90degTurns() { return T90deg_turns_allowed_; } inline static bool DoTrackMasking() { return Tmask_reserved_tracks; } @@ -371,7 +371,7 @@ struct CFollowTrackT /* entered railway station * get platform length */ uint length = BaseStation::GetByTile(m_new_tile)->GetPlatformLength(m_new_tile, TrackdirToExitdir(m_old_td)); - /* how big step we must do to get to the last platform tile; */ + /* how big step we must do to get to the last platform tile? */ m_tiles_skipped = length - 1; /* move to the platform end */ TileIndexDiff diff = TileOffsByDiagDir(m_exitdir); diff --git a/src/pathfinder/npf/aystar.h b/src/pathfinder/npf/aystar.h index cbbe8a41571a1..aa57037d160d3 100644 --- a/src/pathfinder/npf/aystar.h +++ b/src/pathfinder/npf/aystar.h @@ -20,8 +20,6 @@ #include "../../tile_type.h" #include "../../track_type.h" -//#define AYSTAR_DEBUG - /** Return status of #AyStar methods. */ enum AystarStatus { AYSTAR_FOUND_END_NODE, ///< An end node was found. diff --git a/src/pathfinder/npf/npf.cpp b/src/pathfinder/npf/npf.cpp index 25681507c7c4e..90112a5fc33c1 100644 --- a/src/pathfinder/npf/npf.cpp +++ b/src/pathfinder/npf/npf.cpp @@ -144,7 +144,7 @@ static uint NPFHash(uint key1, uint key2) uint part2 = TileY(key1) & NPF_HASH_HALFMASK; assert(IsValidTrackdir((Trackdir)key2)); - assert(IsValidTile(key1)); + assert(IsValidTile((TileIndex)key1)); return ((part1 << NPF_HASH_HALFBITS | part2) + (NPF_HASH_SIZE * key2 / TRACKDIR_END)) % NPF_HASH_SIZE; } @@ -314,7 +314,6 @@ static Vehicle *CountShipProc(Vehicle *v, void *data) static int32 NPFWaterPathCost(AyStar *as, AyStarNode *current, OpenListNode *parent) { - /* TileIndex tile = current->tile; */ int32 cost = 0; Trackdir trackdir = current->direction; @@ -1114,7 +1113,6 @@ void InitializeNPF() } _npf_aystar.loops_per_tick = 0; _npf_aystar.max_path_cost = 0; - //_npf_aystar.max_search_nodes = 0; /* We will limit the number of nodes for now, until we have a better * solution to really fix performance */ _npf_aystar.max_search_nodes = _settings_game.pf.npf.npf_max_search_nodes; diff --git a/src/pathfinder/yapf/yapf.h b/src/pathfinder/yapf/yapf.h index d644669807714..80b6c4ca54a95 100644 --- a/src/pathfinder/yapf/yapf.h +++ b/src/pathfinder/yapf/yapf.h @@ -56,9 +56,10 @@ Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDi * @param path_found [out] Whether a path has been found (true) or has been guessed (false) * @param reserve_track indicates whether YAPF should try to reserve the found path * @param target [out] the target tile of the reservation, free is set to true if path was reserved + * @param dest [out] the final tile of the best path found * @return the best track for next turn */ -Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, struct PBSTileInfo *target); +Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, struct PBSTileInfo *target, TileIndex *dest); /** * Used when user sends road vehicle to the nearest depot or if road vehicle needs servicing using YAPF. diff --git a/src/pathfinder/yapf/yapf_destrail.hpp b/src/pathfinder/yapf/yapf_destrail.hpp index 7f89639bf2f56..1c41579cbaef5 100644 --- a/src/pathfinder/yapf/yapf_destrail.hpp +++ b/src/pathfinder/yapf/yapf_destrail.hpp @@ -118,6 +118,7 @@ class CYapfDestinationTileOrStationRailT : public CYapfDestinationRailBase { TileIndex m_destTile; TrackdirBits m_destTrackdirs; StationID m_dest_station_id; + bool m_any_depot; /** to access inherited path finder */ Tpf& Yapf() @@ -128,6 +129,7 @@ class CYapfDestinationTileOrStationRailT : public CYapfDestinationRailBase { public: void SetDestination(const Train *v) { + m_any_depot = false; switch (v->current_order.GetType()) { case OT_GOTO_WAYPOINT: if (!Waypoint::Get(v->current_order.GetDestination())->IsSingleTile()) { @@ -146,6 +148,12 @@ class CYapfDestinationTileOrStationRailT : public CYapfDestinationRailBase { m_destTrackdirs = INVALID_TRACKDIR_BIT; break; + case OT_GOTO_DEPOT: + if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) { + m_any_depot = true; + } + FALLTHROUGH; + default: m_destTile = v->dest_tile; m_dest_station_id = INVALID_STATION; @@ -170,6 +178,10 @@ class CYapfDestinationTileOrStationRailT : public CYapfDestinationRailBase { && (GetRailStationTrack(tile) == TrackdirToTrack(td)); } + if (m_any_depot) { + return IsRailDepotTile(tile); + } + return (tile == m_destTile) && HasTrackdir(m_destTrackdirs, td); } diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp index 8933c6f299fd5..1b6f1a25284e9 100644 --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.cpp @@ -395,19 +395,19 @@ class CYapfFollowRailT : public CYapfReserveTrack return 't'; } - static Trackdir stChooseRailTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target) + static Trackdir stChooseRailTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target, TileIndex *dest) { /* create pathfinder instance */ Tpf pf1; Trackdir result1; if (_debug_desync_level < 2) { - result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target); + result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target, dest); } else { - result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, false, nullptr); + result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, false, nullptr, nullptr); Tpf pf2; pf2.DisableCache(true); - Trackdir result2 = pf2.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target); + Trackdir result2 = pf2.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target, dest); if (result1 != result2) { Debug(desync, 2, "CACHE ERROR: ChooseRailTrack() = [{}, {}]", result1, result2); DumpState(pf1, pf2); @@ -417,9 +417,10 @@ class CYapfFollowRailT : public CYapfReserveTrack return result1; } - inline Trackdir ChooseRailTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target) + inline Trackdir ChooseRailTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target, TileIndex *dest) { if (target != nullptr) target->tile = INVALID_TILE; + if (dest != nullptr) *dest = INVALID_TILE; /* set origin and destination nodes */ PBSTileInfo origin = FollowTrainReservation(v); @@ -449,7 +450,10 @@ class CYapfFollowRailT : public CYapfReserveTrack Node &best_next_node = *pPrev; next_trackdir = best_next_node.GetTrackdir(); - if (reserve_track && path_found) this->TryReservePath(target, pNode->GetLastTile()); + if (reserve_track && path_found) { + if (dest != nullptr) *dest = Yapf().GetBestNode()->GetLastTile(); + this->TryReservePath(target, pNode->GetLastTile()); + } } /* Treat the path as found if stopped on the first two way signal(s). */ @@ -528,10 +532,10 @@ struct CYapfAnySafeTileRail1 : CYapfT > {}; -Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target) +Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target, TileIndex *dest) { /* default is YAPF type 2 */ - typedef Trackdir (*PfnChooseRailTrack)(const Train*, TileIndex, DiagDirection, TrackBits, bool&, bool, PBSTileInfo*); + typedef Trackdir (*PfnChooseRailTrack)(const Train*, TileIndex, DiagDirection, TrackBits, bool&, bool, PBSTileInfo*, TileIndex*); PfnChooseRailTrack pfnChooseRailTrack = &CYapfRail1::stChooseRailTrack; /* check if non-default YAPF type needed */ @@ -539,7 +543,7 @@ Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdi pfnChooseRailTrack = &CYapfRail2::stChooseRailTrack; // Trackdir, forbid 90-deg } - Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target); + Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target, dest); return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : FindFirstTrack(tracks); } diff --git a/src/pbs.cpp b/src/pbs.cpp index c4dfcbce54f6b..df3a5cf339f55 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -105,8 +105,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations) case MP_ROAD: if (IsLevelCrossing(tile) && !HasCrossingReservation(tile)) { SetCrossingReservation(tile, true); - BarCrossing(tile); - MarkTileDirtyByTile(tile); // crossing barred, make tile dirty + UpdateLevelCrossing(tile, false); return true; } break; diff --git a/src/rail.cpp b/src/rail.cpp index 63afa379e0fce..dd7550d7d3ec8 100644 --- a/src/rail.cpp +++ b/src/rail.cpp @@ -152,7 +152,7 @@ extern const TrackdirBits _uphill_trackdirs[] = { /** * Return the rail type of tile, or INVALID_RAILTYPE if this is no rail tile. */ -RailType GetTileRailType(TileIndex tile) +RailType GetTileRailType(Tile tile) { switch (GetTileType(tile)) { case MP_RAILWAY: diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 6346730cc883c..77fbe00f5fbba 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -531,7 +531,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, RailType rai /* Disallow breaking end-of-line of someone else * so trams can still reverse on this tile. */ if (Company::IsValidID(tram_owner) && HasExactlyOneBit(tram)) { - CommandCost ret = CheckOwnership(tram_owner); + ret = CheckOwnership(tram_owner); if (ret.Failed()) return ret; } @@ -548,6 +548,7 @@ CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, RailType rai if (flags & DC_EXEC) { MakeRoadCrossing(tile, road_owner, tram_owner, _current_company, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtype_road, roadtype_tram, GetTownIndex(tile)); UpdateLevelCrossing(tile, false); + MarkDirtyAdjacentLevelCrossingTiles(tile, GetCrossingRoadAxis(tile)); Company::Get(_current_company)->infrastructure.rail[railtype] += LEVELCROSSING_TRACKBIT_FACTOR; DirtyCompanyInfrastructureWindows(_current_company); if (num_new_road_pieces > 0 && Company::IsValidID(road_owner)) { @@ -649,6 +650,8 @@ CommandCost CmdRemoveSingleRail(DoCommandFlag flags, TileIndex tile, Track track cost.AddCost(RailClearCost(GetRailType(tile))); if (flags & DC_EXEC) { + MarkDirtyAdjacentLevelCrossingTiles(tile, GetCrossingRoadAxis(tile)); + if (HasReservedTracks(tile, trackbit)) { v = GetTrainForReservation(tile, track); if (v != nullptr) FreeTrainTrackReservation(v); @@ -880,7 +883,7 @@ static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, TileI CommandCost total_cost(EXPENSES_CONSTRUCTION); if ((!remove && !ValParamRailtype(railtype)) || !ValParamTrackOrientation(track)) return CMD_ERROR; - if (end_tile >= MapSize()) return CMD_ERROR; + if (end_tile >= Map::Size() || tile >= Map::Size()) return CMD_ERROR; Trackdir trackdir = TrackToTrackdir(track); @@ -890,7 +893,7 @@ static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, TileI bool had_success = false; CommandCost last_error = CMD_ERROR; for (;;) { - CommandCost ret = remove ? Command::Do(flags, tile, TrackdirToTrack(trackdir)) : Command::Do(flags, tile, railtype, TrackdirToTrack(trackdir), auto_remove_signals); + ret = remove ? Command::Do(flags, tile, TrackdirToTrack(trackdir)) : Command::Do(flags, tile, railtype, TrackdirToTrack(trackdir), auto_remove_signals); if (ret.Failed()) { last_error = ret; @@ -922,8 +925,8 @@ static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, TileI * Build rail on a stretch of track. * Stub for the unified rail builder/remover * @param flags operation to perform - * @param tile start tile of drag * @param end_tile end tile of drag + * @param start_tile start tile of drag * @param railtype railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building * @param track track-orientation * @param auto_remove_signals false = build up to an obstacle, true = fail if an obstacle is found (used for AIs). @@ -931,24 +934,24 @@ static CommandCost CmdRailTrackHelper(DoCommandFlag flags, TileIndex tile, TileI * @see CmdRailTrackHelper */ -CommandCost CmdBuildRailroadTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, RailType railtype, Track track, bool auto_remove_signals, bool fail_on_obstacle) +CommandCost CmdBuildRailroadTrack(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, RailType railtype, Track track, bool auto_remove_signals, bool fail_on_obstacle) { - return CmdRailTrackHelper(flags, tile, end_tile, railtype, track, false, auto_remove_signals, fail_on_obstacle); + return CmdRailTrackHelper(flags, start_tile, end_tile, railtype, track, false, auto_remove_signals, fail_on_obstacle); } /** * Build rail on a stretch of track. * Stub for the unified rail builder/remover * @param flags operation to perform - * @param tile start tile of drag * @param end_tile end tile of drag + * @param start_tile start tile of drag * @param track track-orientation * @return the cost of this operation or an error * @see CmdRailTrackHelper */ -CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, Track track) +CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, Track track) { - return CmdRailTrackHelper(flags, tile, end_tile, INVALID_RAILTYPE, track, true, false, false); + return CmdRailTrackHelper(flags, start_tile, end_tile, INVALID_RAILTYPE, track, true, false, false); } /** @@ -1241,7 +1244,7 @@ static CommandCost CmdSignalTrackHelper(DoCommandFlag flags, TileIndex tile, Til { CommandCost total_cost(EXPENSES_CONSTRUCTION); - if (end_tile >= MapSize() || !ValParamTrackOrientation(track)) return CMD_ERROR; + if (end_tile >= Map::Size() || !ValParamTrackOrientation(track)) return CMD_ERROR; if (signal_density == 0 || signal_density > 20) return CMD_ERROR; if (!remove && (sigtype > SIGTYPE_LAST || sigvar > SIG_SEMAPHORE)) return CMD_ERROR; @@ -1537,7 +1540,7 @@ CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_s TileIndex area_end = tile; if (!ValParamRailtype(totype)) return CMD_ERROR; - if (area_start >= MapSize()) return CMD_ERROR; + if (area_start >= Map::Size()) return CMD_ERROR; TrainList affected_trains; @@ -1545,7 +1548,7 @@ CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_s CommandCost error = CommandCost(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK); // by default, there is no track to convert. bool found_convertible_track = false; // whether we actually did convert some track (see bug #7633) - TileIterator *iter = diagonal ? (TileIterator *)new DiagonalTileIterator(area_start, area_end) : new OrthogonalTileIterator(area_start, area_end); + std::unique_ptr iter = TileIterator::Create(area_start, area_end, diagonal); for (; (tile = *iter) != INVALID_TILE; ++(*iter)) { TileType tt = GetTileType(tile); @@ -1588,7 +1591,7 @@ CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_s * Tunnels and bridges have special check later */ if (tt != MP_TUNNELBRIDGE) { if (!IsCompatibleRail(type, totype)) { - CommandCost ret = IsPlainRailTile(tile) ? EnsureNoTrainOnTrackBits(tile, GetTrackBits(tile)) : EnsureNoVehicleOnGround(tile); + ret = IsPlainRailTile(tile) ? EnsureNoTrainOnTrackBits(tile, GetTrackBits(tile)) : EnsureNoVehicleOnGround(tile); if (ret.Failed()) { error = ret; continue; @@ -1672,7 +1675,7 @@ CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_s /* When not converting rail <-> el. rail, any vehicle cannot be in tunnel/bridge */ if (!IsCompatibleRail(GetRailType(tile), totype)) { - CommandCost ret = TunnelBridgeIsFree(tile, endtile); + ret = TunnelBridgeIsFree(tile, endtile); if (ret.Failed()) { error = ret; continue; @@ -1742,7 +1745,6 @@ CommandCost CmdConvertRail(DoCommandFlag flags, TileIndex tile, TileIndex area_s } } - delete iter; return found_convertible_track ? cost : error; } @@ -1819,9 +1821,7 @@ static CommandCost ClearTile_Track(TileIndex tile, DoCommandFlag flags) /* The track was removed, and left a coast tile. Now also clear the water. */ if (flags & DC_EXEC) { - bool remove = IsDockingTile(tile); DoClearSquare(tile); - if (remove) RemoveDockingTile(tile); } cost.AddCost(_price[PR_CLEAR_WATER]); } diff --git a/src/rail_cmd.h b/src/rail_cmd.h index 2a1b696906f61..8bee52e74ce5a 100644 --- a/src/rail_cmd.h +++ b/src/rail_cmd.h @@ -15,8 +15,8 @@ #include "rail_type.h" #include "signal_type.h" -CommandCost CmdBuildRailroadTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, RailType railtype, Track track, bool auto_remove_signals, bool fail_on_obstacle); -CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex tile, TileIndex end_tile, Track track); +CommandCost CmdBuildRailroadTrack(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, RailType railtype, Track track, bool auto_remove_signals, bool fail_on_obstacle); +CommandCost CmdRemoveRailroadTrack(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, Track track); CommandCost CmdBuildSingleRail(DoCommandFlag flags, TileIndex tile, RailType railtype, Track track, bool auto_remove_signals); CommandCost CmdRemoveSingleRail(DoCommandFlag flags, TileIndex tile, Track track); CommandCost CmdBuildTrainDepot(DoCommandFlag flags, TileIndex tile, RailType railtype, DiagDirection dir); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 9a813407babf8..f8bc5360aac83 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -355,10 +355,10 @@ static void DoRailroadTrack(Track track) { if (_remove_button_clicked) { Command::Post(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, - TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), track); + TileVirtXY(_thd.selend.x, _thd.selend.y), TileVirtXY(_thd.selstart.x, _thd.selstart.y), track); } else { Command::Post(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK, CcPlaySound_CONSTRUCTION_RAIL, - TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype, track, _settings_client.gui.auto_remove_signals, false); + TileVirtXY(_thd.selend.x, _thd.selend.y), TileVirtXY(_thd.selstart.x, _thd.selstart.y), _cur_railtype, track, _settings_client.gui.auto_remove_signals, false); } } @@ -813,7 +813,7 @@ static const NWidgetPart _nested_build_rail_widgets[] = { NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_AUTORAIL), SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTORAIL, STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL), - NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(4, 22), SetDataTip(0x0, STR_NULL), EndContainer(), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(4, 22), EndContainer(), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_RAT_DEMOLISH), SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC), @@ -968,7 +968,7 @@ struct BuildRailStationWindow : public PickerWindowBase { public: BuildRailStationWindow(WindowDesc *desc, Window *parent, bool newstation) : PickerWindowBase(desc, parent), filter_editbox(EDITBOX_MAX_SIZE * MAX_CHAR_LENGTH, EDITBOX_MAX_SIZE) { - this->coverage_height = 2 * FONT_HEIGHT_NORMAL + 3 * WD_PAR_VSEP_NORMAL; + this->coverage_height = 2 * FONT_HEIGHT_NORMAL + 3 * WidgetDimensions::scaled.vsep_normal; this->vscroll = nullptr; _railstation.newstations = newstation; @@ -1179,18 +1179,15 @@ struct BuildRailStationWindow : public PickerWindowBase { if (this->IsShaded()) return; /* 'Accepts' and 'Supplies' texts. */ - NWidgetBase *cov = this->GetWidget(WID_BRAS_COVERAGE_TEXTS); - int top = cov->pos_y + WD_PAR_VSEP_NORMAL; - int left = cov->pos_x + WD_FRAMERECT_LEFT; - int right = cov->pos_x + cov->current_x - WD_FRAMERECT_RIGHT; - int bottom = cov->pos_y + cov->current_y; - top = DrawStationCoverageAreaText(left, right, top, SCT_ALL, rad, false) + WD_PAR_VSEP_NORMAL; - top = DrawStationCoverageAreaText(left, right, top, SCT_ALL, rad, true) + WD_PAR_VSEP_NORMAL; + Rect r = this->GetWidget(WID_BRAS_COVERAGE_TEXTS)->GetCurrentRect(); + int top = r.top + WidgetDimensions::scaled.vsep_normal; + top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, false) + WidgetDimensions::scaled.vsep_normal; + top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, true) + WidgetDimensions::scaled.vsep_normal; /* Resize background if the window is too small. * Never make the window smaller to avoid oscillating if the size change affects the acceptance. * (This is the case, if making the window bigger moves the mouse into the window.) */ - if (top > bottom) { - this->coverage_height += top - bottom; + if (top > r.bottom) { + this->coverage_height += top - r.bottom; this->ReInit(); } } @@ -1204,7 +1201,7 @@ struct BuildRailStationWindow : public PickerWindowBase { d = maxdim(d, GetStringBoundingBox(StationClass::Get(station_class)->name)); } size->width = std::max(size->width, d.width + padding.width); - this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM; + this->line_height = FONT_HEIGHT_NORMAL + padding.height; size->height = 5 * this->line_height; resize->height = this->line_height; break; @@ -1235,8 +1232,8 @@ struct BuildRailStationWindow : public PickerWindowBase { case WID_BRAS_PLATFORM_DIR_X: case WID_BRAS_PLATFORM_DIR_Y: case WID_BRAS_IMAGE: - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(58) + 2; + size->width = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Horizontal(); + size->height = ScaleGUITrad(58) + WidgetDimensions::scaled.fullbevel.Vertical(); break; case WID_BRAS_COVERAGE_TEXTS: @@ -1257,41 +1254,37 @@ struct BuildRailStationWindow : public PickerWindowBase { switch (GB(widget, 0, 16)) { case WID_BRAS_PLATFORM_DIR_X: /* Set up a clipping area for the '/' station preview */ - if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; - int x = ScaleGUITrad(31) + 1; - int y = r.bottom - r.top - ScaleGUITrad(31); + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); + int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); + int y = (r.Height() + ScaleSpriteTrad(58)) / 2 - ScaleSpriteTrad(31); if (!DrawStationTile(x, y, _cur_railtype, AXIS_X, _railstation.station_class, _railstation.station_type)) { StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2); } - _cur_dpi = old_dpi; } break; case WID_BRAS_PLATFORM_DIR_Y: /* Set up a clipping area for the '\' station preview */ - if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; - int x = ScaleGUITrad(31) + 1; - int y = r.bottom - r.top - ScaleGUITrad(31); + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); + int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); + int y = (r.Height() + ScaleSpriteTrad(58)) / 2 - ScaleSpriteTrad(31); if (!DrawStationTile(x, y, _cur_railtype, AXIS_Y, _railstation.station_class, _railstation.station_type)) { StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 3); } - _cur_dpi = old_dpi; } break; case WID_BRAS_NEWST_LIST: { + Rect ir = r.Shrink(WidgetDimensions::scaled.matrix); uint statclass = 0; - uint row = 0; for (auto station_class : this->station_classes) { if (this->vscroll->IsVisible(statclass)) { - DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, row * this->line_height + r.top + WD_MATRIX_TOP, + DrawString(ir, StationClass::Get(station_class)->name, station_class == _railstation.station_class ? TC_WHITE : TC_BLACK); - row++; + ir.top += this->line_height; } statclass++; } @@ -1304,19 +1297,17 @@ struct BuildRailStationWindow : public PickerWindowBase { /* Check station availability callback */ const StationSpec *statspec = StationClass::Get(_railstation.station_class)->GetSpec(type); if (!IsStationAvailable(statspec)) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), PC_BLACK, FILLRECT_CHECKER); } /* Set up a clipping area for the station preview. */ - if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.right - r.left + 1, r.bottom - r.top + 1)) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; - int x = ScaleGUITrad(31) + 1; - int y = r.bottom - r.top - ScaleGUITrad(31); + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); + int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); + int y = (r.Height() + ScaleSpriteTrad(58)) / 2 - ScaleSpriteTrad(31); if (!DrawStationTile(x, y, _cur_railtype, _railstation.orientation, _railstation.station_class, type)) { StationPickerDrawSprite(x, y, STATION_RAIL, _cur_railtype, INVALID_ROADTYPE, 2 + _railstation.orientation); } - _cur_dpi = old_dpi; } break; } @@ -1612,7 +1603,7 @@ static const NWidgetPart _nested_station_builder_widgets[] = { NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_PLATFORM_DRAG_N_DROP), SetMinimalSize(75, 12), SetDataTip(STR_STATION_BUILD_DRAG_DROP, STR_STATION_BUILD_DRAG_DROP_TOOLTIP), NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), EndContainer(), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(3, 2, 0, 0), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 0), NWidget(NWID_HORIZONTAL), NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BRAS_HIGHLIGHT_OFF), SetMinimalSize(60, 12), @@ -1637,7 +1628,7 @@ static const NWidgetPart _nested_station_builder_widgets[] = { EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BRAS_COVERAGE_TEXTS), SetPadding(2, 5, 0, 1), SetFill(1, 1), SetResize(1, 0), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BRAS_COVERAGE_TEXTS), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 1), SetResize(1, 0), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BRAS_SHOW_NEWST_RESIZE), NWidget(NWID_VERTICAL), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(0, 1), EndContainer(), @@ -1676,15 +1667,14 @@ struct BuildSignalWindow : public PickerWindowBase { * @param widget_index index of this widget in the window * @param image the sprite to draw */ - void DrawSignalSprite(byte widget_index, SpriteID image) const + void DrawSignalSprite(const Rect &r, int widget_index, SpriteID image) const { Point offset; Dimension sprite_size = GetSpriteSize(image, &offset); - const NWidgetBase *widget = this->GetWidget(widget_index); - int x = widget->pos_x - offset.x + - (widget->current_x - sprite_size.width + offset.x) / 2; // centered - int y = widget->pos_y - sig_sprite_bottom_offset + WD_IMGBTN_TOP + - (widget->current_y - WD_IMGBTN_TOP - WD_IMGBTN_BOTTOM + sig_sprite_size.height) / 2; // aligned to bottom + Rect ir = r.Shrink(WidgetDimensions::scaled.imgbtn); + int x = CenterBounds(ir.left, ir.right, sprite_size.width - offset.x) - offset.x; // centered + int y = ir.top - sig_sprite_bottom_offset + + (ir.Height() + sig_sprite_size.height) / 2; // aligned to bottom DrawSprite(image, PAL_NONE, x + this->IsWidgetLowered(widget_index), @@ -1745,12 +1735,12 @@ struct BuildSignalWindow : public PickerWindowBase { { if (widget == WID_BS_DRAG_SIGNALS_DENSITY_LABEL) { /* Two digits for signals density. */ - size->width = std::max(size->width, 2 * GetDigitWidth() + padding.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT); + size->width = std::max(size->width, 2 * GetDigitWidth() + padding.width + WidgetDimensions::scaled.framerect.Horizontal()); } else if (IsInsideMM(widget, WID_BS_SEMAPHORE_NORM, WID_BS_ELECTRIC_PBS_OWAY + 1)) { - size->width = std::max(size->width, this->sig_sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT); - size->height = std::max(size->height, this->sig_sprite_size.height + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM); + size->width = std::max(size->width, this->sig_sprite_size.width + padding.width); + size->height = std::max(size->height, this->sig_sprite_size.height + padding.height); } else if (widget == WID_BS_CAPTION) { - size->width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; + size->width += WidgetDimensions::scaled.frametext.Horizontal(); } } @@ -1771,7 +1761,7 @@ struct BuildSignalWindow : public PickerWindowBase { int var = SIG_SEMAPHORE - (widget - WID_BS_SEMAPHORE_NORM) / SIGTYPE_END; // SignalVariant order is reversed compared to the widgets. SpriteID sprite = GetRailTypeInfo(_cur_railtype)->gui_sprites.signals[type][var][this->IsWidgetLowered(widget)]; - this->DrawSignalSprite(widget, sprite); + this->DrawSignalSprite(r, widget, sprite); } } @@ -1934,15 +1924,21 @@ struct BuildRailDepotWindow : public PickerWindowBase { { if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return; - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(48) + 2; + size->width = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Horizontal(); + size->height = ScaleGUITrad(48) + WidgetDimensions::scaled.fullbevel.Vertical(); } void DrawWidget(const Rect &r, int widget) const override { if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return; - DrawTrainDepotSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), widget - WID_BRAD_DEPOT_NE + DIAGDIR_NE, _cur_railtype); + DrawPixelInfo tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); + int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); + int y = (r.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31); + DrawTrainDepotSprite(x, y, widget - WID_BRAD_DEPOT_NE + DIAGDIR_NE, _cur_railtype); + } } void OnClick(Point pt, int widget, int click_count) override @@ -2033,8 +2029,8 @@ struct BuildRailWaypointWindow : PickerWindowBase { break; case WID_BRW_WAYPOINT: - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(58) + 2; + size->width = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Horizontal(); + size->height = ScaleGUITrad(58) + WidgetDimensions::scaled.fullbevel.Vertical(); break; } } @@ -2045,10 +2041,17 @@ struct BuildRailWaypointWindow : PickerWindowBase { case WID_BRW_WAYPOINT: { byte type = GB(widget, 16, 16); const StationSpec *statspec = StationClass::Get(STAT_CLASS_WAYP)->GetSpec(type); - DrawWaypointSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), type, _cur_railtype); + + DrawPixelInfo tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); + int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); + int y = (r.Height() + ScaleSpriteTrad(58)) / 2 - ScaleSpriteTrad(31); + DrawWaypointSprite(x, y, type, _cur_railtype); + } if (!IsStationAvailable(statspec)) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), PC_BLACK, FILLRECT_CHECKER); } } } @@ -2083,8 +2086,10 @@ static const NWidgetPart _nested_build_waypoint_widgets[] = { NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BRW_WAYPOINT_MATRIX), SetPIP(3, 2, 3), SetScrollbar(WID_BRW_SCROLL), - NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BRW_WAYPOINT), SetMinimalSize(66, 60), SetDataTip(0x0, STR_WAYPOINT_GRAPHICS_TOOLTIP), SetScrollbar(WID_BRW_SCROLL), EndContainer(), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), + NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BRW_WAYPOINT_MATRIX), SetPIP(0, 2, 0), SetPadding(3), SetScrollbar(WID_BRW_SCROLL), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BRW_WAYPOINT), SetMinimalSize(66, 60), SetDataTip(0x0, STR_WAYPOINT_GRAPHICS_TOOLTIP), SetScrollbar(WID_BRW_SCROLL), EndContainer(), + EndContainer(), EndContainer(), NWidget(NWID_VERTICAL), NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_BRW_SCROLL), @@ -2141,7 +2146,7 @@ static void SetDefaultRailGui() /* Find the most used rail type */ uint count[RAILTYPE_END]; memset(count, 0, sizeof(count)); - for (TileIndex t = 0; t < MapSize(); t++) { + for (TileIndex t = 0; t < Map::Size(); t++) { if (IsTileType(t, MP_RAILWAY) || IsLevelCrossingTile(t) || HasStationTileRail(t) || (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL)) { count[GetRailType(t)]++; diff --git a/src/rail_map.h b/src/rail_map.h index bd1d3c749287f..25f61339eb561 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -33,10 +33,10 @@ enum RailTileType { * @pre IsTileType(t, MP_RAILWAY) * @return the RailTileType */ -static inline RailTileType GetRailTileType(TileIndex t) +debug_inline static RailTileType GetRailTileType(Tile t) { assert(IsTileType(t, MP_RAILWAY)); - return (RailTileType)GB(_m[t].m5, 6, 2); + return (RailTileType)GB(t.m5(), 6, 2); } /** @@ -46,7 +46,7 @@ static inline RailTileType GetRailTileType(TileIndex t) * @pre IsTileType(t, MP_RAILWAY) * @return true if and only if the tile is normal rail (with or without signals) */ -static inline bool IsPlainRail(TileIndex t) +debug_inline static bool IsPlainRail(Tile t) { RailTileType rtt = GetRailTileType(t); return rtt == RAIL_TILE_NORMAL || rtt == RAIL_TILE_SIGNALS; @@ -57,7 +57,7 @@ static inline bool IsPlainRail(TileIndex t) * @param t the tile to get the information from * @return true if and only if the tile is normal rail (with or without signals) */ -static inline bool IsPlainRailTile(TileIndex t) +debug_inline static bool IsPlainRailTile(Tile t) { return IsTileType(t, MP_RAILWAY) && IsPlainRail(t); } @@ -69,7 +69,7 @@ static inline bool IsPlainRailTile(TileIndex t) * @pre IsTileType(t, MP_RAILWAY) * @return true if and only if the tile has signals */ -static inline bool HasSignals(TileIndex t) +static inline bool HasSignals(Tile t) { return GetRailTileType(t) == RAIL_TILE_SIGNALS; } @@ -80,10 +80,10 @@ static inline bool HasSignals(TileIndex t) * @param signals whether the rail tile should have signals or not * @pre IsPlainRailTile(tile) */ -static inline void SetHasSignals(TileIndex tile, bool signals) +static inline void SetHasSignals(Tile tile, bool signals) { assert(IsPlainRailTile(tile)); - SB(_m[tile].m5, 6, 1, signals); + SB(tile.m5(), 6, 1, signals); } /** @@ -92,7 +92,7 @@ static inline void SetHasSignals(TileIndex tile, bool signals) * @pre IsTileType(t, MP_RAILWAY) * @return true if and only if the tile is a rail depot */ -static inline bool IsRailDepot(TileIndex t) +debug_inline static bool IsRailDepot(Tile t) { return GetRailTileType(t) == RAIL_TILE_DEPOT; } @@ -102,7 +102,7 @@ static inline bool IsRailDepot(TileIndex t) * @param t the tile to get the information from * @return true if and only if the tile is a rail depot */ -static inline bool IsRailDepotTile(TileIndex t) +debug_inline static bool IsRailDepotTile(Tile t) { return IsTileType(t, MP_RAILWAY) && IsRailDepot(t); } @@ -112,9 +112,9 @@ static inline bool IsRailDepotTile(TileIndex t) * @param t the tile to get the rail type from * @return the rail type of the tile */ -static inline RailType GetRailType(TileIndex t) +static inline RailType GetRailType(Tile t) { - return (RailType)GB(_me[t].m8, 0, 6); + return (RailType)GB(t.m8(), 0, 6); } /** @@ -122,9 +122,9 @@ static inline RailType GetRailType(TileIndex t) * @param t the tile to set the rail type of * @param r the new rail type for the tile */ -static inline void SetRailType(TileIndex t, RailType r) +static inline void SetRailType(Tile t, RailType r) { - SB(_me[t].m8, 0, 6, r); + SB(t.m8(), 0, 6, r); } @@ -133,10 +133,10 @@ static inline void SetRailType(TileIndex t, RailType r) * @param tile the tile to get the track bits from * @return the track bits of the tile */ -static inline TrackBits GetTrackBits(TileIndex tile) +static inline TrackBits GetTrackBits(Tile tile) { assert(IsPlainRailTile(tile)); - return (TrackBits)GB(_m[tile].m5, 0, 6); + return (TrackBits)GB(tile.m5(), 0, 6); } /** @@ -144,10 +144,10 @@ static inline TrackBits GetTrackBits(TileIndex tile) * @param t the tile to set the track bits of * @param b the new track bits for the tile */ -static inline void SetTrackBits(TileIndex t, TrackBits b) +static inline void SetTrackBits(Tile t, TrackBits b) { assert(IsPlainRailTile(t)); - SB(_m[t].m5, 0, 6, b); + SB(t.m5(), 0, 6, b); } /** @@ -157,7 +157,7 @@ static inline void SetTrackBits(TileIndex t, TrackBits b) * @pre IsPlainRailTile(tile) * @return true if and only if the given track exists on the tile */ -static inline bool HasTrack(TileIndex tile, Track track) +static inline bool HasTrack(Tile tile, Track track) { return HasBit(GetTrackBits(tile), track); } @@ -168,9 +168,9 @@ static inline bool HasTrack(TileIndex tile, Track track) * @pre IsRailDepotTile(t) * @return the direction the depot is facing */ -static inline DiagDirection GetRailDepotDirection(TileIndex t) +static inline DiagDirection GetRailDepotDirection(Tile t) { - return (DiagDirection)GB(_m[t].m5, 0, 2); + return (DiagDirection)GB(t.m5(), 0, 2); } /** @@ -179,7 +179,7 @@ static inline DiagDirection GetRailDepotDirection(TileIndex t) * @param t the tile to get the depot track from * @return the track of the depot */ -static inline Track GetRailDepotTrack(TileIndex t) +static inline Track GetRailDepotTrack(Tile t) { return DiagDirToDiagTrack(GetRailDepotDirection(t)); } @@ -191,13 +191,13 @@ static inline Track GetRailDepotTrack(TileIndex t) * @param t the tile to query * @return the track bits */ -static inline TrackBits GetRailReservationTrackBits(TileIndex t) +static inline TrackBits GetRailReservationTrackBits(Tile t) { assert(IsPlainRailTile(t)); - byte track_b = GB(_m[t].m2, 8, 3); + byte track_b = GB(t.m2(), 8, 3); Track track = (Track)(track_b - 1); // map array saves Track+1 if (track_b == 0) return TRACK_BIT_NONE; - return (TrackBits)(TrackToTrackBits(track) | (HasBit(_m[t].m2, 11) ? TrackToTrackBits(TrackToOppositeTrack(track)) : 0)); + return (TrackBits)(TrackToTrackBits(track) | (HasBit(t.m2(), 11) ? TrackToTrackBits(TrackToOppositeTrack(track)) : 0)); } /** @@ -206,14 +206,14 @@ static inline TrackBits GetRailReservationTrackBits(TileIndex t) * @param t the tile to change * @param b the track bits */ -static inline void SetTrackReservation(TileIndex t, TrackBits b) +static inline void SetTrackReservation(Tile t, TrackBits b) { assert(IsPlainRailTile(t)); assert(b != INVALID_TRACK_BIT); assert(!TracksOverlap(b)); Track track = RemoveFirstTrack(&b); - SB(_m[t].m2, 8, 3, track == INVALID_TRACK ? 0 : track + 1); - SB(_m[t].m2, 11, 1, (byte)(b != TRACK_BIT_NONE)); + SB(t.m2(), 8, 3, track == INVALID_TRACK ? 0 : track + 1); + SB(t.m2(), 11, 1, (byte)(b != TRACK_BIT_NONE)); } /** @@ -223,7 +223,7 @@ static inline void SetTrackReservation(TileIndex t, TrackBits b) * @param t the rack to reserve * @return true if successful */ -static inline bool TryReserveTrack(TileIndex tile, Track t) +static inline bool TryReserveTrack(Tile tile, Track t) { assert(HasTrack(tile, t)); TrackBits bits = TrackToTrackBits(t); @@ -241,7 +241,7 @@ static inline bool TryReserveTrack(TileIndex tile, Track t) * @param tile the tile * @param t the track to free */ -static inline void UnreserveTrack(TileIndex tile, Track t) +static inline void UnreserveTrack(Tile tile, Track t) { assert(HasTrack(tile, t)); TrackBits res = GetRailReservationTrackBits(tile); @@ -255,10 +255,10 @@ static inline void UnreserveTrack(TileIndex tile, Track t) * @param t the depot tile * @return reservation state */ -static inline bool HasDepotReservation(TileIndex t) +static inline bool HasDepotReservation(Tile t) { assert(IsRailDepot(t)); - return HasBit(_m[t].m5, 4); + return HasBit(t.m5(), 4); } /** @@ -267,10 +267,10 @@ static inline bool HasDepotReservation(TileIndex t) * @param t the depot tile * @param b the reservation state */ -static inline void SetDepotReservation(TileIndex t, bool b) +static inline void SetDepotReservation(Tile t, bool b) { assert(IsRailDepot(t)); - SB(_m[t].m5, 4, 1, (byte)b); + SB(t.m5(), 4, 1, (byte)b); } /** @@ -279,7 +279,7 @@ static inline void SetDepotReservation(TileIndex t, bool b) * @param t the tile * @return reserved track bits */ -static inline TrackBits GetDepotReservationTrackBits(TileIndex t) +static inline TrackBits GetDepotReservationTrackBits(Tile t) { return HasDepotReservation(t) ? TrackToTrackBits(GetRailDepotTrack(t)) : TRACK_BIT_NONE; } @@ -290,58 +290,58 @@ static inline bool IsPbsSignal(SignalType s) return s == SIGTYPE_PBS || s == SIGTYPE_PBS_ONEWAY; } -static inline SignalType GetSignalType(TileIndex t, Track track) +static inline SignalType GetSignalType(Tile t, Track track) { assert(GetRailTileType(t) == RAIL_TILE_SIGNALS); byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 4 : 0; - return (SignalType)GB(_m[t].m2, pos, 3); + return (SignalType)GB(t.m2(), pos, 3); } -static inline void SetSignalType(TileIndex t, Track track, SignalType s) +static inline void SetSignalType(Tile t, Track track, SignalType s) { assert(GetRailTileType(t) == RAIL_TILE_SIGNALS); byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 4 : 0; - SB(_m[t].m2, pos, 3, s); - if (track == INVALID_TRACK) SB(_m[t].m2, 4, 3, s); + SB(t.m2(), pos, 3, s); + if (track == INVALID_TRACK) SB(t.m2(), 4, 3, s); } -static inline bool IsPresignalEntry(TileIndex t, Track track) +static inline bool IsPresignalEntry(Tile t, Track track) { return GetSignalType(t, track) == SIGTYPE_ENTRY || GetSignalType(t, track) == SIGTYPE_COMBO; } -static inline bool IsPresignalExit(TileIndex t, Track track) +static inline bool IsPresignalExit(Tile t, Track track) { return GetSignalType(t, track) == SIGTYPE_EXIT || GetSignalType(t, track) == SIGTYPE_COMBO; } /** One-way signals can't be passed the 'wrong' way. */ -static inline bool IsOnewaySignal(TileIndex t, Track track) +static inline bool IsOnewaySignal(Tile t, Track track) { return GetSignalType(t, track) != SIGTYPE_PBS; } -static inline void CycleSignalSide(TileIndex t, Track track) +static inline void CycleSignalSide(Tile t, Track track) { byte sig; byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 4 : 6; - sig = GB(_m[t].m3, pos, 2); + sig = GB(t.m3(), pos, 2); if (--sig == 0) sig = IsPbsSignal(GetSignalType(t, track)) ? 2 : 3; - SB(_m[t].m3, pos, 2, sig); + SB(t.m3(), pos, 2, sig); } -static inline SignalVariant GetSignalVariant(TileIndex t, Track track) +static inline SignalVariant GetSignalVariant(Tile t, Track track) { byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 7 : 3; - return (SignalVariant)GB(_m[t].m2, pos, 1); + return (SignalVariant)GB(t.m2(), pos, 1); } -static inline void SetSignalVariant(TileIndex t, Track track, SignalVariant v) +static inline void SetSignalVariant(Tile t, Track track, SignalVariant v) { byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 7 : 3; - SB(_m[t].m2, pos, 1, v); - if (track == INVALID_TRACK) SB(_m[t].m2, 7, 1, v); + SB(t.m2(), pos, 1, v); + if (track == INVALID_TRACK) SB(t.m2(), 7, 1, v); } /** @@ -349,9 +349,9 @@ static inline void SetSignalVariant(TileIndex t, Track track, SignalVariant v) * @param tile the tile to set the states for * @param state the new state */ -static inline void SetSignalStates(TileIndex tile, uint state) +static inline void SetSignalStates(Tile tile, uint state) { - SB(_m[tile].m4, 4, 4, state); + SB(tile.m4(), 4, 4, state); } /** @@ -359,9 +359,9 @@ static inline void SetSignalStates(TileIndex tile, uint state) * @param tile the tile to set the states for * @return the state of the signals */ -static inline uint GetSignalStates(TileIndex tile) +static inline uint GetSignalStates(Tile tile) { - return GB(_m[tile].m4, 4, 4); + return GB(tile.m4(), 4, 4); } /** @@ -370,7 +370,7 @@ static inline uint GetSignalStates(TileIndex tile) * @param signalbit the signal * @return the state of the signal */ -static inline SignalState GetSingleSignalState(TileIndex t, byte signalbit) +static inline SignalState GetSingleSignalState(Tile t, byte signalbit) { return (SignalState)HasBit(GetSignalStates(t), signalbit); } @@ -380,9 +380,9 @@ static inline SignalState GetSingleSignalState(TileIndex t, byte signalbit) * @param tile the tile to set the present signals for * @param signals the signals that have to be present */ -static inline void SetPresentSignals(TileIndex tile, uint signals) +static inline void SetPresentSignals(Tile tile, uint signals) { - SB(_m[tile].m3, 4, 4, signals); + SB(tile.m3(), 4, 4, signals); } /** @@ -390,9 +390,9 @@ static inline void SetPresentSignals(TileIndex tile, uint signals) * @param tile the tile to get the present signals for * @return the signals that are present */ -static inline uint GetPresentSignals(TileIndex tile) +static inline uint GetPresentSignals(Tile tile) { - return GB(_m[tile].m3, 4, 4); + return GB(tile.m3(), 4, 4); } /** @@ -401,7 +401,7 @@ static inline uint GetPresentSignals(TileIndex tile) * @param signalbit the signal * @return true if and only if the signal is present */ -static inline bool IsSignalPresent(TileIndex t, byte signalbit) +static inline bool IsSignalPresent(Tile t, byte signalbit) { return HasBit(GetPresentSignals(t), signalbit); } @@ -410,7 +410,7 @@ static inline bool IsSignalPresent(TileIndex t, byte signalbit) * Checks for the presence of signals (either way) on the given track on the * given rail tile. */ -static inline bool HasSignalOnTrack(TileIndex tile, Track track) +static inline bool HasSignalOnTrack(Tile tile, Track track) { assert(IsValidTrack(track)); return GetRailTileType(tile) == RAIL_TILE_SIGNALS && (GetPresentSignals(tile) & SignalOnTrack(track)) != 0; @@ -423,7 +423,7 @@ static inline bool HasSignalOnTrack(TileIndex tile, Track track) * Along meaning if you are currently driving on the given trackdir, this is * the signal that is facing us (for which we stop when it's red). */ -static inline bool HasSignalOnTrackdir(TileIndex tile, Trackdir trackdir) +static inline bool HasSignalOnTrackdir(Tile tile, Trackdir trackdir) { assert (IsValidTrackdir(trackdir)); return GetRailTileType(tile) == RAIL_TILE_SIGNALS && GetPresentSignals(tile) & SignalAlongTrackdir(trackdir); @@ -435,7 +435,7 @@ static inline bool HasSignalOnTrackdir(TileIndex tile, Trackdir trackdir) * Along meaning if you are currently driving on the given trackdir, this is * the signal that is facing us (for which we stop when it's red). */ -static inline SignalState GetSignalStateByTrackdir(TileIndex tile, Trackdir trackdir) +static inline SignalState GetSignalStateByTrackdir(Tile tile, Trackdir trackdir) { assert(IsValidTrackdir(trackdir)); assert(HasSignalOnTrack(tile, TrackdirToTrack(trackdir))); @@ -446,7 +446,7 @@ static inline SignalState GetSignalStateByTrackdir(TileIndex tile, Trackdir trac /** * Sets the state of the signal along the given trackdir. */ -static inline void SetSignalStateByTrackdir(TileIndex tile, Trackdir trackdir, SignalState state) +static inline void SetSignalStateByTrackdir(Tile tile, Trackdir trackdir, SignalState state) { if (state == SIGNAL_STATE_GREEN) { // set 1 SetSignalStates(tile, GetSignalStates(tile) | SignalAlongTrackdir(trackdir)); @@ -460,7 +460,7 @@ static inline void SetSignalStateByTrackdir(TileIndex tile, Trackdir trackdir, S * @param tile the tile to check * @param td the trackdir to check */ -static inline bool HasPbsSignalOnTrackdir(TileIndex tile, Trackdir td) +static inline bool HasPbsSignalOnTrackdir(Tile tile, Trackdir td) { return IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, td) && IsPbsSignal(GetSignalType(tile, TrackdirToTrack(td))); @@ -472,14 +472,14 @@ static inline bool HasPbsSignalOnTrackdir(TileIndex tile, Trackdir td) * @param tile the tile to check * @param td the trackdir to check */ -static inline bool HasOnewaySignalBlockingTrackdir(TileIndex tile, Trackdir td) +static inline bool HasOnewaySignalBlockingTrackdir(Tile tile, Trackdir td) { return IsTileType(tile, MP_RAILWAY) && HasSignalOnTrackdir(tile, ReverseTrackdir(td)) && !HasSignalOnTrackdir(tile, td) && IsOnewaySignal(tile, TrackdirToTrack(td)); } -RailType GetTileRailType(TileIndex tile); +RailType GetTileRailType(Tile tile); /** The ground 'under' the rail */ enum RailGroundType { @@ -500,49 +500,49 @@ enum RailGroundType { RAIL_GROUND_HALF_SNOW = 14, ///< Snow only on higher part of slope (steep or one corner raised) }; -static inline void SetRailGroundType(TileIndex t, RailGroundType rgt) +static inline void SetRailGroundType(Tile t, RailGroundType rgt) { - SB(_m[t].m4, 0, 4, rgt); + SB(t.m4(), 0, 4, rgt); } -static inline RailGroundType GetRailGroundType(TileIndex t) +static inline RailGroundType GetRailGroundType(Tile t) { - return (RailGroundType)GB(_m[t].m4, 0, 4); + return (RailGroundType)GB(t.m4(), 0, 4); } -static inline bool IsSnowRailGround(TileIndex t) +static inline bool IsSnowRailGround(Tile t) { return GetRailGroundType(t) == RAIL_GROUND_ICE_DESERT; } -static inline void MakeRailNormal(TileIndex t, Owner o, TrackBits b, RailType r) +static inline void MakeRailNormal(Tile t, Owner o, TrackBits b, RailType r) { SetTileType(t, MP_RAILWAY); SetTileOwner(t, o); SetDockingTile(t, false); - _m[t].m2 = 0; - _m[t].m3 = 0; - _m[t].m4 = 0; - _m[t].m5 = RAIL_TILE_NORMAL << 6 | b; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; - _me[t].m8 = r; + t.m2() = 0; + t.m3() = 0; + t.m4() = 0; + t.m5() = RAIL_TILE_NORMAL << 6 | b; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; + t.m8() = r; } -static inline void MakeRailDepot(TileIndex t, Owner o, DepotID did, DiagDirection d, RailType r) +static inline void MakeRailDepot(Tile t, Owner o, DepotID did, DiagDirection d, RailType r) { SetTileType(t, MP_RAILWAY); SetTileOwner(t, o); SetDockingTile(t, false); - _m[t].m2 = did; - _m[t].m3 = 0; - _m[t].m4 = 0; - _m[t].m5 = RAIL_TILE_DEPOT << 6 | d; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; - _me[t].m8 = r; + t.m2() = did; + t.m3() = 0; + t.m4() = 0; + t.m5() = RAIL_TILE_DEPOT << 6 | d; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; + t.m8() = r; } #endif /* RAIL_MAP_H */ diff --git a/src/road.cpp b/src/road.cpp index d143ae652d576..bbe1960f61a07 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -111,7 +111,8 @@ RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb) bool HasRoadTypeAvail(const CompanyID company, RoadType roadtype) { if (company == OWNER_DEITY || company == OWNER_TOWN || _game_mode == GM_EDITOR || _generating_world) { - return true; // TODO: should there be a proper check? + const RoadTypeInfo *rti = GetRoadTypeInfo(roadtype); + return rti->label != 0 && (rti->flags & ROTFB_HIDDEN) == 0; } else { const Company *c = Company::GetIfValid(company); if (c == nullptr) return false; diff --git a/src/road.h b/src/road.h index 6a2af6698f696..46a1aea031749 100644 --- a/src/road.h +++ b/src/road.h @@ -40,14 +40,14 @@ enum RoadTypeFlags { ROTF_NO_LEVEL_CROSSING, ///< Bit number for disabling level crossing ROTF_NO_HOUSES, ///< Bit number for setting this roadtype as not house friendly ROTF_HIDDEN, ///< Bit number for hidden from construction. - ROTF_TOWN_BUILD, ///< Bit number for allowing towns to build this roadtype. + ROTF_TOWN_BUILD, ///< Bit number for allowing towns to build this roadtype. Does not override ROTF_HIDDEN. ROTFB_NONE = 0, ///< All flags cleared. ROTFB_CATENARY = 1 << ROTF_CATENARY, ///< Value for drawing a catenary. ROTFB_NO_LEVEL_CROSSING = 1 << ROTF_NO_LEVEL_CROSSING, ///< Value for disabling a level crossing. ROTFB_NO_HOUSES = 1 << ROTF_NO_HOUSES, ///< Value for for setting this roadtype as not house friendly. ROTFB_HIDDEN = 1 << ROTF_HIDDEN, ///< Value for hidden from construction. - ROTFB_TOWN_BUILD = 1 << ROTF_TOWN_BUILD, ///< Value for allowing towns to build this roadtype. + ROTFB_TOWN_BUILD = 1 << ROTF_TOWN_BUILD, ///< Value for allowing towns to build this roadtype. Does not override ROTFB_HIDDEN. }; DECLARE_ENUM_AS_BIT_SET(RoadTypeFlags) @@ -58,7 +58,7 @@ enum RoadTypeSpriteGroup { ROTSG_CURSORS, ///< Optional: Cursor and toolbar icon images ROTSG_OVERLAY, ///< Optional: Images for overlaying track ROTSG_GROUND, ///< Required: Main group of ground images - ROTSG_reserved1, ///< Placeholder, if we need specific tunnel sprites. + ROTSG_TUNNEL, ///< Optional: Ground images for tunnels ROTSG_CATENARY_FRONT, ///< Optional: Catenary front ROTSG_CATENARY_BACK, ///< Optional: Catenary back ROTSG_BRIDGE, ///< Required: Bridge surface images @@ -66,6 +66,7 @@ enum RoadTypeSpriteGroup { ROTSG_DEPOT, ///< Optional: Depot images ROTSG_reserved3, ///< Placeholder, if we add road fences (for highways). ROTSG_ROADSTOP, ///< Required: Drive-in stop surface + ROTSG_ONEWAY, ///< Optional: One-way indicator images ROTSG_END, }; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 7394075442bdf..b06ac95676340 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -26,6 +26,7 @@ #include "effectvehicle_base.h" #include "elrail_func.h" #include "roadveh.h" +#include "train.h" #include "town.h" #include "company_base.h" #include "core/random_func.hpp" @@ -502,6 +503,8 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec } if (flags & DC_EXEC) { + MarkDirtyAdjacentLevelCrossingTiles(tile, GetCrossingRoadAxis(tile)); + /* A full diagonal road tile has two road bits. */ UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2); @@ -780,6 +783,7 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, RoadBits pieces, R MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, town_id); SetCrossingReservation(tile, reserved); UpdateLevelCrossing(tile, false); + MarkDirtyAdjacentLevelCrossingTiles(tile, GetCrossingRoadAxis(tile)); MarkTileDirtyByTile(tile); } return CommandCost(EXPENSES_CONSTRUCTION, 2 * RoadBuildCost(rt)); @@ -862,7 +866,7 @@ do_clear:; if (HasPowerOnRoad(rt, existing_rt)) { rt = existing_rt; } else if (HasPowerOnRoad(existing_rt, rt)) { - CommandCost ret = Command::Do(flags, tile, tile, rt); + ret = Command::Do(flags, tile, tile, rt); if (ret.Failed()) return ret; cost.AddCost(ret); } else { @@ -962,8 +966,8 @@ static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir) /** * Build a long piece of road. * @param flags operation to perform - * @param start_tile start tile of drag (the building cost will appear over this tile) * @param end_tile end tile of drag + * @param start_tile start tile of drag * @param rt road type * @param axis direction * @param drd set road direction @@ -974,9 +978,9 @@ static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir) * - true = Fail if an obstacle is found. Always take into account start_half and end_half. This behavior is used for scripts * @return the cost of this operation or an error */ -CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, DisallowedRoadDirections drd, bool start_half, bool end_half, bool is_ai) +CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, RoadType rt, Axis axis, DisallowedRoadDirections drd, bool start_half, bool end_half, bool is_ai) { - if (end_tile >= MapSize()) return CMD_ERROR; + if (start_tile >= Map::Size()) return CMD_ERROR; if (!ValParamRoadType(rt) || !IsValidAxis(axis) || !IsValidDisallowedRoadDirections(drd)) return CMD_ERROR; @@ -1062,19 +1066,19 @@ CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, TileInde /** * Remove a long piece of road. * @param flags operation to perform - * @param start_tile start tile of drag * @param end_tile end tile of drag + * @param start_tile start tile of drag * @param rt road type * @param axis direction * @param start_half start tile starts in the 2nd half of tile * @param end_half end tile starts in the 2nd half of tile (p2 & 2) * @return the cost of this operation or an error */ -std::tuple CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, bool start_half, bool end_half) +std::tuple CmdRemoveLongRoad(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, RoadType rt, Axis axis, bool start_half, bool end_half) { CommandCost cost(EXPENSES_CONSTRUCTION); - if (end_tile >= MapSize()) return { CMD_ERROR, 0 }; + if (start_tile >= Map::Size()) return { CMD_ERROR, 0 }; if (!ValParamRoadType(rt) || !IsValidAxis(axis)) return { CMD_ERROR, 0 }; /* Only drag in X or Y direction dictated by the direction variable */ @@ -1107,7 +1111,7 @@ std::tuple CmdRemoveLongRoad(DoCommandFlag flags, TileIndex if (flags & DC_EXEC) { money_spent += ret.GetCost(); if (money_spent > 0 && money_spent > money_available) { - return { cost, std::get<0>(Command::Do(flags & ~DC_EXEC, start_tile, end_tile, rt, axis, start_half, end_half)).GetCost() }; + return { cost, std::get<0>(Command::Do(flags & ~DC_EXEC, end_tile, start_tile, rt, axis, start_half, end_half)).GetCost() }; } RemoveRoad(tile, flags, bits, rtt, true, false); } @@ -1486,21 +1490,24 @@ static void DrawRoadDetail(SpriteID img, const TileInfo *ti, int dx, int dy, int * @param tram_rti Tram road type information * @param road_offset Road sprite offset (based on road bits) * @param tram_offset Tram sprite offset (based on road bits) + * @param draw_underlay Whether to draw underlays */ -void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rti, uint road_offset, uint tram_offset) +void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rti, uint road_offset, uint tram_offset, bool draw_underlay) { - /* Road underlay takes precedence over tram */ - if (road_rti != nullptr) { - if (road_rti->UsesOverlay()) { - SpriteID ground = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_GROUND); - DrawGroundSprite(ground + road_offset, pal); - } - } else { - if (tram_rti->UsesOverlay()) { - SpriteID ground = GetCustomRoadSprite(tram_rti, ti->tile, ROTSG_GROUND); - DrawGroundSprite(ground + tram_offset, pal); + if (draw_underlay) { + /* Road underlay takes precedence over tram */ + if (road_rti != nullptr) { + if (road_rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_GROUND); + DrawGroundSprite(ground + road_offset, pal); + } } else { - DrawGroundSprite(SPR_TRAMWAY_TRAM + tram_offset, pal); + if (tram_rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(tram_rti, ti->tile, ROTSG_GROUND); + DrawGroundSprite(ground + tram_offset, pal); + } else { + DrawGroundSprite(SPR_TRAMWAY_TRAM + tram_offset, pal); + } } } @@ -1600,7 +1607,17 @@ static void DrawRoadBits(TileInfo *ti) if (road_rti != nullptr) { DisallowedRoadDirections drd = GetDisallowedRoadDirections(ti->tile); if (drd != DRD_NONE) { - DrawGroundSpriteAt(SPR_ONEWAY_BASE + drd - 1 + ((road == ROAD_X) ? 0 : 3), PAL_NONE, 8, 8, GetPartialPixelZ(8, 8, ti->tileh)); + SpriteID oneway = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_ONEWAY); + + if (oneway == 0) oneway = SPR_ONEWAY_BASE; + + if ((ti->tileh == SLOPE_NE) || (ti->tileh == SLOPE_NW)) { + oneway += SPR_ONEWAY_SLOPE_N_OFFSET; + } else if ((ti->tileh == SLOPE_SE) || (ti->tileh == SLOPE_SW)) { + oneway += SPR_ONEWAY_SLOPE_S_OFFSET; + } + + DrawGroundSpriteAt(oneway + drd - 1 + ((road == ROAD_X) ? 0 : 3), PAL_NONE, 8, 8, GetPartialPixelZ(8, 8, ti->tileh)); } } @@ -1699,14 +1716,49 @@ static void DrawTile_Road(TileInfo *ti) /* Draw rail/PBS overlay */ bool draw_pbs = _game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasCrossingReservation(ti->tile); if (rti->UsesOverlay()) { - PaletteID pal = draw_pbs ? PALETTE_CRASH : PAL_NONE; + pal = draw_pbs ? PALETTE_CRASH : PAL_NONE; SpriteID rail = GetCustomRailSprite(rti, ti->tile, RTSG_CROSSING) + axis; DrawGroundSprite(rail, pal); - DrawRailTileSeq(ti, &_crossing_layout, TO_CATENARY, rail, 0, PAL_NONE); + const Axis road_axis = GetCrossingRoadAxis(ti->tile); + const DiagDirection dir1 = AxisToDiagDir(road_axis); + const DiagDirection dir2 = ReverseDiagDir(dir1); + uint adjacent_diagdirs = 0; + for (DiagDirection dir : { dir1, dir2 }) { + const TileIndex t = TileAddByDiagDir(ti->tile, dir); + if (t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis) { + SetBit(adjacent_diagdirs, dir); + } + } + + switch (adjacent_diagdirs) { + case 0: + DrawRailTileSeq(ti, &_crossing_layout, TO_CATENARY, rail, 0, PAL_NONE); + break; + + case (1 << DIAGDIR_NE): + DrawRailTileSeq(ti, &_crossing_layout_SW, TO_CATENARY, rail, 0, PAL_NONE); + break; + + case (1 << DIAGDIR_SE): + DrawRailTileSeq(ti, &_crossing_layout_NW, TO_CATENARY, rail, 0, PAL_NONE); + break; + + case (1 << DIAGDIR_SW): + DrawRailTileSeq(ti, &_crossing_layout_NE, TO_CATENARY, rail, 0, PAL_NONE); + break; + + case (1 << DIAGDIR_NW): + DrawRailTileSeq(ti, &_crossing_layout_SE, TO_CATENARY, rail, 0, PAL_NONE); + break; + + default: + /* Show no sprites */ + break; + } } else if (draw_pbs || tram_rti != nullptr || road_rti->UsesOverlay()) { /* Add another rail overlay, unless there is only the base road sprite. */ - PaletteID pal = draw_pbs ? PALETTE_CRASH : PAL_NONE; + pal = draw_pbs ? PALETTE_CRASH : PAL_NONE; SpriteID rail = GetCrossingRoadAxis(ti->tile) == AXIS_Y ? GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.single_x : GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.single_y; DrawGroundSprite(rail, pal); } @@ -1822,7 +1874,7 @@ void UpdateNearestTownForRoadTiles(bool invalidate) { assert(!invalidate || _generating_world); - for (TileIndex t = 0; t < MapSize(); t++) { + for (TileIndex t = 0; t < Map::Size(); t++) { if (IsTileType(t, MP_ROAD) && !IsRoadDepot(t) && !HasTownOwnedRoad(t)) { TownID tid = INVALID_TOWN; if (!invalidate) { @@ -2033,7 +2085,18 @@ static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, u if (side != INVALID_DIAGDIR && axis != DiagDirToAxis(side)) break; trackdirbits = TrackBitsToTrackdirBits(AxisToTrackBits(axis)); - if (IsCrossingBarred(tile)) red_signals = trackdirbits; + if (IsCrossingBarred(tile)) { + red_signals = trackdirbits; + if (TrainOnCrossing(tile)) break; + + auto mask_red_signal_bits_if_crossing_barred = [&](TileIndex t, TrackdirBits mask) { + if (IsLevelCrossingTile(t) && IsCrossingBarred(t)) red_signals &= mask; + }; + /* Check for blocked adjacent crossing to south, keep only southbound red signal trackdirs, allow northbound traffic */ + mask_red_signal_bits_if_crossing_barred(TileAddByDiagDir(tile, AxisToDiagDir(axis)), TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_SE); + /* Check for blocked adjacent crossing to north, keep only northbound red signal trackdirs, allow southbound traffic */ + mask_red_signal_bits_if_crossing_barred(TileAddByDiagDir(tile, ReverseDiagDir(AxisToDiagDir(axis))), TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_NW); + } break; } @@ -2331,7 +2394,7 @@ CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_s TileIndex area_end = tile; if (!ValParamRoadType(to_type)) return CMD_ERROR; - if (area_start >= MapSize()) return CMD_ERROR; + if (area_start >= Map::Size()) return CMD_ERROR; RoadVehicleList affected_rvs; RoadTramType rtt = GetRoadTramType(to_type); @@ -2340,7 +2403,7 @@ CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_s CommandCost error = CommandCost((rtt == RTT_TRAM) ? STR_ERROR_NO_SUITABLE_TRAMWAY : STR_ERROR_NO_SUITABLE_ROAD); // by default, there is no road to convert. bool found_convertible_road = false; // whether we actually did convert any road/tram (see bug #7633) - TileIterator *iter = new OrthogonalTileIterator(area_start, area_end); + std::unique_ptr iter = std::make_unique(area_start, area_end); for (; (tile = *iter) != INVALID_TILE; ++(*iter)) { /* Is road present on tile? */ if (!MayHaveRoad(tile)) continue; @@ -2496,7 +2559,6 @@ CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_s } } - delete iter; return found_convertible_road ? cost : error; } diff --git a/src/road_cmd.h b/src/road_cmd.h index 82f09d2fa933d..fbe05ef33d653 100644 --- a/src/road_cmd.h +++ b/src/road_cmd.h @@ -14,11 +14,13 @@ #include "road_type.h" #include "command_type.h" +enum RoadStopClassID : byte; + void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt); void UpdateNearestTownForRoadTiles(bool invalidate); -CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, DisallowedRoadDirections drd, bool start_half, bool end_half, bool is_ai); -std::tuple CmdRemoveLongRoad(DoCommandFlag flags, TileIndex start_tile, TileIndex end_tile, RoadType rt, Axis axis, bool start_half, bool end_half); +CommandCost CmdBuildLongRoad(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, RoadType rt, Axis axis, DisallowedRoadDirections drd, bool start_half, bool end_half, bool is_ai); +std::tuple CmdRemoveLongRoad(DoCommandFlag flags, TileIndex end_tile, TileIndex start_tile, RoadType rt, Axis axis, bool start_half, bool end_half); CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, RoadBits pieces, RoadType rt, DisallowedRoadDirections toggle_drd, TownID town_id); CommandCost CmdBuildRoadDepot(DoCommandFlag flags, TileIndex tile, RoadType rt, DiagDirection dir); CommandCost CmdConvertRoad(DoCommandFlag flags, TileIndex tile, TileIndex area_start, RoadType to_type); @@ -32,6 +34,6 @@ DEF_CMD_TRAIT(CMD_CONVERT_ROAD, CmdConvertRoad, 0, CommandCallback CcPlaySound_CONSTRUCTION_OTHER; CommandCallback CcBuildRoadTunnel; void CcRoadDepot(Commands cmd, const CommandCost &result, TileIndex tile, RoadType rt, DiagDirection dir); -void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8 width, uint8 length, RoadStopType, bool is_drive_through, DiagDirection dir, RoadType, StationID, bool); +void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8 width, uint8 length, RoadStopType, bool is_drive_through, DiagDirection dir, RoadType, RoadStopClassID spec_class, byte spec_index, StationID, bool); #endif /* ROAD_CMD_H */ diff --git a/src/road_func.h b/src/road_func.h index 9376460575e27..2db2f24fe369d 100644 --- a/src/road_func.h +++ b/src/road_func.h @@ -153,10 +153,11 @@ RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces = true); RoadTypes GetRoadTypes(bool introduces); RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, Date date); -void UpdateLevelCrossing(TileIndex tile, bool sound = true); +void UpdateLevelCrossing(TileIndex tile, bool sound = true, bool force_bar = false); +void MarkDirtyAdjacentLevelCrossingTiles(TileIndex tile, Axis road_axis); void UpdateCompanyRoadInfrastructure(RoadType rt, Owner o, int count); struct TileInfo; -void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rit, uint road_offset, uint tram_offset); +void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rit, uint road_offset, uint tram_offset, bool draw_underlay = true); #endif /* ROAD_FUNC_H */ diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 80a8ed618cf92..0c9ee9d298068 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -34,6 +34,11 @@ #include "station_cmd.h" #include "road_cmd.h" #include "tunnelbridge_cmd.h" +#include "newgrf_roadstop.h" +#include "querystring_gui.h" +#include "sortlist_type.h" +#include "stringfilter_type.h" +#include "string_func.h" #include "widgets/road_widget.h" @@ -55,7 +60,42 @@ static bool _place_road_end_half; static RoadType _cur_roadtype; static DiagDirection _road_depot_orientation; -static DiagDirection _road_station_picker_orientation; + +struct RoadStopGUISettings { + DiagDirection orientation; + + RoadStopClassID roadstop_class; + byte roadstop_type; + byte roadstop_count; +}; +static RoadStopGUISettings _roadstop_gui_settings; + +/** + * Check whether a road stop type can be built. + * @return true if building is allowed. + */ +static bool IsRoadStopAvailable(const RoadStopSpec *roadstopspec, StationType type) +{ + if (roadstopspec == nullptr) return true; + + if (HasBit(roadstopspec->flags, RSF_BUILD_MENU_ROAD_ONLY) && !RoadTypeIsRoad(_cur_roadtype)) return false; + if (HasBit(roadstopspec->flags, RSF_BUILD_MENU_TRAM_ONLY) && !RoadTypeIsTram(_cur_roadtype)) return false; + + if (roadstopspec->stop_type != ROADSTOPTYPE_ALL) { + switch (type) { + case STATION_BUS: if (roadstopspec->stop_type != ROADSTOPTYPE_PASSENGER) return false; break; + case STATION_TRUCK: if (roadstopspec->stop_type != ROADSTOPTYPE_FREIGHT) return false; break; + default: break; + } + } + + if (!HasBit(roadstopspec->callback_mask, CBM_ROAD_STOP_AVAIL)) return true; + + uint16 cb_res = GetRoadStopCallback(CBID_STATION_AVAILABILITY, 0, 0, roadstopspec, nullptr, INVALID_TILE, _cur_roadtype, type, 0); + if (cb_res == CALLBACK_FAILED) return true; + + return Convert8bitBooleanCallback(roadstopspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res); +} void CcPlaySound_CONSTRUCTION_OTHER(Commands cmd, const CommandCost &result, TileIndex tile) { @@ -135,19 +175,31 @@ void CcRoadDepot(Commands cmd, const CommandCost &result, TileIndex tile, RoadTy * @param length Length of the road stop. * @param is_drive_through False for normal stops, true for drive-through. * @param dir Entrance direction (#DiagDirection) for normal stops. Converted to the axis for drive-through stops. + * @param spec_class Road stop spec class. + * @param spec_index Road stop spec index. * @see CmdBuildRoadStop */ -void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8 width, uint8 length, RoadStopType, bool is_drive_through, DiagDirection dir, RoadType, StationID, bool) +void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8 width, uint8 length, RoadStopType, bool is_drive_through, + DiagDirection dir, RoadType, RoadStopClassID spec_class, byte spec_index, StationID, bool) { if (result.Failed()) return; if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); - TileArea roadstop_area(tile, width, length); - for (TileIndex cur_tile : roadstop_area) { - ConnectRoadToStructure(cur_tile, dir); - /* For a drive-through road stop build connecting road for other entrance. */ - if (is_drive_through) ConnectRoadToStructure(cur_tile, ReverseDiagDir(dir)); + + bool connect_to_road = true; + if ((uint)spec_class < RoadStopClass::GetClassCount() && spec_index < RoadStopClass::Get(spec_class)->GetSpecCount()) { + const RoadStopSpec *roadstopspec = RoadStopClass::Get(spec_class)->GetSpec(spec_index); + if (roadstopspec != nullptr && HasBit(roadstopspec->flags, RSF_NO_AUTO_ROAD_CONNECTION)) connect_to_road = false; + } + + if (connect_to_road) { + TileArea roadstop_area(tile, width, length); + for (TileIndex cur_tile : roadstop_area) { + ConnectRoadToStructure(cur_tile, dir); + /* For a drive-through road stop build connecting road for other entrance. */ + if (is_drive_through) ConnectRoadToStructure(cur_tile, ReverseDiagDir(dir)); + } } } @@ -164,15 +216,19 @@ void CcRoadStop(Commands cmd, const CommandCost &result, TileIndex tile, uint8 w static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, RoadStopType stop_type, bool adjacent, RoadType rt, StringID err_msg) { TileArea ta(start_tile, end_tile); - DiagDirection ddir = _road_station_picker_orientation; + DiagDirection ddir = _roadstop_gui_settings.orientation; bool drive_through = ddir >= DIAGDIR_END; if (drive_through) ddir = static_cast(ddir - DIAGDIR_END); // Adjust picker result to actual direction. + RoadStopClassID spec_class = _roadstop_gui_settings.roadstop_class; + byte spec_index = _roadstop_gui_settings.roadstop_type; auto proc = [=](bool test, StationID to_join) -> bool { if (test) { - return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), ta.tile, ta.w, ta.h, stop_type, drive_through, ddir, rt, INVALID_STATION, adjacent).Succeeded(); + return Command::Do(CommandFlagsToDCFlags(GetCommandFlags()), ta.tile, ta.w, ta.h, stop_type, drive_through, + ddir, rt, spec_class, spec_index, INVALID_STATION, adjacent).Succeeded(); } else { - return Command::Post(err_msg, CcRoadStop, ta.tile, ta.w, ta.h, stop_type, drive_through, ddir, rt, to_join, adjacent); + return Command::Post(err_msg, CcRoadStop, ta.tile, ta.w, ta.h, stop_type, drive_through, + ddir, rt, spec_class, spec_index, to_join, adjacent); } }; @@ -188,8 +244,8 @@ static void PlaceRoad_BusStation(TileIndex tile) if (_remove_button_clicked) { VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_BUSSTOP); } else { - if (_road_station_picker_orientation < DIAGDIR_END) { // Not a drive-through stop. - VpStartPlaceSizing(tile, (DiagDirToAxis(_road_station_picker_orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_BUSSTOP); + if (_roadstop_gui_settings.orientation < DIAGDIR_END) { // Not a drive-through stop. + VpStartPlaceSizing(tile, (DiagDirToAxis(_roadstop_gui_settings.orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_BUSSTOP); } else { VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_BUSSTOP); } @@ -206,8 +262,8 @@ static void PlaceRoad_TruckStation(TileIndex tile) if (_remove_button_clicked) { VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_REMOVE_TRUCKSTOP); } else { - if (_road_station_picker_orientation < DIAGDIR_END) { // Not a drive-through stop. - VpStartPlaceSizing(tile, (DiagDirToAxis(_road_station_picker_orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_TRUCKSTOP); + if (_roadstop_gui_settings.orientation < DIAGDIR_END) { // Not a drive-through stop. + VpStartPlaceSizing(tile, (DiagDirToAxis(_roadstop_gui_settings.orientation) == AXIS_X) ? VPM_X_LIMITED : VPM_Y_LIMITED, DDSP_BUILD_TRUCKSTOP); } else { VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_TRUCKSTOP); } @@ -642,17 +698,17 @@ struct BuildRoadToolbarWindow : Window { if (_remove_button_clicked) { Command::Post(this->rti->strings.err_remove_road, CcPlaySound_CONSTRUCTION_OTHER, - start_tile, end_tile, _cur_roadtype, _place_road_dir, start_half, _place_road_end_half); + end_tile, start_tile, _cur_roadtype, _place_road_dir, start_half, _place_road_end_half); } else { Command::Post(this->rti->strings.err_build_road, CcPlaySound_CONSTRUCTION_OTHER, - start_tile, end_tile, _cur_roadtype, _place_road_dir, _one_way_button_clicked ? DRD_NORTHBOUND : DRD_NONE, start_half, _place_road_end_half, false); + end_tile, start_tile, _cur_roadtype, _place_road_dir, _one_way_button_clicked ? DRD_NORTHBOUND : DRD_NONE, start_half, _place_road_end_half, false); } break; } case DDSP_BUILD_BUSSTOP: case DDSP_REMOVE_BUSSTOP: - if (this->IsWidgetLowered(WID_ROT_BUS_STATION)) { + if (this->IsWidgetLowered(WID_ROT_BUS_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), ROADSTOP_BUS, _cur_roadtype)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); Command::Post(this->rti->strings.err_remove_station[ROADSTOP_BUS], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w, ta.h, ROADSTOP_BUS, _ctrl_pressed); @@ -664,7 +720,7 @@ struct BuildRoadToolbarWindow : Window { case DDSP_BUILD_TRUCKSTOP: case DDSP_REMOVE_TRUCKSTOP: - if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION)) { + if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), ROADSTOP_TRUCK, _cur_roadtype)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); Command::Post(this->rti->strings.err_remove_station[ROADSTOP_TRUCK], CcPlaySound_CONSTRUCTION_OTHER, ta.tile, ta.w, ta.h, ROADSTOP_TRUCK, _ctrl_pressed); @@ -974,15 +1030,21 @@ struct BuildRoadDepotWindow : public PickerWindowBase { { if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return; - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(48) + 2; + size->width = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Horizontal(); + size->height = ScaleGUITrad(48) + WidgetDimensions::scaled.fullbevel.Vertical(); } void DrawWidget(const Rect &r, int widget) const override { if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return; - DrawRoadDepotSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), (DiagDirection)(widget - WID_BROD_DEPOT_NE + DIAGDIR_NE), _cur_roadtype); + DrawPixelInfo tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); + int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); + int y = (r.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31); + DrawRoadDepotSprite(x, y, (DiagDirection)(widget - WID_BROD_DEPOT_NE + DIAGDIR_NE), _cur_roadtype); + } } void OnClick(Point pt, int widget, int click_count) override @@ -1011,27 +1073,20 @@ static const NWidgetPart _nested_build_road_depot_widgets[] = { NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROD_CAPTION), SetDataTip(STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN), - NWidget(NWID_SPACER), SetMinimalSize(0, 3), - NWidget(NWID_HORIZONTAL_LTR), - NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0), - NWidget(NWID_VERTICAL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SW), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), - EndContainer(), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(2, 0), - NWidget(NWID_VERTICAL), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), + NWidget(NWID_HORIZONTAL), SetPadding(3), + NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(NWID_VERTICAL), SetPIP(0, 2, 0), + NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, 2, 0), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NW), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_NE), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SE), SetMinimalSize(66, 50), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), + NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, 2, 0), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SW), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROD_DEPOT_SE), SetMinimalSize(66, 50), SetFill(0, 0), SetDataTip(0x0, STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP), EndContainer(), EndContainer(), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(3, 0), SetFill(1, 0), + NWidget(NWID_SPACER), SetFill(1, 0), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 3), EndContainer(), }; @@ -1047,14 +1102,91 @@ static void ShowRoadDepotPicker(Window *parent) new BuildRoadDepotWindow(&_build_road_depot_desc, parent); } +/** Enum referring to the Hotkeys in the build road stop window */ +enum BuildRoadStopHotkeys { + BROSHK_FOCUS_FILTER_BOX, ///< Focus the edit box for editing the filter string +}; + struct BuildRoadStationWindow : public PickerWindowBase { - BuildRoadStationWindow(WindowDesc *desc, Window *parent, RoadStopType rs) : PickerWindowBase(desc, parent) +private: + RoadStopType roadStopType; ///< The RoadStopType for this Window. + uint line_height; ///< Height of a single line in the newstation selection matrix. + uint coverage_height; ///< Height of the coverage texts. + Scrollbar *vscrollList; ///< Vertical scrollbar of the new station list. + Scrollbar *vscrollMatrix; ///< Vertical scrollbar of the station picker matrix. + + typedef GUIList GUIRoadStopClassList; ///< Type definition for the list to hold available road stop classes. + + static const uint EDITBOX_MAX_SIZE = 16; ///< The maximum number of characters for the filter edit box. + + static Listing last_sorting; ///< Default sorting of #GUIRoadStopClassList. + static Filtering last_filtering; ///< Default filtering of #GUIRoadStopClassList. + static GUIRoadStopClassList::SortFunction * const sorter_funcs[]; ///< Sort functions of the #GUIRoadStopClassList. + static GUIRoadStopClassList::FilterFunction * const filter_funcs[]; ///< Filter functions of the #GUIRoadStopClassList. + GUIRoadStopClassList roadstop_classes; ///< Available road stop classes. + StringFilter string_filter; ///< Filter for available road stop classes. + QueryString filter_editbox; ///< Filter editbox. + + void EnsureSelectedClassIsVisible() + { + uint pos = 0; + for (auto rs_class : this->roadstop_classes) { + if (rs_class == _roadstop_gui_settings.roadstop_class) break; + pos++; + } + this->vscrollList->SetCount((int)this->roadstop_classes.size()); + this->vscrollList->ScrollTowards(pos); + } + + void CheckOrientationValid() + { + if (_roadstop_gui_settings.orientation >= DIAGDIR_END) return; + const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(_roadstop_gui_settings.roadstop_type); + if (spec != nullptr && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) { + this->RaiseWidget(_roadstop_gui_settings.orientation + WID_BROS_STATION_NE); + _roadstop_gui_settings.orientation = DIAGDIR_END; + this->LowerWidget(_roadstop_gui_settings.orientation + WID_BROS_STATION_NE); + this->SetDirty(); + CloseWindowById(WC_SELECT_STATION, 0); + } + } + +public: + BuildRoadStationWindow(WindowDesc *desc, Window *parent, RoadStopType rs) : PickerWindowBase(desc, parent), filter_editbox(EDITBOX_MAX_SIZE * MAX_CHAR_LENGTH, EDITBOX_MAX_SIZE) { + this->coverage_height = 2 * FONT_HEIGHT_NORMAL + 3 * WidgetDimensions::scaled.vsep_normal; + this->vscrollList = nullptr; + this->vscrollMatrix = nullptr; + this->roadStopType = rs; + bool newstops = GetIfNewStopsByType(rs, _cur_roadtype); + this->CreateNestedTree(); + /* Hide the station class filter if no stations other than the default one are available. */ + this->GetWidget(WID_BROS_SHOW_NEWST_DEFSIZE)->SetDisplayedPlane(newstops ? 0 : SZSP_NONE); + this->GetWidget(WID_BROS_FILTER_CONTAINER)->SetDisplayedPlane(newstops ? 0 : SZSP_HORIZONTAL); + this->GetWidget(WID_BROS_SHOW_NEWST_ADDITIONS)->SetDisplayedPlane(newstops ? 0 : SZSP_HORIZONTAL); + this->GetWidget(WID_BROS_SHOW_NEWST_ORIENTATION)->SetDisplayedPlane(newstops ? 0 : SZSP_HORIZONTAL); + this->GetWidget(WID_BROS_SHOW_NEWST_TYPE_SEL)->SetDisplayedPlane(newstops ? 0 : SZSP_HORIZONTAL); + this->GetWidget(WID_BROS_SHOW_NEWST_MATRIX)->SetDisplayedPlane(newstops ? 0 : SZSP_NONE); + this->GetWidget(WID_BROS_SHOW_NEWST_RESIZE)->SetDisplayedPlane(newstops ? 0 : SZSP_NONE); + if (newstops) { + this->vscrollList = this->GetScrollbar(WID_BROS_NEWST_SCROLL); + this->vscrollMatrix = this->GetScrollbar(WID_BROS_MATRIX_SCROLL); + + this->querystrings[WID_BROS_FILTER_EDITBOX] = &this->filter_editbox; + this->roadstop_classes.SetListing(this->last_sorting); + this->roadstop_classes.SetFiltering(this->last_filtering); + this->roadstop_classes.SetSortFuncs(this->sorter_funcs); + this->roadstop_classes.SetFilterFuncs(this->filter_funcs); + } + + this->roadstop_classes.ForceRebuild(); + BuildRoadStopClassesAvailable(); + /* Trams don't have non-drivethrough stations */ - if (RoadTypeIsTram(_cur_roadtype) && _road_station_picker_orientation < DIAGDIR_END) { - _road_station_picker_orientation = DIAGDIR_END; + if (RoadTypeIsTram(_cur_roadtype) && _roadstop_gui_settings.orientation < DIAGDIR_END) { + _roadstop_gui_settings.orientation = DIAGDIR_END; } const RoadTypeInfo *rti = GetRoadTypeInfo(_cur_roadtype); this->GetWidget(WID_BROS_CAPTION)->widget_data = rti->strings.picker_title[rs]; @@ -1063,12 +1195,42 @@ struct BuildRoadStationWindow : public PickerWindowBase { this->GetWidget(i)->tool_tip = rti->strings.picker_tooltip[rs]; } - this->LowerWidget(_road_station_picker_orientation + WID_BROS_STATION_NE); + this->LowerWidget(_roadstop_gui_settings.orientation + WID_BROS_STATION_NE); this->LowerWidget(_settings_client.gui.station_show_coverage + WID_BROS_LT_OFF); this->FinishInitNested(TRANSPORT_ROAD); this->window_class = (rs == ROADSTOP_BUS) ? WC_BUS_STATION : WC_TRUCK_STATION; + if (!newstops || _roadstop_gui_settings.roadstop_class >= (int)RoadStopClass::GetClassCount()) { + /* There's no new stops available or the list has reduced in size. + * Now, set the default road stops as selected. */ + _roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT; + _roadstop_gui_settings.roadstop_type = 0; + } + if (newstops) { + /* The currently selected class doesn't have any stops for this RoadStopType, reset the selection. */ + if (!GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), rs, _cur_roadtype)) { + _roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT; + _roadstop_gui_settings.roadstop_type = 0; + } + _roadstop_gui_settings.roadstop_count = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpecCount(); + _roadstop_gui_settings.roadstop_type = std::min((int)_roadstop_gui_settings.roadstop_type, _roadstop_gui_settings.roadstop_count - 1); + + /* Reset back to default class if the previously selected class is not available for this road stop type. */ + if (!GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), roadStopType, _cur_roadtype)) { + _roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT; + } + + this->SelectFirstAvailableTypeIfUnavailable(); + + NWidgetMatrix *matrix = this->GetWidget(WID_BROS_MATRIX); + matrix->SetScrollbar(this->vscrollMatrix); + matrix->SetCount(_roadstop_gui_settings.roadstop_count); + matrix->SetClicked(_roadstop_gui_settings.roadstop_type); + + this->EnsureSelectedClassIsVisible(); + this->CheckOrientationValid(); + } } void Close() override @@ -1077,6 +1239,94 @@ struct BuildRoadStationWindow : public PickerWindowBase { this->PickerWindowBase::Close(); } + /** Sort classes by RoadStopClassID. */ + static bool RoadStopClassIDSorter(RoadStopClassID const &a, RoadStopClassID const &b) + { + return a < b; + } + + /** Filter classes by class name. */ + static bool CDECL TagNameFilter(RoadStopClassID const *sc, StringFilter &filter) + { + char buffer[DRAW_STRING_BUFFER]; + GetString(buffer, RoadStopClass::Get(*sc)->name, lastof(buffer)); + + filter.ResetState(); + filter.AddLine(buffer); + return filter.GetState(); + } + + inline bool ShowNewStops() const + { + return this->vscrollList != nullptr; + } + + void BuildRoadStopClassesAvailable() + { + if (!this->roadstop_classes.NeedRebuild()) return; + + this->roadstop_classes.clear(); + + for (uint i = 0; i < RoadStopClass::GetClassCount(); i++) { + RoadStopClassID rs_id = (RoadStopClassID)i; + if (rs_id == ROADSTOP_CLASS_WAYP) { + // Skip waypoints. + continue; + } + RoadStopClass *rs_class = RoadStopClass::Get(rs_id); + if (GetIfClassHasNewStopsByType(rs_class, this->roadStopType, _cur_roadtype)) this->roadstop_classes.push_back(rs_id); + } + + if (this->ShowNewStops()) { + this->roadstop_classes.Filter(this->string_filter); + this->roadstop_classes.shrink_to_fit(); + this->roadstop_classes.RebuildDone(); + this->roadstop_classes.Sort(); + + this->vscrollList->SetCount((uint)this->roadstop_classes.size()); + } + } + + void SelectFirstAvailableTypeIfUnavailable() + { + const RoadStopClass *rs_class = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class); + StationType st = GetRoadStationTypeByWindowClass(this->window_class); + + if (IsRoadStopAvailable(rs_class->GetSpec(_roadstop_gui_settings.roadstop_type), st)) return; + for (uint i = 0; i < _roadstop_gui_settings.roadstop_count; i++) { + if (IsRoadStopAvailable(rs_class->GetSpec(i), st)) { + _roadstop_gui_settings.roadstop_type = i; + break; + } + } + } + + void OnInvalidateData(int data = 0, bool gui_scope = true) override + { + if (!gui_scope) return; + + this->BuildRoadStopClassesAvailable(); + } + + EventState OnHotkey(int hotkey) override + { + if (hotkey == BROSHK_FOCUS_FILTER_BOX) { + this->SetFocusedWidget(WID_BROS_FILTER_EDITBOX); + SetFocusedWindow(this); // The user has asked to give focus to the text box, so make sure this window is focused. + return ES_HANDLED; + } + + return ES_NOT_HANDLED; + } + + void OnEditboxChanged(int wid) override + { + string_filter.SetFilterTerm(this->filter_editbox.text.buf); + this->roadstop_classes.SetFilterState(!string_filter.IsEmpty()); + this->roadstop_classes.ForceRebuild(); + this->InvalidateData(); + } + void OnPaint() override { this->DrawWidgets(); @@ -1088,50 +1338,187 @@ struct BuildRoadStationWindow : public PickerWindowBase { SetTileSelectSize(1, 1); } + if (this->IsShaded()) return; + /* 'Accepts' and 'Supplies' texts. */ StationCoverageType sct = (this->window_class == WC_BUS_STATION) ? SCT_PASSENGERS_ONLY : SCT_NON_PASSENGERS_ONLY; - int top = this->GetWidget(WID_BROS_LT_ON)->pos_y + this->GetWidget(WID_BROS_LT_ON)->current_y + WD_PAR_VSEP_NORMAL; - NWidgetBase *back_nwi = this->GetWidget(WID_BROS_BACKGROUND); - int right = back_nwi->pos_x + back_nwi->current_x; - int bottom = back_nwi->pos_y + back_nwi->current_y; - top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, sct, rad, false) + WD_PAR_VSEP_NORMAL; - top = DrawStationCoverageAreaText(back_nwi->pos_x + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, sct, rad, true) + WD_PAR_VSEP_NORMAL; + Rect r = this->GetWidget(WID_BROS_ACCEPTANCE)->GetCurrentRect(); + int top = r.top + WidgetDimensions::scaled.vsep_normal; + top = DrawStationCoverageAreaText(r.left, r.right, top, sct, rad, false) + WidgetDimensions::scaled.vsep_normal; + top = DrawStationCoverageAreaText(r.left, r.right, top, sct, rad, true) + WidgetDimensions::scaled.vsep_normal; /* Resize background if the window is too small. * Never make the window smaller to avoid oscillating if the size change affects the acceptance. * (This is the case, if making the window bigger moves the mouse into the window.) */ - if (top > bottom) { - ResizeWindow(this, 0, top - bottom, false); + if (top > r.bottom) { + this->coverage_height += top - r.bottom; + this->ReInit(); } } void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { - if (!IsInsideMM(widget, WID_BROS_STATION_NE, WID_BROS_STATION_Y + 1)) return; + switch (widget) { + case WID_BROS_NEWST_LIST: { + Dimension d = { 0, 0 }; + for (auto rs_class : this->roadstop_classes) { + d = maxdim(d, GetStringBoundingBox(RoadStopClass::Get(rs_class)->name)); + } + size->width = std::max(size->width, d.width + padding.width); + this->line_height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.matrix.Vertical(); + size->height = 5 * this->line_height; + resize->height = this->line_height; + break; + } - size->width = ScaleGUITrad(64) + 2; - size->height = ScaleGUITrad(48) + 2; + case WID_BROS_SHOW_NEWST_TYPE: { + Dimension d = {0, 0}; + StringID str = this->GetWidget(widget)->widget_data; + for (auto roadstop_class : this->roadstop_classes) { + RoadStopClass *rs_class = RoadStopClass::Get(roadstop_class); + for (uint j = 0; j < rs_class->GetSpecCount(); j++) { + const RoadStopSpec *roadstopspec = rs_class->GetSpec(j); + SetDParam(0, (roadstopspec != nullptr && roadstopspec->name != 0) ? roadstopspec->name : STR_STATION_CLASS_DFLT); + d = maxdim(d, GetStringBoundingBox(str)); + } + } + size->width = std::max(size->width, d.width + padding.width); + break; + } + + case WID_BROS_STATION_NE: + case WID_BROS_STATION_SE: + case WID_BROS_STATION_SW: + case WID_BROS_STATION_NW: + case WID_BROS_STATION_X: + case WID_BROS_STATION_Y: + case WID_BROS_IMAGE: + size->width = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Horizontal(); + size->height = ScaleGUITrad(48) + WidgetDimensions::scaled.fullbevel.Vertical(); + break; + + case WID_BROS_MATRIX: + fill->height = 1; + resize->height = 1; + break; + + case WID_BROS_ACCEPTANCE: + size->height = this->coverage_height; + break; + } + } + + /** + * Simply to have a easier way to get the StationType for bus, truck and trams from the WindowClass. + */ + StationType GetRoadStationTypeByWindowClass(WindowClass window_class) const { + switch (window_class) { + case WC_BUS_STATION: return STATION_BUS; + case WC_TRUCK_STATION: return STATION_TRUCK; + default: NOT_REACHED(); + } } void DrawWidget(const Rect &r, int widget) const override { - if (!IsInsideMM(widget, WID_BROS_STATION_NE, WID_BROS_STATION_Y + 1)) return; + switch (GB(widget, 0, 16)) { + case WID_BROS_STATION_NE: + case WID_BROS_STATION_SE: + case WID_BROS_STATION_SW: + case WID_BROS_STATION_NW: + case WID_BROS_STATION_X: + case WID_BROS_STATION_Y: { + StationType st = GetRoadStationTypeByWindowClass(this->window_class); + const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(_roadstop_gui_settings.roadstop_type); + bool disabled = (spec != nullptr && widget < WID_BROS_STATION_X && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)); + DrawPixelInfo tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); + int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); + int y = (r.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31); + if (spec == nullptr || disabled) { + StationPickerDrawSprite(x, y, st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE); + if (disabled) GfxFillRect(1, 1, r.Width() - 1, r.Height() - 1, PC_BLACK, FILLRECT_CHECKER); + } else { + DrawRoadStopTile(x, y, _cur_roadtype, spec, st, widget - WID_BROS_STATION_NE); + } + } + break; + } + + case WID_BROS_NEWST_LIST: { + uint statclass = 0; + uint row = 0; + for (auto rs_class : this->roadstop_classes) { + if (this->vscrollList->IsVisible(statclass)) { + DrawString(r.left + WidgetDimensions::scaled.matrix.left, r.right, row * this->line_height + r.top + WidgetDimensions::scaled.matrix.top, + RoadStopClass::Get(rs_class)->name, + rs_class == _roadstop_gui_settings.roadstop_class ? TC_WHITE : TC_BLACK); + row++; + } + statclass++; + } + break; + } + + case WID_BROS_IMAGE: { + byte type = GB(widget, 16, 16); + assert(type < _roadstop_gui_settings.roadstop_count); + + const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(type); + StationType st = GetRoadStationTypeByWindowClass(this->window_class); + + if (!IsRoadStopAvailable(spec, st)) { + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), PC_BLACK, FILLRECT_CHECKER); + } - StationType st = (this->window_class == WC_BUS_STATION) ? STATION_BUS : STATION_TRUCK; - StationPickerDrawSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE); + /* Set up a clipping area for the sprite preview. */ + DrawPixelInfo tmp_dpi; + if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); + int x = (r.Width() - ScaleSpriteTrad(64)) / 2 + ScaleSpriteTrad(31); + int y = (r.Height() + ScaleSpriteTrad(48)) / 2 - ScaleSpriteTrad(31); + if (spec == nullptr) { + StationPickerDrawSprite(x, y, st, INVALID_RAILTYPE, _cur_roadtype, _roadstop_gui_settings.orientation); + } else { + DiagDirection orientation = _roadstop_gui_settings.orientation; + if (orientation < DIAGDIR_END && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) orientation = DIAGDIR_END; + DrawRoadStopTile(x, y, _cur_roadtype, spec, st, (uint8)orientation); + } + } + break; + } + } + } + + void OnResize() override { + if (this->vscrollList != nullptr) { + this->vscrollList->SetCapacityFromWidget(this, WID_BROS_NEWST_LIST); + } + } + + void SetStringParameters(int widget) const override { + if (widget == WID_BROS_SHOW_NEWST_TYPE) { + const RoadStopSpec *roadstopspec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(_roadstop_gui_settings.roadstop_type); + SetDParam(0, (roadstopspec != nullptr && roadstopspec->name != 0) ? roadstopspec->name : STR_STATION_CLASS_DFLT); + } } void OnClick(Point pt, int widget, int click_count) override { - switch (widget) { + switch (GB(widget, 0, 16)) { case WID_BROS_STATION_NE: case WID_BROS_STATION_SE: case WID_BROS_STATION_SW: case WID_BROS_STATION_NW: case WID_BROS_STATION_X: case WID_BROS_STATION_Y: - this->RaiseWidget(_road_station_picker_orientation + WID_BROS_STATION_NE); - _road_station_picker_orientation = (DiagDirection)(widget - WID_BROS_STATION_NE); - this->LowerWidget(_road_station_picker_orientation + WID_BROS_STATION_NE); + if (widget < WID_BROS_STATION_X) { + const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(_roadstop_gui_settings.roadstop_type); + if (spec != nullptr && HasBit(spec->flags, RSF_DRIVE_THROUGH_ONLY)) return; + } + this->RaiseWidget(_roadstop_gui_settings.orientation + WID_BROS_STATION_NE); + _roadstop_gui_settings.orientation = (DiagDirection)(widget - WID_BROS_STATION_NE); + this->LowerWidget(_roadstop_gui_settings.orientation + WID_BROS_STATION_NE); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); this->SetDirty(); CloseWindowById(WC_SELECT_STATION, 0); @@ -1147,6 +1534,48 @@ struct BuildRoadStationWindow : public PickerWindowBase { SetViewportCatchmentStation(nullptr, true); break; + case WID_BROS_NEWST_LIST: { + int y = this->vscrollList->GetScrolledRowFromWidget(pt.y, this, WID_BROS_NEWST_LIST); + if (y >= (int)this->roadstop_classes.size()) return; + RoadStopClassID class_id = this->roadstop_classes[y]; + if (_roadstop_gui_settings.roadstop_class != class_id && GetIfClassHasNewStopsByType(RoadStopClass::Get(class_id), roadStopType, _cur_roadtype)) { + _roadstop_gui_settings.roadstop_class = class_id; + RoadStopClass *rsclass = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class); + _roadstop_gui_settings.roadstop_count = rsclass->GetSpecCount(); + _roadstop_gui_settings.roadstop_type = std::min((int)_roadstop_gui_settings.roadstop_type, std::max(0, (int)_roadstop_gui_settings.roadstop_count - 1)); + this->SelectFirstAvailableTypeIfUnavailable(); + + NWidgetMatrix *matrix = this->GetWidget(WID_BROS_MATRIX); + matrix->SetCount(_roadstop_gui_settings.roadstop_count); + matrix->SetClicked(_roadstop_gui_settings.roadstop_type); + this->CheckOrientationValid(); + } + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + this->SetDirty(); + CloseWindowById(WC_SELECT_STATION, 0); + break; + } + + case WID_BROS_IMAGE: { + int y = GB(widget, 16, 16); + if (y >= _roadstop_gui_settings.roadstop_count) return; + + const RoadStopSpec *spec = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class)->GetSpec(y); + StationType st = GetRoadStationTypeByWindowClass(this->window_class); + + if (!IsRoadStopAvailable(spec, st)) return; + + _roadstop_gui_settings.roadstop_type = y; + + this->GetWidget(WID_BROS_MATRIX)->SetClicked(_roadstop_gui_settings.roadstop_type); + + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + this->SetDirty(); + CloseWindowById(WC_SELECT_STATION, 0); + this->CheckOrientationValid(); + break; + } + default: break; } @@ -1156,6 +1585,25 @@ struct BuildRoadStationWindow : public PickerWindowBase { { CheckRedrawStationCoverage(this); } + + static HotkeyList hotkeys; +}; + +static Hotkey buildroadstop_hotkeys[] = { + Hotkey('F', "focus_filter_box", BROSHK_FOCUS_FILTER_BOX), + HOTKEY_LIST_END +}; +HotkeyList BuildRoadStationWindow::hotkeys("buildroadstop", buildroadstop_hotkeys); + +Listing BuildRoadStationWindow::last_sorting = { false, 0 }; +Filtering BuildRoadStationWindow::last_filtering = { false, 0 }; + +BuildRoadStationWindow::GUIRoadStopClassList::SortFunction * const BuildRoadStationWindow::sorter_funcs[] = { + &RoadStopClassIDSorter, +}; + +BuildRoadStationWindow::GUIRoadStopClassList::FilterFunction * const BuildRoadStationWindow::filter_funcs[] = { + &TagNameFilter, }; /** Widget definition of the build road station window */ @@ -1163,38 +1611,82 @@ static const NWidgetPart _nested_road_station_picker_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROS_CAPTION), + NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_DEFSIZE), + NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN), + EndContainer(), EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BROS_BACKGROUND), - NWidget(NWID_SPACER), SetMinimalSize(0, 3), - NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(NWID_SPACER), SetFill(1, 0), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 2), - NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(NWID_SPACER), SetFill(1, 0), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 1), - NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_INFO), SetMinimalSize(140, 14), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), - NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(NWID_HORIZONTAL), SetPadding(2, 0, 0, 2), + NWidget(NWID_VERTICAL), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_FILTER_CONTAINER), + NWidget(NWID_HORIZONTAL), SetPadding(0, 5, 2, 0), + NWidget(WWT_TEXT, COLOUR_DARK_GREEN), SetFill(0, 1), SetDataTip(STR_LIST_FILTER_TITLE, STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_BROS_FILTER_EDITBOX), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + EndContainer(), + EndContainer(), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_ADDITIONS), + NWidget(NWID_HORIZONTAL), SetPadding(0, 5, 2, 0), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_BROS_NEWST_LIST), SetMinimalSize(122, 71), SetFill(1, 0), + SetMatrixDataTip(1, 0, STR_STATION_BUILD_STATION_CLASS_TOOLTIP), SetScrollbar(WID_BROS_NEWST_SCROLL), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_BROS_NEWST_SCROLL), + EndContainer(), + EndContainer(), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_ORIENTATION), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(4, 2, 1, 2), SetFill(1, 0), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPadding(3), + NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(NWID_VERTICAL), SetPIP(0, 2, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_NE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SW), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_SE), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + EndContainer(), + EndContainer(), + NWidget(NWID_SPACER), SetFill(1, 0), + EndContainer(), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_TYPE_SEL), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_SHOW_NEWST_TYPE), SetMinimalSize(144, 8), SetDataTip(STR_ORANGE_STRING, STR_NULL), SetPadding(4, 2, 4, 2), SetFill(1, 0), + EndContainer(), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 0), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12), + SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12), + SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), + NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), + EndContainer(), + EndContainer(), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_MATRIX), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BROS_MATRIX_SCROLL), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BROS_MATRIX), SetScrollbar(WID_BROS_MATRIX_SCROLL), SetPIP(0, 2, 0), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BROS_IMAGE), SetMinimalSize(66, 60), + SetFill(0, 0), SetResize(0, 0), SetDataTip(0x0, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(WID_BROS_MATRIX_SCROLL), + EndContainer(), + EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_BROS_MATRIX_SCROLL), + EndContainer(), + EndContainer(), + EndContainer(), EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12), - SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12), - SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), - NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 1), SetResize(1, 0), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_RESIZE), + NWidget(NWID_VERTICAL), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(0, 1), EndContainer(), + NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN), + EndContainer(), + EndContainer(), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetResize(0, 1), EndContainer(), }; @@ -1210,29 +1702,76 @@ static const NWidgetPart _nested_tram_station_picker_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_BROS_CAPTION), + NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_DEFSIZE), + NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN), + EndContainer(), EndContainer(), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BROS_BACKGROUND), - NWidget(NWID_SPACER), SetMinimalSize(0, 3), - NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), - NWidget(NWID_SPACER), SetFill(1, 0), - EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 1), - NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), - NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_INFO), SetMinimalSize(140, 14), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), - NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(NWID_HORIZONTAL), SetPadding(2, 0, 0, 2), + NWidget(NWID_VERTICAL), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_FILTER_CONTAINER), + NWidget(NWID_HORIZONTAL), SetPadding(0, 5, 2, 0), + NWidget(WWT_TEXT, COLOUR_DARK_GREEN), SetFill(0, 1), SetDataTip(STR_LIST_FILTER_TITLE, STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_BROS_FILTER_EDITBOX), SetFill(1, 0), SetResize(1, 0), + SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + EndContainer(), + EndContainer(), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_ADDITIONS), + NWidget(NWID_HORIZONTAL), SetPadding(0, 5, 2, 0), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_BROS_NEWST_LIST), SetMinimalSize(122, 71), SetFill(1, 0), + SetMatrixDataTip(1, 0, STR_STATION_BUILD_STATION_CLASS_TOOLTIP), SetScrollbar(WID_BROS_NEWST_SCROLL), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_BROS_NEWST_SCROLL), + EndContainer(), + EndContainer(), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_ORIENTATION), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(144, 11), SetDataTip(STR_STATION_BUILD_ORIENTATION, STR_NULL), SetPadding(4, 2, 1, 2), SetFill(1, 0), + EndContainer(), + NWidget(NWID_HORIZONTAL), SetPadding(3), + NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(NWID_VERTICAL), SetPIP(0, 2, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, 2, 0), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_X), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_BROS_STATION_Y), SetMinimalSize(66, 50), SetFill(0, 0), EndContainer(), + EndContainer(), + EndContainer(), + NWidget(NWID_SPACER), SetFill(1, 0), + EndContainer(), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_TYPE_SEL), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN, WID_BROS_SHOW_NEWST_TYPE), SetMinimalSize(144, 8), SetDataTip(STR_ORANGE_STRING, STR_NULL), SetPadding(4, 2, 4, 2), SetFill(1, 0), + EndContainer(), + NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 0), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12), + SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12), + SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), + NWidget(NWID_SPACER), SetMinimalSize(2, 0), SetFill(1, 0), + EndContainer(), + EndContainer(), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_MATRIX), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetScrollbar(WID_BROS_MATRIX_SCROLL), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_MATRIX, COLOUR_DARK_GREEN, WID_BROS_MATRIX), SetScrollbar(WID_BROS_MATRIX_SCROLL), SetPIP(0, 2, 0), SetPadding(2, 0, 0, 0), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BROS_IMAGE), SetMinimalSize(66, 60), + SetFill(0, 0), SetResize(0, 0), SetDataTip(0x0, STR_STATION_BUILD_STATION_TYPE_TOOLTIP), SetScrollbar(WID_BROS_MATRIX_SCROLL), + EndContainer(), + EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_DARK_GREEN, WID_BROS_MATRIX_SCROLL), + EndContainer(), + EndContainer(), + EndContainer(), EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(2, 0, 2), - NWidget(NWID_SPACER), SetFill(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_OFF), SetMinimalSize(60, 12), - SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BROS_LT_ON), SetMinimalSize(60, 12), - SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP), - NWidget(NWID_SPACER), SetFill(1, 0), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BROS_ACCEPTANCE), SetPadding(WidgetDimensions::unscaled.framerect), SetFill(1, 1), SetResize(1, 0), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BROS_SHOW_NEWST_RESIZE), + NWidget(NWID_VERTICAL), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetFill(0, 1), EndContainer(), + NWidget(WWT_RESIZEBOX, COLOUR_DARK_GREEN), + EndContainer(), + EndContainer(), EndContainer(), - NWidget(NWID_SPACER), SetMinimalSize(0, 10), SetResize(0, 1), EndContainer(), }; @@ -1251,7 +1790,7 @@ static void ShowRVStationPicker(Window *parent, RoadStopType rs) void InitializeRoadGui() { _road_depot_orientation = DIAGDIR_NW; - _road_station_picker_orientation = DIAGDIR_NW; + _roadstop_gui_settings.orientation = DIAGDIR_NW; } /** diff --git a/src/road_map.cpp b/src/road_map.cpp index 9954e4299370e..d5642ff48c072 100644 --- a/src/road_map.cpp +++ b/src/road_map.cpp @@ -30,7 +30,7 @@ * @param straight_tunnel_bridge_entrance whether to return straight road bits for tunnels/bridges. * @return the road bits of the given tile */ -RoadBits GetAnyRoadBits(TileIndex tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance) +RoadBits GetAnyRoadBits(Tile tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance) { if (!MayHaveRoad(tile) || !HasTileRoadType(tile, rtt)) return ROAD_NONE; diff --git a/src/road_map.h b/src/road_map.h index 6be02e42f623e..2b95993aa72cb 100644 --- a/src/road_map.h +++ b/src/road_map.h @@ -30,7 +30,7 @@ enum RoadTileType { * @param t Tile to query. * @return true if tile can be queried about road/tram types. */ -static inline bool MayHaveRoad(TileIndex t) +static inline bool MayHaveRoad(Tile t) { switch (GetTileType(t)) { case MP_ROAD: @@ -49,10 +49,10 @@ static inline bool MayHaveRoad(TileIndex t) * @pre IsTileType(t, MP_ROAD) * @return The road tile type. */ -static inline RoadTileType GetRoadTileType(TileIndex t) +debug_inline static RoadTileType GetRoadTileType(Tile t) { assert(IsTileType(t, MP_ROAD)); - return (RoadTileType)GB(_m[t].m5, 6, 2); + return (RoadTileType)GB(t.m5(), 6, 2); } /** @@ -61,7 +61,7 @@ static inline RoadTileType GetRoadTileType(TileIndex t) * @pre IsTileType(t, MP_ROAD) * @return True if normal road. */ -static inline bool IsNormalRoad(TileIndex t) +debug_inline static bool IsNormalRoad(Tile t) { return GetRoadTileType(t) == ROAD_TILE_NORMAL; } @@ -71,7 +71,7 @@ static inline bool IsNormalRoad(TileIndex t) * @param t Tile to query. * @return True if normal road tile. */ -static inline bool IsNormalRoadTile(TileIndex t) +debug_inline static bool IsNormalRoadTile(Tile t) { return IsTileType(t, MP_ROAD) && IsNormalRoad(t); } @@ -82,7 +82,7 @@ static inline bool IsNormalRoadTile(TileIndex t) * @pre IsTileType(t, MP_ROAD) * @return True if level crossing. */ -static inline bool IsLevelCrossing(TileIndex t) +static inline bool IsLevelCrossing(Tile t) { return GetRoadTileType(t) == ROAD_TILE_CROSSING; } @@ -92,7 +92,7 @@ static inline bool IsLevelCrossing(TileIndex t) * @param t Tile to query. * @return True if level crossing tile. */ -static inline bool IsLevelCrossingTile(TileIndex t) +static inline bool IsLevelCrossingTile(Tile t) { return IsTileType(t, MP_ROAD) && IsLevelCrossing(t); } @@ -103,7 +103,7 @@ static inline bool IsLevelCrossingTile(TileIndex t) * @pre IsTileType(t, MP_ROAD) * @return True if road depot. */ -static inline bool IsRoadDepot(TileIndex t) +debug_inline static bool IsRoadDepot(Tile t) { return GetRoadTileType(t) == ROAD_TILE_DEPOT; } @@ -113,7 +113,7 @@ static inline bool IsRoadDepot(TileIndex t) * @param t Tile to query. * @return True if road depot tile. */ -static inline bool IsRoadDepotTile(TileIndex t) +debug_inline static bool IsRoadDepotTile(Tile t) { return IsTileType(t, MP_ROAD) && IsRoadDepot(t); } @@ -125,11 +125,11 @@ static inline bool IsRoadDepotTile(TileIndex t) * @pre IsNormalRoad(t) * @return The present road bits for the road type. */ -static inline RoadBits GetRoadBits(TileIndex t, RoadTramType rtt) +static inline RoadBits GetRoadBits(Tile t, RoadTramType rtt) { assert(IsNormalRoad(t)); - if (rtt == RTT_TRAM) return (RoadBits)GB(_m[t].m3, 0, 4); - return (RoadBits)GB(_m[t].m5, 0, 4); + if (rtt == RTT_TRAM) return (RoadBits)GB(t.m3(), 0, 4); + return (RoadBits)GB(t.m5(), 0, 4); } /** @@ -138,7 +138,7 @@ static inline RoadBits GetRoadBits(TileIndex t, RoadTramType rtt) * @param tile The tile from which we want to get the RoadBits * @return all set RoadBits of the tile */ -static inline RoadBits GetAllRoadBits(TileIndex tile) +static inline RoadBits GetAllRoadBits(Tile tile) { return GetRoadBits(tile, RTT_ROAD) | GetRoadBits(tile, RTT_TRAM); } @@ -150,29 +150,29 @@ static inline RoadBits GetAllRoadBits(TileIndex tile) * @param rt Road type. * @pre IsNormalRoad(t) */ -static inline void SetRoadBits(TileIndex t, RoadBits r, RoadTramType rtt) +static inline void SetRoadBits(Tile t, RoadBits r, RoadTramType rtt) { assert(IsNormalRoad(t)); // XXX incomplete if (rtt == RTT_TRAM) { - SB(_m[t].m3, 0, 4, r); + SB(t.m3(), 0, 4, r); } else { - SB(_m[t].m5, 0, 4, r); + SB(t.m5(), 0, 4, r); } } -static inline RoadType GetRoadTypeRoad(TileIndex t) +static inline RoadType GetRoadTypeRoad(Tile t) { assert(MayHaveRoad(t)); - return (RoadType)GB(_m[t].m4, 0, 6); + return (RoadType)GB(t.m4(), 0, 6); } -static inline RoadType GetRoadTypeTram(TileIndex t) +static inline RoadType GetRoadTypeTram(Tile t) { assert(MayHaveRoad(t)); - return (RoadType)GB(_me[t].m8, 6, 6); + return (RoadType)GB(t.m8(), 6, 6); } -static inline RoadType GetRoadType(TileIndex t, RoadTramType rtt) +static inline RoadType GetRoadType(Tile t, RoadTramType rtt) { return (rtt == RTT_TRAM) ? GetRoadTypeTram(t) : GetRoadTypeRoad(t); } @@ -182,7 +182,7 @@ static inline RoadType GetRoadType(TileIndex t, RoadTramType rtt) * @param t The tile to query. * @return Present road types. */ -static inline RoadTypes GetPresentRoadTypes(TileIndex t) +static inline RoadTypes GetPresentRoadTypes(Tile t) { RoadTypes result = ROADTYPES_NONE; if (MayHaveRoad(t)) { @@ -192,12 +192,12 @@ static inline RoadTypes GetPresentRoadTypes(TileIndex t) return result; } -static inline bool HasRoadTypeRoad(TileIndex t) +static inline bool HasRoadTypeRoad(Tile t) { return GetRoadTypeRoad(t) != INVALID_ROADTYPE; } -static inline bool HasRoadTypeTram(TileIndex t) +static inline bool HasRoadTypeTram(Tile t) { return GetRoadTypeTram(t) != INVALID_ROADTYPE; } @@ -208,7 +208,7 @@ static inline bool HasRoadTypeTram(TileIndex t) * @param tram True to check tram, false to check road. * @return True if the tile has the specified road type. */ -static inline bool HasTileRoadType(TileIndex t, RoadTramType rtt) +static inline bool HasTileRoadType(Tile t, RoadTramType rtt) { return GetRoadType(t, rtt) != INVALID_ROADTYPE; } @@ -219,7 +219,7 @@ static inline bool HasTileRoadType(TileIndex t, RoadTramType rtt) * @param rts Allowed road types. * @return True if the tile has one of the specified road types. */ -static inline bool HasTileAnyRoadType(TileIndex t, RoadTypes rts) +static inline bool HasTileAnyRoadType(Tile t, RoadTypes rts) { if (!MayHaveRoad(t)) return false; return (GetPresentRoadTypes(t) & rts); @@ -231,14 +231,14 @@ static inline bool HasTileAnyRoadType(TileIndex t, RoadTypes rts) * @param rtt RoadTramType. * @return Owner of the given road type. */ -static inline Owner GetRoadOwner(TileIndex t, RoadTramType rtt) +static inline Owner GetRoadOwner(Tile t, RoadTramType rtt) { assert(MayHaveRoad(t)); - if (rtt == RTT_ROAD) return (Owner)GB(IsNormalRoadTile(t) ? _m[t].m1 : _me[t].m7, 0, 5); + if (rtt == RTT_ROAD) return (Owner)GB(IsNormalRoadTile(t) ? t.m1() : t.m7(), 0, 5); /* Trams don't need OWNER_TOWN, and remapping OWNER_NONE * to OWNER_TOWN makes it use one bit less */ - Owner o = (Owner)GB(_m[t].m3, 4, 4); + Owner o = (Owner)GB(t.m3(), 4, 4); return o == OWNER_TOWN ? OWNER_NONE : o; } @@ -248,12 +248,12 @@ static inline Owner GetRoadOwner(TileIndex t, RoadTramType rtt) * @param rtt RoadTramType. * @param o New owner of the given road type. */ -static inline void SetRoadOwner(TileIndex t, RoadTramType rtt, Owner o) +static inline void SetRoadOwner(Tile t, RoadTramType rtt, Owner o) { if (rtt == RTT_ROAD) { - SB(IsNormalRoadTile(t) ? _m[t].m1 : _me[t].m7, 0, 5, o); + SB(IsNormalRoadTile(t) ? t.m1() : t.m7(), 0, 5, o); } else { - SB(_m[t].m3, 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); + SB(t.m3(), 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); } } @@ -265,7 +265,7 @@ static inline void SetRoadOwner(TileIndex t, RoadTramType rtt, Owner o) * @pre HasTileRoadType(t, rt) * @return True if the road type is owned by the given owner. */ -static inline bool IsRoadOwner(TileIndex t, RoadTramType rtt, Owner o) +static inline bool IsRoadOwner(Tile t, RoadTramType rtt, Owner o) { assert(HasTileRoadType(t, rtt)); return (GetRoadOwner(t, rtt) == o); @@ -277,7 +277,7 @@ static inline bool IsRoadOwner(TileIndex t, RoadTramType rtt, Owner o) * @pre IsTileType(t, MP_ROAD) * @return true iff tile has road and the road is owned by a town */ -static inline bool HasTownOwnedRoad(TileIndex t) +static inline bool HasTownOwnedRoad(Tile t) { return HasTileRoadType(t, RTT_ROAD) && IsRoadOwner(t, RTT_ROAD, OWNER_TOWN); } @@ -298,10 +298,10 @@ static inline bool IsValidDisallowedRoadDirections(DisallowedRoadDirections drt) * @param t the tile to get the directions from * @return the disallowed directions */ -static inline DisallowedRoadDirections GetDisallowedRoadDirections(TileIndex t) +static inline DisallowedRoadDirections GetDisallowedRoadDirections(Tile t) { assert(IsNormalRoad(t)); - return (DisallowedRoadDirections)GB(_m[t].m5, 4, 2); + return (DisallowedRoadDirections)GB(t.m5(), 4, 2); } /** @@ -309,11 +309,11 @@ static inline DisallowedRoadDirections GetDisallowedRoadDirections(TileIndex t) * @param t the tile to set the directions for * @param drd the disallowed directions */ -static inline void SetDisallowedRoadDirections(TileIndex t, DisallowedRoadDirections drd) +static inline void SetDisallowedRoadDirections(Tile t, DisallowedRoadDirections drd) { assert(IsNormalRoad(t)); assert(drd < DRD_END); - SB(_m[t].m5, 4, 2, drd); + SB(t.m5(), 4, 2, drd); } /** @@ -322,10 +322,10 @@ static inline void SetDisallowedRoadDirections(TileIndex t, DisallowedRoadDirect * @pre IsLevelCrossing(t) * @return The axis of the road. */ -static inline Axis GetCrossingRoadAxis(TileIndex t) +static inline Axis GetCrossingRoadAxis(Tile t) { assert(IsLevelCrossing(t)); - return (Axis)GB(_m[t].m5, 0, 1); + return (Axis)GB(t.m5(), 0, 1); } /** @@ -334,7 +334,7 @@ static inline Axis GetCrossingRoadAxis(TileIndex t) * @pre IsLevelCrossing(t) * @return The axis of the rail. */ -static inline Axis GetCrossingRailAxis(TileIndex t) +static inline Axis GetCrossingRailAxis(Tile t) { assert(IsLevelCrossing(t)); return OtherAxis((Axis)GetCrossingRoadAxis(t)); @@ -345,7 +345,7 @@ static inline Axis GetCrossingRailAxis(TileIndex t) * @param tile The tile to query. * @return The present road bits. */ -static inline RoadBits GetCrossingRoadBits(TileIndex tile) +static inline RoadBits GetCrossingRoadBits(Tile tile) { return GetCrossingRoadAxis(tile) == AXIS_X ? ROAD_X : ROAD_Y; } @@ -355,7 +355,7 @@ static inline RoadBits GetCrossingRoadBits(TileIndex tile) * @param tile The tile to query. * @return The rail track. */ -static inline Track GetCrossingRailTrack(TileIndex tile) +static inline Track GetCrossingRailTrack(Tile tile) { return AxisToTrack(GetCrossingRailAxis(tile)); } @@ -365,7 +365,7 @@ static inline Track GetCrossingRailTrack(TileIndex tile) * @param tile The tile to query. * @return The rail track bits. */ -static inline TrackBits GetCrossingRailBits(TileIndex tile) +static inline TrackBits GetCrossingRailBits(Tile tile) { return AxisToTrackBits(GetCrossingRailAxis(tile)); } @@ -377,10 +377,10 @@ static inline TrackBits GetCrossingRailBits(TileIndex tile) * @return reservation state * @pre IsLevelCrossingTile(t) */ -static inline bool HasCrossingReservation(TileIndex t) +static inline bool HasCrossingReservation(Tile t) { assert(IsLevelCrossingTile(t)); - return HasBit(_m[t].m5, 4); + return HasBit(t.m5(), 4); } /** @@ -390,10 +390,10 @@ static inline bool HasCrossingReservation(TileIndex t) * @param b the reservation state * @pre IsLevelCrossingTile(t) */ -static inline void SetCrossingReservation(TileIndex t, bool b) +static inline void SetCrossingReservation(Tile t, bool b) { assert(IsLevelCrossingTile(t)); - SB(_m[t].m5, 4, 1, b ? 1 : 0); + SB(t.m5(), 4, 1, b ? 1 : 0); } /** @@ -402,7 +402,7 @@ static inline void SetCrossingReservation(TileIndex t, bool b) * @pre IsLevelCrossingTile(t) * @return reserved track bits */ -static inline TrackBits GetCrossingReservationTrackBits(TileIndex t) +static inline TrackBits GetCrossingReservationTrackBits(Tile t) { return HasCrossingReservation(t) ? GetCrossingRailBits(t) : TRACK_BIT_NONE; } @@ -413,10 +413,10 @@ static inline TrackBits GetCrossingReservationTrackBits(TileIndex t) * @pre IsLevelCrossing(t) * @return True if the level crossing is barred. */ -static inline bool IsCrossingBarred(TileIndex t) +static inline bool IsCrossingBarred(Tile t) { assert(IsLevelCrossing(t)); - return HasBit(_m[t].m5, 5); + return HasBit(t.m5(), 5); } /** @@ -425,17 +425,17 @@ static inline bool IsCrossingBarred(TileIndex t) * @param barred True if the crossing should be barred, false otherwise. * @pre IsLevelCrossing(t) */ -static inline void SetCrossingBarred(TileIndex t, bool barred) +static inline void SetCrossingBarred(Tile t, bool barred) { assert(IsLevelCrossing(t)); - SB(_m[t].m5, 5, 1, barred ? 1 : 0); + SB(t.m5(), 5, 1, barred ? 1 : 0); } /** * Unbar a level crossing. * @param t The tile to change. */ -static inline void UnbarCrossing(TileIndex t) +static inline void UnbarCrossing(Tile t) { SetCrossingBarred(t, false); } @@ -444,7 +444,7 @@ static inline void UnbarCrossing(TileIndex t) * Bar a level crossing. * @param t The tile to change. */ -static inline void BarCrossing(TileIndex t) +static inline void BarCrossing(Tile t) { SetCrossingBarred(t, true); } @@ -456,9 +456,9 @@ static inline void BarCrossing(TileIndex t) * @param t The tile to query. * @return True if the tile has snow/desert. */ -static inline bool IsOnSnow(TileIndex t) +static inline bool IsOnSnow(Tile t) { - return HasBit(_me[t].m7, 5); + return HasBit(t.m7(), 5); } /** Toggle the snow/desert state of a road tile. */ @@ -467,9 +467,9 @@ static inline bool IsOnSnow(TileIndex t) * Toggle the snow/desert state of a road tile. * @param t The tile to change. */ -static inline void ToggleSnow(TileIndex t) +static inline void ToggleSnow(Tile t) { - ToggleBit(_me[t].m7, 5); + ToggleBit(t.m7(), 5); } @@ -490,9 +490,9 @@ enum Roadside { * @param tile The tile to query. * @return The road decoration of the tile. */ -static inline Roadside GetRoadside(TileIndex tile) +static inline Roadside GetRoadside(Tile tile) { - return (Roadside)GB(_me[tile].m6, 3, 3); + return (Roadside)GB(tile.m6(), 3, 3); } /** @@ -500,9 +500,9 @@ static inline Roadside GetRoadside(TileIndex tile) * @param tile The tile to change. * @param s The new road decoration of the tile. */ -static inline void SetRoadside(TileIndex tile, Roadside s) +static inline void SetRoadside(Tile tile, Roadside s) { - SB(_me[tile].m6, 3, 3, s); + SB(tile.m6(), 3, 3, s); } /** @@ -510,7 +510,7 @@ static inline void SetRoadside(TileIndex tile, Roadside s) * @param t The tile to check. * @return True if the tile has road works in progress. */ -static inline bool HasRoadWorks(TileIndex t) +static inline bool HasRoadWorks(Tile t) { return GetRoadside(t) >= ROADSIDE_GRASS_ROAD_WORKS; } @@ -520,11 +520,11 @@ static inline bool HasRoadWorks(TileIndex t) * @param t The tile to modify. * @return True if the road works are in the last stage. */ -static inline bool IncreaseRoadWorksCounter(TileIndex t) +static inline bool IncreaseRoadWorksCounter(Tile t) { - AB(_me[t].m7, 0, 4, 1); + AB(t.m7(), 0, 4, 1); - return GB(_me[t].m7, 0, 4) == 15; + return GB(t.m7(), 0, 4) == 15; } /** @@ -532,7 +532,7 @@ static inline bool IncreaseRoadWorksCounter(TileIndex t) * @param t The tile to start the work on. * @pre !HasRoadWorks(t) */ -static inline void StartRoadWorks(TileIndex t) +static inline void StartRoadWorks(Tile t) { assert(!HasRoadWorks(t)); /* Remove any trees or lamps in case or roadwork */ @@ -548,12 +548,12 @@ static inline void StartRoadWorks(TileIndex t) * @param t Tile to stop the road works on. * @pre HasRoadWorks(t) */ -static inline void TerminateRoadWorks(TileIndex t) +static inline void TerminateRoadWorks(Tile t) { assert(HasRoadWorks(t)); SetRoadside(t, (Roadside)(GetRoadside(t) - ROADSIDE_GRASS_ROAD_WORKS + ROADSIDE_GRASS)); /* Stop the counter */ - SB(_me[t].m7, 0, 4, 0); + SB(t.m7(), 0, 4, 0); } @@ -562,25 +562,25 @@ static inline void TerminateRoadWorks(TileIndex t) * @param t The tile to query. * @return Diagonal direction of the depot exit. */ -static inline DiagDirection GetRoadDepotDirection(TileIndex t) +static inline DiagDirection GetRoadDepotDirection(Tile t) { assert(IsRoadDepot(t)); - return (DiagDirection)GB(_m[t].m5, 0, 2); + return (DiagDirection)GB(t.m5(), 0, 2); } -RoadBits GetAnyRoadBits(TileIndex tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance = false); +RoadBits GetAnyRoadBits(Tile tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance = false); /** * Set the road road type of a tile. * @param t The tile to change. * @param rt The road type to set. */ -static inline void SetRoadTypeRoad(TileIndex t, RoadType rt) +static inline void SetRoadTypeRoad(Tile t, RoadType rt) { assert(MayHaveRoad(t)); assert(rt == INVALID_ROADTYPE || RoadTypeIsRoad(rt)); - SB(_m[t].m4, 0, 6, rt); + SB(t.m4(), 0, 6, rt); } /** @@ -588,11 +588,11 @@ static inline void SetRoadTypeRoad(TileIndex t, RoadType rt) * @param t The tile to change. * @param rt The road type to set. */ -static inline void SetRoadTypeTram(TileIndex t, RoadType rt) +static inline void SetRoadTypeTram(Tile t, RoadType rt) { assert(MayHaveRoad(t)); assert(rt == INVALID_ROADTYPE || RoadTypeIsTram(rt)); - SB(_me[t].m8, 6, 6, rt); + SB(t.m8(), 6, 6, rt); } /** @@ -601,7 +601,7 @@ static inline void SetRoadTypeTram(TileIndex t, RoadType rt) * @param rtt Set road or tram type. * @param rt The road type to set. */ -static inline void SetRoadType(TileIndex t, RoadTramType rtt, RoadType rt) +static inline void SetRoadType(Tile t, RoadTramType rtt, RoadType rt) { if (rtt == RTT_TRAM) { SetRoadTypeTram(t, rt); @@ -616,7 +616,7 @@ static inline void SetRoadType(TileIndex t, RoadTramType rtt, RoadType rt) * @param road_rt The road roadtype to set for the tile. * @param tram_rt The tram roadtype to set for the tile. */ -static inline void SetRoadTypes(TileIndex t, RoadType road_rt, RoadType tram_rt) +static inline void SetRoadTypes(Tile t, RoadType road_rt, RoadType tram_rt) { SetRoadTypeRoad(t, road_rt); SetRoadTypeTram(t, tram_rt); @@ -632,15 +632,15 @@ static inline void SetRoadTypes(TileIndex t, RoadType road_rt, RoadType tram_rt) * @param road New owner of road. * @param tram New owner of tram tracks. */ -static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadType road_rt, RoadType tram_rt, TownID town, Owner road, Owner tram) +static inline void MakeRoadNormal(Tile t, RoadBits bits, RoadType road_rt, RoadType tram_rt, TownID town, Owner road, Owner tram) { SetTileType(t, MP_ROAD); SetTileOwner(t, road); - _m[t].m2 = town; - _m[t].m3 = (tram_rt != INVALID_ROADTYPE ? bits : 0); - _m[t].m5 = (road_rt != INVALID_ROADTYPE ? bits : 0) | ROAD_TILE_NORMAL << 6; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; + t.m2() = town; + t.m3() = (tram_rt != INVALID_ROADTYPE ? bits : 0); + t.m5() = (road_rt != INVALID_ROADTYPE ? bits : 0) | ROAD_TILE_NORMAL << 6; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; SetRoadTypes(t, road_rt, tram_rt); SetRoadOwner(t, RTT_TRAM, tram); } @@ -657,17 +657,17 @@ static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadType road_rt, * @param tram_rt The tram roadtype to set for the tile. * @param town Town ID if the road is a town-owned road. */ -static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner rail, Axis roaddir, RailType rat, RoadType road_rt, RoadType tram_rt, uint town) +static inline void MakeRoadCrossing(Tile t, Owner road, Owner tram, Owner rail, Axis roaddir, RailType rat, RoadType road_rt, RoadType tram_rt, uint town) { SetTileType(t, MP_ROAD); SetTileOwner(t, rail); - _m[t].m2 = town; - _m[t].m3 = 0; - _m[t].m4 = INVALID_ROADTYPE; - _m[t].m5 = ROAD_TILE_CROSSING << 6 | roaddir; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = road; - _me[t].m8 = INVALID_ROADTYPE << 6 | rat; + t.m2() = town; + t.m3() = 0; + t.m4() = INVALID_ROADTYPE; + t.m5() = ROAD_TILE_CROSSING << 6 | roaddir; + SB(t.m6(), 2, 4, 0); + t.m7() = road; + t.m8() = INVALID_ROADTYPE << 6 | rat; SetRoadTypes(t, road_rt, tram_rt); SetRoadOwner(t, RTT_TRAM, tram); } @@ -680,17 +680,17 @@ static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner r * @param dir Direction of the depot exit.* * @param rt Road type of the depot. */ -static inline void MakeRoadDepot(TileIndex t, Owner owner, DepotID did, DiagDirection dir, RoadType rt) +static inline void MakeRoadDepot(Tile t, Owner owner, DepotID did, DiagDirection dir, RoadType rt) { SetTileType(t, MP_ROAD); SetTileOwner(t, owner); - _m[t].m2 = did; - _m[t].m3 = 0; - _m[t].m4 = INVALID_ROADTYPE; - _m[t].m5 = ROAD_TILE_DEPOT << 6 | dir; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = owner; - _me[t].m8 = INVALID_ROADTYPE << 6; + t.m2() = did; + t.m3() = 0; + t.m4() = INVALID_ROADTYPE; + t.m5() = ROAD_TILE_DEPOT << 6 | dir; + SB(t.m6(), 2, 4, 0); + t.m7() = owner; + t.m8() = INVALID_ROADTYPE << 6; SetRoadType(t, GetRoadTramType(rt), rt); SetRoadOwner(t, RTT_TRAM, owner); } diff --git a/src/roadveh.h b/src/roadveh.h index 8f1060a03bf2c..54b9ef54ab415 100644 --- a/src/roadveh.h +++ b/src/roadveh.h @@ -124,29 +124,29 @@ struct RoadVehicle FINAL : public GroundVehicle { friend struct GroundVehicle; // GroundVehicle needs to use the acceleration functions defined at RoadVehicle. - void MarkDirty(); - void UpdateDeltaXY(); - ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_ROADVEH_REVENUE : EXPENSES_ROADVEH_RUN; } - bool IsPrimaryVehicle() const { return this->IsFrontEngine(); } - void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const; - int GetDisplaySpeed() const { return this->gcache.last_speed / 2; } - int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; } - Money GetRunningCost() const; + void MarkDirty() override; + void UpdateDeltaXY() override; + ExpensesType GetExpenseType(bool income) const override { return income ? EXPENSES_ROADVEH_REVENUE : EXPENSES_ROADVEH_RUN; } + bool IsPrimaryVehicle() const override { return this->IsFrontEngine(); } + void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override; + int GetDisplaySpeed() const override { return this->gcache.last_speed / 2; } + int GetDisplayMaxSpeed() const override { return this->vcache.cached_max_speed / 2; } + Money GetRunningCost() const override; int GetDisplayImageWidth(Point *offset = nullptr) const; - bool IsInDepot() const { return this->state == RVSB_IN_DEPOT; } - bool Tick(); - void OnNewVanillaDay(); - void OnNewDay(); - uint Crash(bool flooded = false); - Trackdir GetVehicleTrackdir() const; - TileIndex GetOrderStationLocation(StationID station); - bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse); + bool IsInDepot() const override { return this->state == RVSB_IN_DEPOT; } + bool Tick() override; + void OnNewVanillaDay() override; + void OnNewDay() override; + uint Crash(bool flooded = false) override; + Trackdir GetVehicleTrackdir() const override; + TileIndex GetOrderStationLocation(StationID station) override; + ClosestDepot FindClosestDepot() override; bool IsBus() const; - int GetCurrentMaxSpeed() const; + int GetCurrentMaxSpeed() const override; int UpdateSpeed(); - void SetDestTile(TileIndex tile); + void SetDestTile(TileIndex tile) override; protected: // These functions should not be called outside acceleration code. @@ -179,7 +179,7 @@ struct RoadVehicle FINAL : public GroundVehicle { */ inline uint16 GetWeight() const { - uint16 weight = (CargoSpec::Get(this->cargo_type)->weight * this->cargo.StoredCount()) / 16; + uint16 weight = CargoSpec::Get(this->cargo_type)->WeightOfNUnits(this->cargo.StoredCount()); /* Vehicle weight is not added for articulated parts. */ if (!this->IsArticulatedPart()) { @@ -190,6 +190,12 @@ struct RoadVehicle FINAL : public GroundVehicle { return weight; } + /** + * Calculates the weight value that this vehicle will have when fully loaded with its current cargo. + * @return Weight value in tonnes. + */ + uint16 GetMaxWeight() const override; + /** * Allows to know the tractive effort value that this vehicle will use. * @return Tractive effort value from the engine. diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 873c3830df5ab..3da11641548ec 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -94,10 +94,10 @@ int RoadVehicle::GetDisplayImageWidth(Point *offset) const int reference_width = ROADVEHINFO_DEFAULT_VEHICLE_WIDTH; if (offset != nullptr) { - offset->x = ScaleGUITrad(reference_width) / 2; + offset->x = ScaleSpriteTrad(reference_width) / 2; offset->y = 0; } - return ScaleGUITrad(this->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH); + return ScaleSpriteTrad(this->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH); } static void GetRoadVehIcon(EngineID engine, EngineImageType image_type, VehicleSpriteSeq *result) @@ -175,8 +175,8 @@ void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs Rect rect; seq.GetBounds(&rect); - width = UnScaleGUI(rect.right - rect.left + 1); - height = UnScaleGUI(rect.bottom - rect.top + 1); + width = UnScaleGUI(rect.Width()); + height = UnScaleGUI(rect.Height()); xoffs = UnScaleGUI(rect.left); yoffs = UnScaleGUI(rect.top); } @@ -346,15 +346,12 @@ static FindDepotData FindClosestRoadDepot(const RoadVehicle *v, int max_distance } } -bool RoadVehicle::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) +ClosestDepot RoadVehicle::FindClosestDepot() { FindDepotData rfdd = FindClosestRoadDepot(this, 0); - if (rfdd.best_length == UINT_MAX) return false; + if (rfdd.best_length == UINT_MAX) return ClosestDepot(); - if (location != nullptr) *location = rfdd.tile; - if (destination != nullptr) *destination = GetDepotIndex(rfdd.tile); - - return true; + return ClosestDepot(rfdd.tile, GetDepotIndex(rfdd.tile)); } /** @@ -1004,7 +1001,7 @@ struct RoadDriveEntry { #include "table/roadveh_movement.h" -static bool RoadVehLeaveDepot(RoadVehicle *v, bool first) +bool RoadVehLeaveDepot(RoadVehicle *v, bool first) { /* Don't leave unless v and following wagons are in the depot. */ for (const RoadVehicle *u = v; u != nullptr; u = u->Next()) { @@ -1280,9 +1277,12 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev) Direction new_dir = RoadVehGetSlidingDirection(v, x, y); if (v->IsFrontEngine()) { - Vehicle *u = RoadVehFindCloseTo(v, x, y, new_dir); + const Vehicle *u = RoadVehFindCloseTo(v, x, y, new_dir); if (u != nullptr) { v->cur_speed = u->First()->cur_speed; + /* We might be blocked, prevent pathfinding rerun as we already know where we are heading to. */ + v->path.tile.push_front(tile); + v->path.td.push_front(dir); return false; } } @@ -1392,15 +1392,15 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev) int y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y; Direction new_dir = RoadVehGetSlidingDirection(v, x, y); - if (v->IsFrontEngine() && RoadVehFindCloseTo(v, x, y, new_dir) != nullptr) { - /* We are blocked. */ - v->cur_speed = 0; - if (!v->path.empty()) { - /* Prevent pathfinding rerun as we already know where we are heading to. */ + if (v->IsFrontEngine()) { + const Vehicle *u = RoadVehFindCloseTo(v, x, y, new_dir); + if (u != nullptr) { + v->cur_speed = u->First()->cur_speed; + /* We might be blocked, prevent pathfinding rerun as we already know where we are heading to. */ v->path.tile.push_front(v->tile); v->path.td.push_front(dir); + return false; } - return false; } uint32 r = VehicleEnterTile(v, v->tile, x, y); @@ -1753,3 +1753,16 @@ Trackdir RoadVehicle::GetVehicleTrackdir() const * otherwise transform it into a valid track direction */ return (Trackdir)((IsReversingRoadTrackdir((Trackdir)this->state)) ? (this->state - 6) : this->state); } + +uint16 RoadVehicle::GetMaxWeight() const +{ + uint16 weight = CargoSpec::Get(this->cargo_type)->WeightOfNUnits(this->GetEngine()->DetermineCapacity(this)); + + /* Vehicle weight is not added for articulated parts. */ + if (!this->IsArticulatedPart()) { + /* Road vehicle weight is in units of 1/4 t. */ + weight += GetVehicleProperty(this, PROP_ROADVEH_WEIGHT, RoadVehInfo(this->engine_type)->weight) / 4; + } + + return weight; +} diff --git a/src/roadveh_cmd.h b/src/roadveh_cmd.h index 3d71abce735cd..357c8799ed286 100644 --- a/src/roadveh_cmd.h +++ b/src/roadveh_cmd.h @@ -14,10 +14,14 @@ #include "engine_type.h" #include "vehicle_type.h" +bool RoadVehLeaveDepot(RoadVehicle *v, bool first); +bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev); +bool RoadVehiclesAreBuilt(); + CommandCost CmdBuildRoadVehicle(DoCommandFlag flags, TileIndex tile, const Engine *e, Vehicle **v); CommandCost CmdTurnRoadVeh(DoCommandFlag flags, VehicleID veh_id); -DEF_CMD_TRAIT(CMD_TURN_ROADVEH, CmdTurnRoadVeh, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_TURN_ROADVEH, CmdTurnRoadVeh, CMD_LOCATION, CMDT_VEHICLE_MANAGEMENT) #endif /* ROADVEH_CMD_H */ diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp index f25bd734f9175..37e43b506b92e 100644 --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -8,6 +8,7 @@ /** @file roadveh_gui.cpp GUI for road vehicles. */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "roadveh.h" #include "window_gui.h" #include "strings_func.h" @@ -23,20 +24,19 @@ * Draw the details for the given vehicle at the given position * * @param v current vehicle - * @param left The left most coordinate to draw - * @param right The right most coordinate to draw - * @param y The y coordinate + * @param r the Rect to draw within */ -void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) +void DrawRoadVehDetails(const Vehicle *v, const Rect &r) { - uint y_offset = v->HasArticulatedPart() ? ScaleGUITrad(15) : 0; // Draw the first line below the sprite of an articulated RV instead of after it. + int y = r.top + (v->HasArticulatedPart() ? ScaleSpriteTrad(15) : 0); // Draw the first line below the sprite of an articulated RV instead of after it. StringID str; Money feeder_share = 0; - SetDParam(0, v->engine_type); + SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails)); SetDParam(1, v->build_year); SetDParam(2, v->value); - DrawString(left, right, y + y_offset, STR_VEHICLE_INFO_BUILT_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_BUILT_VALUE); + y += FONT_HEIGHT_NORMAL; if (v->HasArticulatedPart()) { CargoArray max_cargo; @@ -76,7 +76,8 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) } } - DrawString(left, right, y + FONT_HEIGHT_NORMAL + y_offset, capacity, TC_BLUE); + DrawString(r.left, r.right, y, capacity, TC_BLUE); + y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; for (const Vehicle *u = v; u != nullptr; u = u->Next()) { if (u->cargo_cap == 0) continue; @@ -89,17 +90,16 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) str = STR_VEHICLE_DETAILS_CARGO_FROM; feeder_share += u->cargo.FeederShare(); } - DrawString(left, right, y + 2 * FONT_HEIGHT_NORMAL + 1 + y_offset, str); - - y_offset += FONT_HEIGHT_NORMAL + 1; + DrawString(r.left, r.right, y, str); + y += FONT_HEIGHT_NORMAL; } - - y_offset -= FONT_HEIGHT_NORMAL + 1; + y += WidgetDimensions::scaled.vsep_normal; } else { SetDParam(0, v->cargo_type); SetDParam(1, v->cargo_cap); SetDParam(4, GetCargoSubtypeText(v)); - DrawString(left, right, y + FONT_HEIGHT_NORMAL + y_offset, STR_VEHICLE_INFO_CAPACITY); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_CAPACITY); + y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; str = STR_VEHICLE_DETAILS_CARGO_EMPTY; if (v->cargo.StoredCount() > 0) { @@ -109,39 +109,39 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) str = STR_VEHICLE_DETAILS_CARGO_FROM; feeder_share += v->cargo.FeederShare(); } - DrawString(left, right, y + 2 * FONT_HEIGHT_NORMAL + 1 + y_offset, str); + DrawString(r.left, r.right, y, str); + y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; } /* Draw Transfer credits text */ SetDParam(0, feeder_share); - DrawString(left, right, y + 3 * FONT_HEIGHT_NORMAL + 3 + y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); } /** * Draws an image of a road vehicle chain * @param v Front vehicle - * @param left The minimum horizontal position - * @param right The maximum horizontal position - * @param y Vertical position to draw at + * @param r Rect to draw at * @param selection Selected vehicle to draw a frame around * @param skip Number of pixels to skip at the front (for scrolling) */ -void DrawRoadVehImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip) +void DrawRoadVehImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip) { bool rtl = _current_text_dir == TD_RTL; Direction dir = rtl ? DIR_E : DIR_W; const RoadVehicle *u = RoadVehicle::From(v); - DrawPixelInfo tmp_dpi, *old_dpi; - int max_width = right - left + 1; + DrawPixelInfo tmp_dpi; + int max_width = r.Width(); - if (!FillDrawPixelInfo(&tmp_dpi, left, y, max_width, ScaleGUITrad(14))) return; + if (!FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) return; - old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); int px = rtl ? max_width + skip : -skip; - for (; u != nullptr && (rtl ? px > 0 : px < max_width); u = u->Next()) { + int y = r.Height() / 2; + for (; u != nullptr && (rtl ? px > 0 : px < max_width); u = u->Next()) + { Point offset; int width = u->GetDisplayImageWidth(&offset); @@ -149,15 +149,15 @@ void DrawRoadVehImage(const Vehicle *v, int left, int right, int y, VehicleID se PaletteID pal = (u->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(u); VehicleSpriteSeq seq; u->GetImage(dir, image_type, &seq); - seq.Draw(px + (rtl ? -offset.x : offset.x), ScaleGUITrad(6) + offset.y, pal, (u->vehstatus & VS_CRASHED) != 0); + seq.Draw(px + (rtl ? -offset.x : offset.x), y + offset.y, pal, (u->vehstatus & VS_CRASHED) != 0); } px += rtl ? -width : width; } if (v->index == selection) { - DrawFrameRect((rtl ? px : 0), 0, (rtl ? max_width : px) - 1, ScaleGUITrad(13) - 1, COLOUR_WHITE, FR_BORDERONLY); + int height = ScaleSpriteTrad(12); + Rect hr = {(rtl ? px : 0), 0, (rtl ? max_width : px) - 1, height - 1}; + DrawFrameRect(hr.Translate(r.left, CenterBounds(r.top, r.bottom, height)).Expand(WidgetDimensions::scaled.bevel), COLOUR_WHITE, FR_BORDERONLY); } - - _cur_dpi = old_dpi; } diff --git a/src/saveload/CMakeLists.txt b/src/saveload/CMakeLists.txt index 32bcc57ac14b8..3eea5b67419a8 100644 --- a/src/saveload/CMakeLists.txt +++ b/src/saveload/CMakeLists.txt @@ -19,6 +19,7 @@ add_files( group_sl.cpp industry_sl.cpp labelmaps_sl.cpp + league_sl.cpp linkgraph_sl.cpp map_sl.cpp misc_sl.cpp diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 2a1457244eebf..aa4b3230b6e7d 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -24,6 +24,7 @@ #include "../string_func.h" #include "../date_func.h" #include "../roadveh.h" +#include "../roadveh_cmd.h" #include "../train.h" #include "../station_base.h" #include "../waypoint_base.h" @@ -39,7 +40,8 @@ #include "../company_func.h" #include "../road_cmd.h" #include "../ai/ai.hpp" -#include "../ai/ai_gui.hpp" +#include "../script/script_gui.h" +#include "../game/game.hpp" #include "../town.h" #include "../economy_base.h" #include "../animated_tile_func.h" @@ -57,7 +59,6 @@ #include "../ship.h" #include "../water.h" - #include "saveload_internal.h" #include @@ -76,7 +77,7 @@ extern Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMP * @param t the tile to change. * @param include_invalid_water_class Also consider WATER_CLASS_INVALID, i.e. industry tiles on land */ -void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_water_class) +void SetWaterClassDependingOnSurroundings(Tile t, bool include_invalid_water_class) { /* If the slope is not flat, we always assume 'land' (if allowed). Also for one-corner-raised-shores. * Note: Wrt. autosloping under industry tiles this is the most fool-proof behaviour. */ @@ -92,7 +93,7 @@ void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_wate /* Mark tile dirty in all cases */ MarkTileDirtyByTile(t); - if (TileX(t) == 0 || TileY(t) == 0 || TileX(t) == MapMaxX() - 1 || TileY(t) == MapMaxY() - 1) { + if (TileX(t) == 0 || TileY(t) == 0 || TileX(t) == Map::MaxX() - 1 || TileY(t) == Map::MaxY() - 1) { /* tiles at map borders are always WATER_CLASS_SEA */ SetWaterClass(t, WATER_CLASS_SEA); return; @@ -103,7 +104,7 @@ void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_wate bool has_river = false; for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { - TileIndex neighbour = TileAddByDiagDir(t, dir); + Tile neighbour = TileAddByDiagDir(t, dir); switch (GetTileType(neighbour)) { case MP_WATER: /* clear water and shipdepots have already a WaterClass associated */ @@ -126,7 +127,7 @@ void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_wate case MP_TREES: /* trees on shore */ - has_water |= (GB(_m[neighbour].m2, 4, 2) == TREE_GROUND_SHORE); + has_water |= (GB(neighbour.m2(), 4, 2) == TREE_GROUND_SHORE); break; default: break; @@ -149,16 +150,16 @@ void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_wate static void ConvertTownOwner() { - for (TileIndex tile = 0; tile != MapSize(); tile++) { + for (auto tile : Map::Iterate()) { switch (GetTileType(tile)) { case MP_ROAD: - if (GB(_m[tile].m5, 4, 2) == ROAD_TILE_CROSSING && HasBit(_m[tile].m3, 7)) { - _m[tile].m3 = OWNER_TOWN; + if (GB(tile.m5(), 4, 2) == ROAD_TILE_CROSSING && HasBit(tile.m3(), 7)) { + tile.m3() = OWNER_TOWN; } FALLTHROUGH; case MP_TUNNELBRIDGE: - if (_m[tile].m1 & 0x80) SetTileOwner(tile, OWNER_TOWN); + if (tile.m1() & 0x80) SetTileOwner(tile, OWNER_TOWN); break; default: break; @@ -202,8 +203,8 @@ static void UpdateCurrencies() */ static void UpdateVoidTiles() { - for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, MapMaxY())); - for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(MapMaxX(), y)); + for (uint x = 0; x < Map::SizeX(); x++) MakeVoid(TileXY(x, Map::MaxY())); + for (uint y = 0; y < Map::SizeY(); y++) MakeVoid(TileXY(Map::MaxX(), y)); } static inline RailType UpdateRailType(RailType rt, RailType min) @@ -250,6 +251,8 @@ static void InitializeWindowsAndCaches() UpdateAllVirtCoords(); ResetViewportAfterLoadGame(); + ScriptObject::InitializeRandomizers(); + for (Company *c : Company::Iterate()) { /* For each company, verify (while loading a scenario) that the inauguration date is the current year and set it * accordingly if it is not the case. No need to set it on companies that are not been used already, @@ -302,7 +305,6 @@ static void InitializeWindowsAndCaches() CheckTrainsLengths(); ShowNewGRFError(); - ShowAIDebugWindowIfAIError(); /* Rebuild the smallmap list of owners. */ BuildOwnerLegend(); @@ -437,14 +439,14 @@ static void CDECL HandleSavegameLoadCrash(int signum) * a rail track had an invalid owner. When conversion isn't possible, track is removed. * @param t tile to update */ -static void FixOwnerOfRailTrack(TileIndex t) +static void FixOwnerOfRailTrack(Tile t) { assert(!Company::IsValidID(GetTileOwner(t)) && (IsLevelCrossingTile(t) || IsPlainRailTile(t))); /* remove leftover rail piece from crossing (from very old savegames) */ Train *v = nullptr; for (Train *w : Train::Iterate()) { - if (w->tile == t) { + if (w->tile == TileIndex(t)) { v = w; break; } @@ -472,15 +474,15 @@ static void FixOwnerOfRailTrack(TileIndex t) Owner road = GetRoadOwner(t, RTT_ROAD); Owner tram = GetRoadOwner(t, RTT_TRAM); RoadBits bits = GetCrossingRoadBits(t); - bool hasroad = HasBit(_me[t].m7, 6); - bool hastram = HasBit(_me[t].m7, 7); + bool hasroad = HasBit(t.m7(), 6); + bool hastram = HasBit(t.m7(), 7); /* MakeRoadNormal */ SetTileType(t, MP_ROAD); SetTileOwner(t, road); - _m[t].m3 = (hasroad ? bits : 0); - _m[t].m5 = (hastram ? bits : 0) | ROAD_TILE_NORMAL << 6; - SB(_me[t].m6, 2, 4, 0); + t.m3() = (hasroad ? bits : 0); + t.m5() = (hastram ? bits : 0) | ROAD_TILE_NORMAL << 6; + SB(t.m6(), 2, 4, 0); SetRoadOwner(t, RTT_TRAM, tram); return; } @@ -531,12 +533,30 @@ static uint FixVehicleInclination(Vehicle *v, Direction dir) * @param t The tile to analyze * @return True if a bridge might have been present prior to savegame 194. */ -static inline bool MayHaveBridgeAbove(TileIndex t) +static inline bool MayHaveBridgeAbove(Tile t) { return IsTileType(t, MP_CLEAR) || IsTileType(t, MP_RAILWAY) || IsTileType(t, MP_ROAD) || IsTileType(t, MP_WATER) || IsTileType(t, MP_TUNNELBRIDGE) || IsTileType(t, MP_OBJECT); } +/** + * Start the scripts. + */ +static void StartScripts() +{ + /* Script debug window requires AIs to be started before trying to start GameScript. */ + + /* Start the AIs. */ + for (const Company *c : Company::Iterate()) { + if (Company::IsValidAiID(c->index)) AI::StartNew(c->index, false); + } + + /* Start the GameScript. */ + Game::StartNew(); + + ShowScriptDebugWindowIfScriptError(); +} + /** * Perform a (large) amount of savegame conversion *magic* in order to * load older savegames and to fill the caches for various purposes. @@ -546,8 +566,6 @@ bool AfterLoadGame() { SetSignalHandlers(); - TileIndex map_size = MapSize(); - extern TileIndex _cur_tileloop_tile; // From landscape.cpp. /* The LFSR used in RunTileLoop iteration cannot have a zeroed state, make it non-zeroed. */ if (_cur_tileloop_tile == 0) _cur_tileloop_tile = 1; @@ -594,10 +612,10 @@ bool AfterLoadGame() for (Station *st : Station::Iterate()) { st->train_station.w = st->train_station.h = 0; } - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (!IsTileType(t, MP_STATION)) continue; - if (_m[t].m5 > 7) continue; // is it a rail station tile? - Station *st = Station::Get(_m[t].m2); + if (t.m5() > 7) continue; // is it a rail station tile? + Station *st = Station::Get(t.m2()); assert(st->train_station.tile != 0); int dx = TileX(t) - TileX(st->train_station.tile); int dy = TileY(t) - TileY(st->train_station.tile); @@ -611,15 +629,15 @@ bool AfterLoadGame() _settings_game.construction.map_height_limit = 15; /* In old savegame versions, the heightlevel was coded in bits 0..3 of the type field */ - for (TileIndex t = 0; t < map_size; t++) { - _m[t].height = GB(_m[t].type, 0, 4); - SB(_m[t].type, 0, 2, GB(_me[t].m6, 0, 2)); - SB(_me[t].m6, 0, 2, 0); + for (auto t : Map::Iterate()) { + t.height() = GB(t.type(), 0, 4); + SB(t.type(), 0, 2, GB(t.m6(), 0, 2)); + SB(t.m6(), 0, 2, 0); if (MayHaveBridgeAbove(t)) { - SB(_m[t].type, 2, 2, GB(_me[t].m6, 6, 2)); - SB(_me[t].m6, 6, 2, 0); + SB(t.type(), 2, 2, GB(t.m6(), 6, 2)); + SB(t.m6(), 6, 2, 0); } else { - SB(_m[t].type, 2, 2, 0); + SB(t.type(), 2, 2, 0); } } } @@ -638,7 +656,7 @@ bool AfterLoadGame() * (4.3) version, so I just check when versions are older, and then * walk through the whole map.. */ if (IsSavegameVersionBefore(SLV_4, 3)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsTileType(t, MP_WATER) && GetTileOwner(t) >= MAX_COMPANIES) { SetTileOwner(t, OWNER_WATER); } @@ -798,13 +816,6 @@ bool AfterLoadGame() /* Update all vehicles */ AfterLoadVehicles(true); - /* Make sure there is an AI attached to an AI company */ - { - for (const Company *c : Company::Iterate()) { - if (c->is_ai && c->ai_instance == nullptr) AI::StartNew(c->index); - } - } - /* make sure there is a town in the game */ if (_game_mode == GM_NORMAL && Town::GetNumItems() == 0) { SetSaveLoadError(STR_ERROR_NO_TOWN_IN_SCENARIO); @@ -819,18 +830,6 @@ bool AfterLoadGame() * version. It didn't show up before r12070. */ if (IsSavegameVersionBefore(SLV_87)) UpdateVoidTiles(); - /* If Load Scenario / New (Scenario) Game is used, - * a company does not exist yet. So create one here. - * 1 exception: network-games. Those can have 0 companies - * But this exception is not true for non-dedicated network servers! */ - if (!_networking || (_networking && _network_server && !_network_dedicated)) { - CompanyID first_human_company = GetFirstPlayableCompanyID(); - if (!Company::IsValidID(first_human_company)) { - Company *c = DoStartupNewCompany(false, first_human_company); - c->settings = _settings_client.company; - } - } - /* Fix the cache for cargo payments. */ for (CargoPayment *cp : CargoPayment::Iterate()) { cp->front->cargo_payment = cp; @@ -839,7 +838,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_72)) { /* Locks in very old savegames had OWNER_WATER as owner */ - for (TileIndex t = 0; t < MapSize(); t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { default: break; @@ -848,7 +847,7 @@ bool AfterLoadGame() break; case MP_STATION: { - if (HasBit(_me[t].m6, 3)) SetBit(_me[t].m6, 2); + if (HasBit(t.m6(), 3)) SetBit(t.m6(), 2); StationGfx gfx = GetStationGfx(t); StationType st; if ( IsInsideMM(gfx, 0, 8)) { // Rail station @@ -886,14 +885,14 @@ bool AfterLoadGame() ResetSignalHandlers(); return false; } - SB(_me[t].m6, 3, 3, st); + SB(t.m6(), 3, 3, st); break; } } } } - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_STATION: { BaseStation *bst = BaseStation::GetByTile(t); @@ -963,16 +962,16 @@ bool AfterLoadGame() * to use m2 (16bit big), so we need to clean m2, and that is where this is * all about ;) */ if (IsSavegameVersionBefore(SLV_6, 1)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_HOUSE: - _m[t].m4 = _m[t].m2; + t.m4() = t.m2(); SetTownIndex(t, CalcClosestTownFromTile(t)->index); break; case MP_ROAD: - _m[t].m4 |= (_m[t].m2 << 4); - if ((GB(_m[t].m5, 4, 2) == ROAD_TILE_CROSSING ? (Owner)_m[t].m3 : GetTileOwner(t)) == OWNER_TOWN) { + t.m4() |= (t.m2() << 4); + if ((GB(t.m5(), 4, 2) == ROAD_TILE_CROSSING ? (Owner)t.m3() : GetTileOwner(t)) == OWNER_TOWN) { SetTownIndex(t, CalcClosestTownFromTile(t)->index); } else { SetTownIndex(t, 0); @@ -1018,26 +1017,26 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_48)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_RAILWAY: if (IsPlainRail(t)) { /* Swap ground type and signal type for plain rail tiles, so the * ground type uses the same bits as for depots and waypoints. */ - uint tmp = GB(_m[t].m4, 0, 4); - SB(_m[t].m4, 0, 4, GB(_m[t].m2, 0, 4)); - SB(_m[t].m2, 0, 4, tmp); - } else if (HasBit(_m[t].m5, 2)) { + uint tmp = GB(t.m4(), 0, 4); + SB(t.m4(), 0, 4, GB(t.m2(), 0, 4)); + SB(t.m2(), 0, 4, tmp); + } else if (HasBit(t.m5(), 2)) { /* Split waypoint and depot rail type and remove the subtype. */ - ClrBit(_m[t].m5, 2); - ClrBit(_m[t].m5, 6); + ClrBit(t.m5(), 2); + ClrBit(t.m5(), 6); } break; case MP_ROAD: /* Swap m3 and m4, so the track type for rail crossings is the * same as for normal rail. */ - Swap(_m[t].m3, _m[t].m4); + Swap(t.m3(), t.m4()); break; default: break; @@ -1048,34 +1047,34 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_61)) { /* Added the RoadType */ bool old_bridge = IsSavegameVersionBefore(SLV_42); - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_ROAD: - SB(_m[t].m5, 6, 2, GB(_m[t].m5, 4, 2)); + SB(t.m5(), 6, 2, GB(t.m5(), 4, 2)); switch (GetRoadTileType(t)) { default: SlErrorCorrupt("Invalid road tile type"); case ROAD_TILE_NORMAL: - SB(_m[t].m4, 0, 4, GB(_m[t].m5, 0, 4)); - SB(_m[t].m4, 4, 4, 0); - SB(_me[t].m6, 2, 4, 0); + SB(t.m4(), 0, 4, GB(t.m5(), 0, 4)); + SB(t.m4(), 4, 4, 0); + SB(t.m6(), 2, 4, 0); break; case ROAD_TILE_CROSSING: - SB(_m[t].m4, 5, 2, GB(_m[t].m5, 2, 2)); + SB(t.m4(), 5, 2, GB(t.m5(), 2, 2)); break; case ROAD_TILE_DEPOT: break; } - SB(_me[t].m7, 6, 2, 1); // Set pre-NRT road type bits for conversion later. + SB(t.m7(), 6, 2, 1); // Set pre-NRT road type bits for conversion later. break; case MP_STATION: - if (IsRoadStop(t)) SB(_me[t].m7, 6, 2, 1); + if (IsRoadStop(t)) SB(t.m7(), 6, 2, 1); break; case MP_TUNNELBRIDGE: /* Middle part of "old" bridges */ - if (old_bridge && IsBridge(t) && HasBit(_m[t].m5, 6)) break; - if (((old_bridge && IsBridge(t)) ? (TransportType)GB(_m[t].m5, 1, 2) : GetTunnelBridgeTransportType(t)) == TRANSPORT_ROAD) { - SB(_me[t].m7, 6, 2, 1); // Set pre-NRT road type bits for conversion later. + if (old_bridge && IsBridge(t) && HasBit(t.m5(), 6)) break; + if (((old_bridge && IsBridge(t)) ? (TransportType)GB(t.m5(), 1, 2) : GetTunnelBridgeTransportType(t)) == TRANSPORT_ROAD) { + SB(t.m7(), 6, 2, 1); // Set pre-NRT road type bits for conversion later. } break; @@ -1088,27 +1087,27 @@ bool AfterLoadGame() bool fix_roadtypes = !IsSavegameVersionBefore(SLV_61); bool old_bridge = IsSavegameVersionBefore(SLV_42); - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_ROAD: - if (fix_roadtypes) SB(_me[t].m7, 6, 2, (RoadTypes)GB(_me[t].m7, 5, 3)); - SB(_me[t].m7, 5, 1, GB(_m[t].m3, 7, 1)); // snow/desert + if (fix_roadtypes) SB(t.m7(), 6, 2, (RoadTypes)GB(t.m7(), 5, 3)); + SB(t.m7(), 5, 1, GB(t.m3(), 7, 1)); // snow/desert switch (GetRoadTileType(t)) { default: SlErrorCorrupt("Invalid road tile type"); case ROAD_TILE_NORMAL: - SB(_me[t].m7, 0, 4, GB(_m[t].m3, 0, 4)); // road works - SB(_me[t].m6, 3, 3, GB(_m[t].m3, 4, 3)); // ground - SB(_m[t].m3, 0, 4, GB(_m[t].m4, 4, 4)); // tram bits - SB(_m[t].m3, 4, 4, GB(_m[t].m5, 0, 4)); // tram owner - SB(_m[t].m5, 0, 4, GB(_m[t].m4, 0, 4)); // road bits + SB(t.m7(), 0, 4, GB(t.m3(), 0, 4)); // road works + SB(t.m6(), 3, 3, GB(t.m3(), 4, 3)); // ground + SB(t.m3(), 0, 4, GB(t.m4(), 4, 4)); // tram bits + SB(t.m3(), 4, 4, GB(t.m5(), 0, 4)); // tram owner + SB(t.m5(), 0, 4, GB(t.m4(), 0, 4)); // road bits break; case ROAD_TILE_CROSSING: - SB(_me[t].m7, 0, 5, GB(_m[t].m4, 0, 5)); // road owner - SB(_me[t].m6, 3, 3, GB(_m[t].m3, 4, 3)); // ground - SB(_m[t].m3, 4, 4, GB(_m[t].m5, 0, 4)); // tram owner - SB(_m[t].m5, 0, 1, GB(_m[t].m4, 6, 1)); // road axis - SB(_m[t].m5, 5, 1, GB(_m[t].m4, 5, 1)); // crossing state + SB(t.m7(), 0, 5, GB(t.m4(), 0, 5)); // road owner + SB(t.m6(), 3, 3, GB(t.m3(), 4, 3)); // ground + SB(t.m3(), 4, 4, GB(t.m5(), 0, 4)); // tram owner + SB(t.m5(), 0, 1, GB(t.m4(), 6, 1)); // road axis + SB(t.m5(), 5, 1, GB(t.m4(), 5, 1)); // crossing state break; case ROAD_TILE_DEPOT: @@ -1118,32 +1117,32 @@ bool AfterLoadGame() const Town *town = CalcClosestTownFromTile(t); if (town != nullptr) SetTownIndex(t, town->index); } - _m[t].m4 = 0; + t.m4() = 0; break; case MP_STATION: if (!IsRoadStop(t)) break; - if (fix_roadtypes) SB(_me[t].m7, 6, 2, (RoadTypes)GB(_m[t].m3, 0, 3)); - SB(_me[t].m7, 0, 5, HasBit(_me[t].m6, 2) ? OWNER_TOWN : GetTileOwner(t)); - SB(_m[t].m3, 4, 4, _m[t].m1); - _m[t].m4 = 0; + if (fix_roadtypes) SB(t.m7(), 6, 2, (RoadTypes)GB(t.m3(), 0, 3)); + SB(t.m7(), 0, 5, HasBit(t.m6(), 2) ? OWNER_TOWN : GetTileOwner(t)); + SB(t.m3(), 4, 4, t.m1()); + t.m4() = 0; break; case MP_TUNNELBRIDGE: - if (old_bridge && IsBridge(t) && HasBit(_m[t].m5, 6)) break; - if (((old_bridge && IsBridge(t)) ? (TransportType)GB(_m[t].m5, 1, 2) : GetTunnelBridgeTransportType(t)) == TRANSPORT_ROAD) { - if (fix_roadtypes) SB(_me[t].m7, 6, 2, (RoadTypes)GB(_m[t].m3, 0, 3)); + if (old_bridge && IsBridge(t) && HasBit(t.m5(), 6)) break; + if (((old_bridge && IsBridge(t)) ? (TransportType)GB(t.m5(), 1, 2) : GetTunnelBridgeTransportType(t)) == TRANSPORT_ROAD) { + if (fix_roadtypes) SB(t.m7(), 6, 2, (RoadTypes)GB(t.m3(), 0, 3)); Owner o = GetTileOwner(t); - SB(_me[t].m7, 0, 5, o); // road owner - SB(_m[t].m3, 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); // tram owner + SB(t.m7(), 0, 5, o); // road owner + SB(t.m3(), 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); // tram owner } - SB(_me[t].m6, 2, 4, GB(_m[t].m2, 4, 4)); // bridge type - SB(_me[t].m7, 5, 1, GB(_m[t].m4, 7, 1)); // snow/desert + SB(t.m6(), 2, 4, GB(t.m2(), 4, 4)); // bridge type + SB(t.m7(), 5, 1, GB(t.m4(), 7, 1)); // snow/desert - _m[t].m2 = 0; - _m[t].m4 = 0; + t.m2() = 0; + t.m4() = 0; break; default: break; @@ -1153,27 +1152,27 @@ bool AfterLoadGame() /* Railtype moved from m3 to m8 in version SLV_EXTEND_RAILTYPES. */ if (IsSavegameVersionBefore(SLV_EXTEND_RAILTYPES)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_RAILWAY: - SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + SetRailType(t, (RailType)GB(t.m3(), 0, 4)); break; case MP_ROAD: if (IsLevelCrossing(t)) { - SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + SetRailType(t, (RailType)GB(t.m3(), 0, 4)); } break; case MP_STATION: if (HasStationRail(t)) { - SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + SetRailType(t, (RailType)GB(t.m3(), 0, 4)); } break; case MP_TUNNELBRIDGE: if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) { - SetRailType(t, (RailType)GB(_m[t].m3, 0, 4)); + SetRailType(t, (RailType)GB(t.m3(), 0, 4)); } break; @@ -1184,14 +1183,14 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_42)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (MayHaveBridgeAbove(t)) ClearBridgeMiddle(t); if (IsBridgeTile(t)) { - if (HasBit(_m[t].m5, 6)) { // middle part - Axis axis = (Axis)GB(_m[t].m5, 0, 1); + if (HasBit(t.m5(), 6)) { // middle part + Axis axis = (Axis)GB(t.m5(), 0, 1); - if (HasBit(_m[t].m5, 5)) { // transport route under bridge? - if (GB(_m[t].m5, 3, 2) == TRANSPORT_RAIL) { + if (HasBit(t.m5(), 5)) { // transport route under bridge? + if (GB(t.m5(), 3, 2) == TRANSPORT_RAIL) { MakeRailNormal( t, GetTileOwner(t), @@ -1203,15 +1202,15 @@ bool AfterLoadGame() /* MakeRoadNormal */ SetTileType(t, MP_ROAD); - _m[t].m2 = town; - _m[t].m3 = 0; - _m[t].m5 = (axis == AXIS_X ? ROAD_Y : ROAD_X) | ROAD_TILE_NORMAL << 6; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 1 << 6; + t.m2() = town; + t.m3() = 0; + t.m5() = (axis == AXIS_X ? ROAD_Y : ROAD_X) | ROAD_TILE_NORMAL << 6; + SB(t.m6(), 2, 4, 0); + t.m7() = 1 << 6; SetRoadOwner(t, RTT_TRAM, OWNER_NONE); } } else { - if (GB(_m[t].m5, 3, 2) == 0) { + if (GB(t.m5(), 3, 2) == 0) { MakeClear(t, CLEAR_GRASS, 3); } else { if (!IsTileFlat(t)) { @@ -1227,12 +1226,12 @@ bool AfterLoadGame() } SetBridgeMiddle(t, axis); } else { // ramp - Axis axis = (Axis)GB(_m[t].m5, 0, 1); - uint north_south = GB(_m[t].m5, 5, 1); + Axis axis = (Axis)GB(t.m5(), 0, 1); + uint north_south = GB(t.m5(), 5, 1); DiagDirection dir = ReverseDiagDir(XYNSToDiagDir(axis, north_south)); - TransportType type = (TransportType)GB(_m[t].m5, 1, 2); + TransportType type = (TransportType)GB(t.m5(), 1, 2); - _m[t].m5 = 1 << 7 | type << 2 | dir; + t.m5() = 1 << 7 | type << 2 | dir; } } } @@ -1266,7 +1265,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_ROAD_TYPES)) { /* Add road subtypes */ - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { bool has_road = false; switch (GetTileType(t)) { case MP_ROAD: @@ -1283,12 +1282,12 @@ bool AfterLoadGame() } if (has_road) { - RoadType road_rt = HasBit(_me[t].m7, 6) ? ROADTYPE_ROAD : INVALID_ROADTYPE; - RoadType tram_rt = HasBit(_me[t].m7, 7) ? ROADTYPE_TRAM : INVALID_ROADTYPE; + RoadType road_rt = HasBit(t.m7(), 6) ? ROADTYPE_ROAD : INVALID_ROADTYPE; + RoadType tram_rt = HasBit(t.m7(), 7) ? ROADTYPE_TRAM : INVALID_ROADTYPE; assert(road_rt != INVALID_ROADTYPE || tram_rt != INVALID_ROADTYPE); SetRoadTypes(t, road_rt, tram_rt); - SB(_me[t].m7, 6, 2, 0); // Clear pre-NRT road type bits. + SB(t.m7(), 6, 2, 0); // Clear pre-NRT road type bits. } } } @@ -1305,7 +1304,7 @@ bool AfterLoadGame() } /* .. so we convert the entire map from normal to elrail (so maintain "fairness") */ - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_RAILWAY: SetRailType(t, UpdateRailType(GetRailType(t), min_rail)); @@ -1357,7 +1356,7 @@ bool AfterLoadGame() /* From version 15, we moved a semaphore bit from bit 2 to bit 3 in m4, making * room for PBS. Now in version 21 move it back :P. */ if (IsSavegameVersionBefore(SLV_21) && !IsSavegameVersionBefore(SLV_15)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_RAILWAY: if (HasSignals(t)) { @@ -1366,23 +1365,23 @@ bool AfterLoadGame() * (see the code somewhere above) so don't use m4, use m2 instead. */ /* convert PBS signals to combo-signals */ - if (HasBit(_m[t].m2, 2)) SB(_m[t].m2, 0, 2, SIGTYPE_COMBO); + if (HasBit(t.m2(), 2)) SB(t.m2(), 0, 2, SIGTYPE_COMBO); /* move the signal variant back */ - SB(_m[t].m2, 2, 1, HasBit(_m[t].m2, 3) ? SIG_SEMAPHORE : SIG_ELECTRIC); - ClrBit(_m[t].m2, 3); + SB(t.m2(), 2, 1, HasBit(t.m2(), 3) ? SIG_SEMAPHORE : SIG_ELECTRIC); + ClrBit(t.m2(), 3); } /* Clear PBS reservation on track */ if (!IsRailDepotTile(t)) { - SB(_m[t].m4, 4, 4, 0); + SB(t.m4(), 4, 4, 0); } else { - ClrBit(_m[t].m3, 6); + ClrBit(t.m3(), 6); } break; case MP_STATION: // Clear PBS reservation on station - ClrBit(_m[t].m3, 6); + ClrBit(t.m3(), 6); break; default: break; @@ -1437,7 +1436,7 @@ bool AfterLoadGame() * To give this prettiness to old savegames, we remove all farmfields and * plant new ones. */ if (IsSavegameVersionBefore(SLV_32)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_FIELDS)) { /* remove fields */ MakeClear(t, CLEAR_GRASS, 3); @@ -1474,33 +1473,33 @@ bool AfterLoadGame() /* From version 53, the map array was changed for house tiles to allow * space for newhouses grf features. A new byte, m7, was also added. */ if (IsSavegameVersionBefore(SLV_53)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsTileType(t, MP_HOUSE)) { - if (GB(_m[t].m3, 6, 2) != TOWN_HOUSE_COMPLETED) { + if (GB(t.m3(), 6, 2) != TOWN_HOUSE_COMPLETED) { /* Move the construction stage from m3[7..6] to m5[5..4]. * The construction counter does not have to move. */ - SB(_m[t].m5, 3, 2, GB(_m[t].m3, 6, 2)); - SB(_m[t].m3, 6, 2, 0); + SB(t.m5(), 3, 2, GB(t.m3(), 6, 2)); + SB(t.m3(), 6, 2, 0); /* The "house is completed" bit is now in m6[2]. */ SetHouseCompleted(t, false); } else { /* The "lift has destination" bit has been moved from * m5[7] to m7[0]. */ - SB(_me[t].m7, 0, 1, HasBit(_m[t].m5, 7)); - ClrBit(_m[t].m5, 7); + SB(t.m7(), 0, 1, HasBit(t.m5(), 7)); + ClrBit(t.m5(), 7); /* The "lift is moving" bit has been removed, as it does * the same job as the "lift has destination" bit. */ - ClrBit(_m[t].m1, 7); + ClrBit(t.m1(), 7); /* The position of the lift goes from m1[7..0] to m6[7..2], * making m1 totally free, now. The lift position does not * have to be a full byte since the maximum value is 36. */ - SetLiftPosition(t, GB(_m[t].m1, 0, 6 )); + SetLiftPosition(t, GB(t.m1(), 0, 6 )); - _m[t].m1 = 0; - _m[t].m3 = 0; + t.m1() = 0; + t.m3() = 0; SetHouseCompleted(t, true); } } @@ -1511,23 +1510,23 @@ bool AfterLoadGame() UpdateHousesAndTowns(); if (IsSavegameVersionBefore(SLV_43)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsTileType(t, MP_INDUSTRY)) { switch (GetIndustryGfx(t)) { case GFX_POWERPLANT_SPARKS: - _m[t].m3 = GB(_m[t].m1, 2, 5); + t.m3() = GB(t.m1(), 2, 5); break; case GFX_OILWELL_ANIMATED_1: case GFX_OILWELL_ANIMATED_2: case GFX_OILWELL_ANIMATED_3: - _m[t].m3 = GB(_m[t].m1, 0, 2); + t.m3() = GB(t.m1(), 0, 2); break; case GFX_COAL_MINE_TOWER_ANIMATED: case GFX_COPPER_MINE_TOWER_ANIMATED: case GFX_GOLD_MINE_TOWER_ANIMATED: - _m[t].m3 = _m[t].m1; + t.m3() = t.m1(); break; default: // No animation states to change @@ -1571,9 +1570,9 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_49)) for (Company *c : Company::Iterate()) c->face = ConvertFromOldCompanyManagerFace(c->face); if (IsSavegameVersionBefore(SLV_52)) { - for (TileIndex t = 0; t < map_size; t++) { - if (IsTileType(t, MP_OBJECT) && _m[t].m5 == OBJECT_STATUE) { - _m[t].m2 = CalcClosestTownFromTile(t)->index; + for (auto t : Map::Iterate()) { + if (IsTileType(t, MP_OBJECT) && t.m5() == OBJECT_STATUE) { + t.m2() = CalcClosestTownFromTile(t)->index; } } } @@ -1629,13 +1628,13 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_64)) { /* Since now we allow different signal types and variants on a single tile. * Move signal states to m4 to make room and clone the signal type/variant. */ - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsTileType(t, MP_RAILWAY) && HasSignals(t)) { /* move signal states */ - SetSignalStates(t, GB(_m[t].m2, 4, 4)); - SB(_m[t].m2, 4, 4, 0); + SetSignalStates(t, GB(t.m2(), 4, 4)); + SB(t.m2(), 4, 4, 0); /* clone signal type and variant */ - SB(_m[t].m2, 4, 3, GB(_m[t].m2, 0, 3)); + SB(t.m2(), 4, 3, GB(t.m2(), 0, 3)); } } } @@ -1657,7 +1656,7 @@ bool AfterLoadGame() /* From version 82, old style canals (above sealevel (0), WATER owner) are no longer supported. Replace the owner for those by OWNER_NONE. */ if (IsSavegameVersionBefore(SLV_82)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsTileType(t, MP_WATER) && GetWaterTileType(t) == WATER_TILE_CLEAR && GetTileOwner(t) == OWNER_WATER && @@ -1674,9 +1673,9 @@ bool AfterLoadGame() * making floods using the removal of ship depots. */ if (IsSavegameVersionBefore(SLV_83)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsShipDepotTile(t)) { - _m[t].m4 = (TileHeight(t) == 0) ? OWNER_WATER : OWNER_NONE; + t.m4() = (TileHeight(t) == 0) ? OWNER_WATER : OWNER_NONE; } } } @@ -1708,10 +1707,10 @@ bool AfterLoadGame() * land used to have zero density, now they have full density. Therefore, * make all grassy/rough land trees have a density of 3. */ if (IsSavegameVersionBefore(SLV_81)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (GetTileType(t) == MP_TREES) { - TreeGround groundType = (TreeGround)GB(_m[t].m2, 4, 2); - if (groundType != TREE_GROUND_SNOW_DESERT) SB(_m[t].m2, 6, 2, 3); + TreeGround groundType = (TreeGround)GB(t.m2(), 4, 2); + if (groundType != TREE_GROUND_SNOW_DESERT) SB(t.m2(), 6, 2, 3); } } } @@ -1766,15 +1765,15 @@ bool AfterLoadGame() /* The water class was moved/unified. */ if (IsSavegameVersionBefore(SLV_146)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_STATION: switch (GetStationType(t)) { case STATION_OILRIG: case STATION_DOCK: case STATION_BUOY: - SetWaterClass(t, (WaterClass)GB(_m[t].m3, 0, 2)); - SB(_m[t].m3, 0, 2, 0); + SetWaterClass(t, (WaterClass)GB(t.m3(), 0, 2)); + SB(t.m3(), 0, 2, 0); break; default: @@ -1784,8 +1783,8 @@ bool AfterLoadGame() break; case MP_WATER: - SetWaterClass(t, (WaterClass)GB(_m[t].m3, 0, 2)); - SB(_m[t].m3, 0, 2, 0); + SetWaterClass(t, (WaterClass)GB(t.m3(), 0, 2)); + SB(t.m3(), 0, 2, 0); break; case MP_OBJECT: @@ -1800,7 +1799,7 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_86)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { /* Move river flag and update canals to use water class */ if (IsTileType(t, MP_WATER)) { if (GetWaterClass(t) != WATER_CLASS_RIVER) { @@ -1812,7 +1811,7 @@ bool AfterLoadGame() MakeCanal(t, o, Random()); } } else if (IsShipDepot(t)) { - Owner o = (Owner)_m[t].m4; // Original water owner + Owner o = (Owner)t.m4(); // Original water owner SetWaterClass(t, o == OWNER_WATER ? WATER_CLASS_SEA : WATER_CLASS_CANAL); } } @@ -1822,7 +1821,7 @@ bool AfterLoadGame() /* Update locks, depots, docks and buoys to have a water class based * on its neighbouring tiles. Done after river and canal updates to * ensure neighbours are correct. */ - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (!IsTileFlat(t)) continue; if (IsTileType(t, MP_WATER) && IsLock(t)) SetWaterClassDependingOnSurroundings(t, false); @@ -1831,10 +1830,10 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_87)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { /* skip oil rigs at borders! */ if ((IsTileType(t, MP_WATER) || IsBuoyTile(t)) && - (TileX(t) == 0 || TileY(t) == 0 || TileX(t) == MapMaxX() - 1 || TileY(t) == MapMaxY() - 1)) { + (TileX(t) == 0 || TileY(t) == 0 || TileX(t) == Map::MaxX() - 1 || TileY(t) == Map::MaxY() - 1)) { /* Some version 86 savegames have wrong water class at map borders (under buoy, or after removing buoy). * This conversion has to be done before buoys with invalid owner are removed. */ SetWaterClass(t, WATER_CLASS_SEA); @@ -1898,10 +1897,10 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_91)) { /* Increase HouseAnimationFrame from 5 to 7 bits */ - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsTileType(t, MP_HOUSE) && GetHouseType(t) >= NEW_HOUSE_OFFSET) { - SB(_me[t].m6, 2, 6, GB(_me[t].m6, 3, 5)); - SB(_m[t].m3, 5, 1, 0); + SB(t.m6(), 2, 6, GB(t.m6(), 3, 5)); + SB(t.m3(), 5, 1, 0); } } } @@ -1919,7 +1918,7 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_99)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { /* Set newly introduced WaterClass of industry tiles */ if (IsTileType(t, MP_STATION) && IsOilRig(t)) { SetWaterClassDependingOnSurroundings(t, true); @@ -1934,7 +1933,7 @@ bool AfterLoadGame() /* Replace "house construction year" with "house age" */ if (IsTileType(t, MP_HOUSE) && IsHouseCompleted(t)) { - _m[t].m5 = Clamp(_cur_year - (_m[t].m5 + ORIGINAL_BASE_YEAR), 0, 0xFF); + t.m5() = Clamp(_cur_year - (t.m5() + ORIGINAL_BASE_YEAR), 0, 0xFF); } } } @@ -1943,15 +1942,15 @@ bool AfterLoadGame() * format here, as an old layout wouldn't work properly anyway. To be safe, we * clear any possible PBS reservations as well. */ if (IsSavegameVersionBefore(SLV_100)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_RAILWAY: if (HasSignals(t)) { /* move the signal variant */ - SetSignalVariant(t, TRACK_UPPER, HasBit(_m[t].m2, 2) ? SIG_SEMAPHORE : SIG_ELECTRIC); - SetSignalVariant(t, TRACK_LOWER, HasBit(_m[t].m2, 6) ? SIG_SEMAPHORE : SIG_ELECTRIC); - ClrBit(_m[t].m2, 2); - ClrBit(_m[t].m2, 6); + SetSignalVariant(t, TRACK_UPPER, HasBit(t.m2(), 2) ? SIG_SEMAPHORE : SIG_ELECTRIC); + SetSignalVariant(t, TRACK_LOWER, HasBit(t.m2(), 6) ? SIG_SEMAPHORE : SIG_ELECTRIC); + ClrBit(t.m2(), 2); + ClrBit(t.m2(), 6); } /* Clear PBS reservation on track */ @@ -1986,13 +1985,6 @@ bool AfterLoadGame() } } - if (IsSavegameVersionBefore(SLV_102)) { - for (TileIndex t = 0; t < map_size; t++) { - /* Now all crossings should be in correct state */ - if (IsLevelCrossingTile(t)) UpdateLevelCrossing(t, false); - } - } - if (IsSavegameVersionBefore(SLV_103)) { /* Non-town-owned roads now store the closest town */ UpdateNearestTownForRoadTiles(false); @@ -2033,50 +2025,50 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_112)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { /* Check for HQ bit being set, instead of using map accessor, * since we've already changed it code-wise */ - if (IsTileType(t, MP_OBJECT) && HasBit(_m[t].m5, 7)) { + if (IsTileType(t, MP_OBJECT) && HasBit(t.m5(), 7)) { /* Move size and part identification of HQ out of the m5 attribute, * on new locations */ - _m[t].m3 = GB(_m[t].m5, 0, 5); - _m[t].m5 = OBJECT_HQ; + t.m3() = GB(t.m5(), 0, 5); + t.m5() = OBJECT_HQ; } } } if (IsSavegameVersionBefore(SLV_144)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (!IsTileType(t, MP_OBJECT)) continue; /* Reordering/generalisation of the object bits. */ - ObjectType type = _m[t].m5; - SB(_me[t].m6, 2, 4, type == OBJECT_HQ ? GB(_m[t].m3, 2, 3) : 0); - _m[t].m3 = type == OBJECT_HQ ? GB(_m[t].m3, 1, 1) | GB(_m[t].m3, 0, 1) << 4 : 0; + ObjectType type = t.m5(); + SB(t.m6(), 2, 4, type == OBJECT_HQ ? GB(t.m3(), 2, 3) : 0); + t.m3() = type == OBJECT_HQ ? GB(t.m3(), 1, 1) | GB(t.m3(), 0, 1) << 4 : 0; /* Make sure those bits are clear as well! */ - _m[t].m4 = 0; - _me[t].m7 = 0; + t.m4() = 0; + t.m7() = 0; } } if (IsSavegameVersionBefore(SLV_147) && Object::GetNumItems() == 0) { /* Make real objects for object tiles. */ - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (!IsTileType(t, MP_OBJECT)) continue; if (Town::GetNumItems() == 0) { /* No towns, so remove all objects! */ DoClearSquare(t); } else { - uint offset = _m[t].m3; + uint offset = t.m3(); /* Also move the animation state. */ - _m[t].m3 = GB(_me[t].m6, 2, 4); - SB(_me[t].m6, 2, 4, 0); + t.m3() = GB(t.m6(), 2, 4); + SB(t.m6(), 2, 4, 0); if (offset == 0) { /* No offset, so make the object. */ - ObjectType type = _m[t].m5; + ObjectType type = t.m5(); int size = type == OBJECT_HQ ? 2 : 1; if (!Object::CanAllocateItem()) { @@ -2086,18 +2078,18 @@ bool AfterLoadGame() } Object *o = new Object(); - o->location.tile = t; + o->location.tile = (TileIndex)t; o->location.w = size; o->location.h = size; o->build_date = _date; - o->town = type == OBJECT_STATUE ? Town::Get(_m[t].m2) : CalcClosestTownFromTile(t, UINT_MAX); - _m[t].m2 = o->index; + o->town = type == OBJECT_STATUE ? Town::Get(t.m2()) : CalcClosestTownFromTile(t, UINT_MAX); + t.m2() = o->index; Object::IncTypeCount(type); } else { /* We're at an offset, so get the ID from our "root". */ - TileIndex northern_tile = t - TileXY(GB(offset, 0, 4), GB(offset, 4, 4)); + Tile northern_tile = t - TileXY(GB(offset, 0, 4), GB(offset, 4, 4)); assert(IsTileType(northern_tile, MP_OBJECT)); - _m[t].m2 = _m[northern_tile].m2; + t.m2() = northern_tile.m2(); } } } @@ -2302,16 +2294,17 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_128)) { for (const Depot *d : Depot::Iterate()) { + Tile tile = d->xy; /* At some point, invalid depots were saved into the game (possibly those removed in the past?) * Remove them here, so they don't cause issues further down the line */ - if (!IsDepotTile(d->xy)) { + if (!IsDepotTile(tile)) { Debug(sl, 0, "Removing invalid depot {} at {}, {}", d->index, TileX(d->xy), TileY(d->xy)); delete d; d = nullptr; continue; } - _m[d->xy].m2 = d->index; - if (IsTileType(d->xy, MP_WATER)) _m[GetOtherShipDepotTile(d->xy)].m2 = d->index; + tile.m2() = d->index; + if (IsTileType(tile, MP_WATER)) Tile(GetOtherShipDepotTile(tile)).m2() = d->index; } } @@ -2328,20 +2321,19 @@ bool AfterLoadGame() /* The bits for the tree ground and tree density have * been swapped (m2 bits 7..6 and 5..4. */ if (IsSavegameVersionBefore(SLV_135)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsTileType(t, MP_CLEAR)) { if (GetRawClearGround(t) == CLEAR_SNOW) { SetClearGroundDensity(t, CLEAR_GRASS, GetClearDensity(t)); - SetBit(_m[t].m3, 4); + SetBit(t.m3(), 4); } else { - ClrBit(_m[t].m3, 4); + ClrBit(t.m3(), 4); } } if (IsTileType(t, MP_TREES)) { - uint density = GB(_m[t].m2, 6, 2); - uint ground = GB(_m[t].m2, 4, 2); - uint counter = GB(_m[t].m2, 0, 4); - _m[t].m2 = ground << 6 | density << 4 | counter; + uint density = GB(t.m2(), 6, 2); + uint ground = GB(t.m2(), 4, 2); + t.m2() = ground << 6 | density << 4; } } } @@ -2374,7 +2366,7 @@ bool AfterLoadGame() {119, 15}, // 14 unused tiles (radar) {140, 4}, // APT_GRASS_FENCE_NE_FLAG_2 }; - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsAirportTile(t)) { StationGfx old_gfx = GetStationGfx(t); byte offset = 0; @@ -2404,7 +2396,7 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_141)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { /* Reset tropic zone for VOID tiles, they shall not have any. */ if (IsTileType(t, MP_VOID)) SetTropicZone(t, TROPICZONE_NORMAL); } @@ -2445,27 +2437,27 @@ bool AfterLoadGame() /* Move the animation frame to the same location (m7) for all objects. */ if (IsSavegameVersionBefore(SLV_147)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { switch (GetTileType(t)) { case MP_HOUSE: if (GetHouseType(t) >= NEW_HOUSE_OFFSET) { - uint per_proc = _me[t].m7; - _me[t].m7 = GB(_me[t].m6, 2, 6) | (GB(_m[t].m3, 5, 1) << 6); - SB(_m[t].m3, 5, 1, 0); - SB(_me[t].m6, 2, 6, std::min(per_proc, 63U)); + uint per_proc = t.m7(); + t.m7() = GB(t.m6(), 2, 6) | (GB(t.m3(), 5, 1) << 6); + SB(t.m3(), 5, 1, 0); + SB(t.m6(), 2, 6, std::min(per_proc, 63U)); } break; case MP_INDUSTRY: { - uint rand = _me[t].m7; - _me[t].m7 = _m[t].m3; - _m[t].m3 = rand; + uint rand = t.m7(); + t.m7() = t.m3(); + t.m3() = rand; break; } case MP_OBJECT: - _me[t].m7 = _m[t].m3; - _m[t].m3 = 0; + t.m7() = t.m3(); + t.m3() = 0; break; default: @@ -2484,7 +2476,7 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_149)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (!IsTileType(t, MP_STATION)) continue; if (!IsBuoy(t) && !IsOilRig(t) && !(IsDock(t) && IsTileFlat(t))) { SetWaterClass(t, WATER_CLASS_INVALID); @@ -2777,19 +2769,19 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_164) && !IsSavegameVersionBefore(SLV_32)) { /* We store 4 fences in the field tiles instead of only SE and SW. */ - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (!IsTileType(t, MP_CLEAR) && !IsTileType(t, MP_TREES)) continue; if (IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_FIELDS)) continue; - uint fence = GB(_m[t].m4, 5, 3); + uint fence = GB(t.m4(), 5, 3); if (fence != 0 && IsTileType(TILE_ADDXY(t, 1, 0), MP_CLEAR) && IsClearGround(TILE_ADDXY(t, 1, 0), CLEAR_FIELDS)) { SetFence(TILE_ADDXY(t, 1, 0), DIAGDIR_NE, fence); } - fence = GB(_m[t].m4, 2, 3); + fence = GB(t.m4(), 2, 3); if (fence != 0 && IsTileType(TILE_ADDXY(t, 0, 1), MP_CLEAR) && IsClearGround(TILE_ADDXY(t, 0, 1), CLEAR_FIELDS)) { SetFence(TILE_ADDXY(t, 0, 1), DIAGDIR_NW, fence); } - SB(_m[t].m4, 2, 3, 0); - SB(_m[t].m4, 5, 3, 0); + SB(t.m4(), 2, 3, 0); + SB(t.m4(), 5, 3, 0); } } @@ -2826,7 +2818,7 @@ bool AfterLoadGame() /* The road owner of standard road stops was not properly accounted for. */ if (IsSavegameVersionBefore(SLV_172)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (!IsStandardRoadStopTile(t)) continue; Owner o = GetTileOwner(t); SetRoadOwner(t, RTT_ROAD, o); @@ -2867,7 +2859,7 @@ bool AfterLoadGame() /* Blocked tiles could be reserved due to a bug, which causes * other places to assert upon e.g. station reconstruction. */ - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (HasStationTileRail(t) && IsStationTileBlocked(t)) { SetRailStationReservation(t, false); } @@ -2887,11 +2879,11 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_186)) { /* Move ObjectType from map to pool */ - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsTileType(t, MP_OBJECT)) { - Object *o = Object::Get(_m[t].m2); - o->type = _m[t].m5; - _m[t].m5 = 0; // zero upper bits of (now bigger) ObjectID + Object *o = Object::Get(t.m2()); + o->type = t.m5(); + t.m5() = 0; // zero upper bits of (now bigger) ObjectID } } } @@ -2949,7 +2941,6 @@ bool AfterLoadGame() RoadVehicle *u = v; RoadVehicle *prev = nullptr; for (uint sf : skip_frames) { - extern bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev); if (sf >= cur_skip) IndividualRoadVehicleController(u, prev); prev = u; @@ -3087,14 +3078,14 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_TREES_WATER_CLASS)) { /* Update water class for trees. */ - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsTileType(t, MP_TREES)) SetWaterClass(t, GetTreeGround(t) == TREE_GROUND_SHORE ? WATER_CLASS_SEA : WATER_CLASS_INVALID); } } /* Update structures for multitile docks */ if (IsSavegameVersionBefore(SLV_MULTITILE_DOCKS)) { - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { /* Clear docking tile flag from relevant tiles as it * was not previously cleared. */ if (IsTileType(t, MP_WATER) || IsTileType(t, MP_RAILWAY) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE)) { @@ -3116,7 +3107,7 @@ bool AfterLoadGame() if (IsSavegameVersionBeforeOrAt(SLV_ENDING_YEAR)) { /* Reset roadtype/streetcartype info for non-road bridges. */ - for (TileIndex t = 0; t < map_size; t++) { + for (auto t : Map::Iterate()) { if (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) != TRANSPORT_ROAD) { SetRoadTypes(t, INVALID_ROADTYPE, INVALID_ROADTYPE); } @@ -3148,6 +3139,70 @@ bool AfterLoadGame() } } + /* Use current order time to approximate last loading time */ + if (IsSavegameVersionBefore(SLV_LAST_LOADING_TICK)) { + for (Vehicle *v : Vehicle::Iterate()) { + v->last_loading_tick = std::max(_tick_counter, static_cast(v->current_order_time)) - v->current_order_time; + } + } + + /* Road stops is 'only' updating some caches, but they are needed for PF calls in SLV_MULTITRACK_LEVEL_CROSSINGS teleporting. */ + AfterLoadRoadStops(); + + /* Road vehicles stopped on multitrack level crossings need teleporting to a depot + * to avoid crashing into the side of the train they're waiting for. */ + if (IsSavegameVersionBefore(SLV_MULTITRACK_LEVEL_CROSSINGS)) { + /* Teleport road vehicles to the nearest depot. */ + for (RoadVehicle *rv : RoadVehicle::Iterate()) { + /* Ignore trailers of articulated vehicles. */ + if (rv->IsArticulatedPart()) continue; + + /* Ignore moving vehicles. */ + if (rv->cur_speed > 0) continue; + + /* Ignore crashed vehicles. */ + if (rv->vehstatus & VS_CRASHED) continue; + + /* Ignore vehicles not on level crossings. */ + TileIndex cur_tile = rv->tile; + if (!IsLevelCrossingTile(cur_tile)) continue; + + ClosestDepot closestDepot = rv->FindClosestDepot(); + + /* Try to find a depot with a distance limit of 512 tiles (Manhattan distance). */ + if (closestDepot.found && DistanceManhattan(rv->tile, closestDepot.location) < 512u) { + /* Teleport all parts of articulated vehicles. */ + for (RoadVehicle *u = rv; u != nullptr; u = u->Next()) { + u->tile = closestDepot.location; + int x = TileX(closestDepot.location) * TILE_SIZE + TILE_SIZE / 2; + int y = TileY(closestDepot.location) * TILE_SIZE + TILE_SIZE / 2; + u->x_pos = x; + u->y_pos = y; + u->z_pos = GetSlopePixelZ(x, y); + + u->vehstatus |= VS_HIDDEN; + u->state = RVSB_IN_DEPOT; + u->UpdatePosition(); + } + RoadVehLeaveDepot(rv, false); + } + } + + if (IsSavegameVersionBeforeOrAt(SLV_MULTITRACK_LEVEL_CROSSINGS)) { + /* Reset unused tree counters to reduce the savegame size. */ + for (auto t : Map::Iterate()) { + if (IsTileType(t, MP_TREES)) { + SB(t.m2(), 0, 4, 0); + } + } + } + + /* Refresh all level crossings to bar adjacent crossing tiles, if needed. */ + for (auto tile : Map::Iterate()) { + if (IsLevelCrossingTile(tile)) UpdateLevelCrossing(tile, false); + } + } + /* Compute station catchment areas. This is needed here in case UpdateStationAcceptance is called below. */ Station::RecomputeCatchmentForAll(); @@ -3173,8 +3228,6 @@ bool AfterLoadGame() } } - /* Road stops is 'only' updating some caches */ - AfterLoadRoadStops(); AfterLoadLabelMaps(); AfterLoadCompanyStats(); AfterLoadStoryBook(); @@ -3186,6 +3239,23 @@ bool AfterLoadGame() ResetSignalHandlers(); AfterLoadLinkGraphs(); + + /* Start the scripts. This MUST happen after everything else except + * starting a new company. */ + StartScripts(); + + /* If Load Scenario / New (Scenario) Game is used, + * a company does not exist yet. So create one here. + * 1 exception: network-games. Those can have 0 companies + * But this exception is not true for non-dedicated network servers! */ + if (!_networking || (_networking && _network_server && !_network_dedicated)) { + CompanyID first_human_company = GetFirstPlayableCompanyID(); + if (!Company::IsValidID(first_human_company)) { + Company *c = DoStartupNewCompany(false, first_human_company); + c->settings = _settings_client.company; + } + } + return true; } diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp index 51a67b14aa2bb..90e96ba9a2fcc 100644 --- a/src/saveload/ai_sl.cpp +++ b/src/saveload/ai_sl.cpp @@ -77,7 +77,7 @@ struct AIPLChunkHandler : ChunkHandler { _ai_saveload_version = -1; SlObject(nullptr, slt); - if (_networking && !_network_server) { + if (_game_mode == GM_MENU || (_networking && !_network_server)) { if (Company::IsValidAiID(index)) AIInstance::LoadEmpty(); continue; } @@ -112,11 +112,8 @@ struct AIPLChunkHandler : ChunkHandler { config->StringToSettings(_ai_saveload_settings); - /* Start the AI directly if it was active in the savegame */ - if (Company::IsValidAiID(index)) { - AI::StartNew(index, false); - AI::Load(index, _ai_saveload_version); - } + /* Load the AI saved data */ + if (Company::IsValidAiID(index)) config->SetToLoadData(AIInstance::Load(_ai_saveload_version)); } } diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index e63b0b9ea1104..7682ce572a499 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -106,7 +106,7 @@ void AfterLoadCompanyStats() } Company *c; - for (TileIndex tile = 0; tile < MapSize(); tile++) { + for (TileIndex tile = 0; tile < Map::Size(); tile++) { switch (GetTileType(tile)) { case MP_RAILWAY: c = Company::GetIfValid(GetTileOwner(tile)); diff --git a/src/saveload/compat/station_sl_compat.h b/src/saveload/compat/station_sl_compat.h index 1c24a8d5d9220..d94761506eda7 100644 --- a/src/saveload/compat/station_sl_compat.h +++ b/src/saveload/compat/station_sl_compat.h @@ -32,6 +32,12 @@ const SaveLoadCompat _station_spec_list_sl_compat[] = { SLC_VAR("localidx"), }; +/** Nominal field order for SlRoadStopSpecList. */ +const SaveLoadCompat _station_road_stop_spec_list_sl_compat[] = { + SLC_VAR("grfid"), + SLC_VAR("localidx"), +}; + /** Original field order for SlStationCargo. */ const SaveLoadCompat _station_cargo_sl_compat[] = { SLC_VAR("first"), diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index bfd0b910c2b90..9e938bafb37ef 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -69,7 +69,7 @@ struct GSDTChunkHandler : ChunkHandler { _game_saveload_version = -1; SlObject(nullptr, slt); - if (_networking && !_network_server) { + if (_game_mode == GM_MENU || (_networking && !_network_server)) { GameInstance::LoadEmpty(); if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs"); return; @@ -102,9 +102,8 @@ struct GSDTChunkHandler : ChunkHandler { config->StringToSettings(_game_saveload_settings); - /* Start the GameScript directly if it was active in the savegame */ - Game::StartNew(); - Game::Load(_game_saveload_version); + /* Load the GameScript saved data */ + config->SetToLoadData(GameInstance::Load(_game_saveload_version)); if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs"); } diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index a1890f1a86488..c1f627f10c38b 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.cpp @@ -344,8 +344,8 @@ class SlGamelogAction : public DefaultSaveLoadHandler. + */ + +/** @file league_sl.cpp Code handling saving and loading of league tables */ + +#include "../stdafx.h" + +#include "saveload.h" + +#include "../league_base.h" + +#include "../safeguards.h" + +static const SaveLoad _league_table_elements_desc[] = { + SLE_VAR(LeagueTableElement, table, SLE_UINT8), + SLE_CONDVAR(LeagueTableElement, rating, SLE_FILE_U64 | SLE_VAR_I64, SL_MIN_VERSION, SLV_LINKGRAPH_EDGES), + SLE_CONDVAR(LeagueTableElement, rating, SLE_INT64, SLV_LINKGRAPH_EDGES, SL_MAX_VERSION), + SLE_VAR(LeagueTableElement, company, SLE_UINT8), + SLE_SSTR(LeagueTableElement, text, SLE_STR | SLF_ALLOW_CONTROL), + SLE_SSTR(LeagueTableElement, score, SLE_STR | SLF_ALLOW_CONTROL), + SLE_VAR(LeagueTableElement, link.type, SLE_UINT8), + SLE_VAR(LeagueTableElement, link.target, SLE_UINT32), +}; + +struct LEAEChunkHandler : ChunkHandler { + LEAEChunkHandler() : ChunkHandler('LEAE', CH_TABLE) {} + + void Save() const override + { + SlTableHeader(_league_table_elements_desc); + + for (LeagueTableElement *lte : LeagueTableElement::Iterate()) { + SlSetArrayIndex(lte->index); + SlObject(lte, _league_table_elements_desc); + } + } + + void Load() const override + { + const std::vector slt = SlTableHeader(_league_table_elements_desc); + + int index; + while ((index = SlIterateArray()) != -1) { + LeagueTableElement *lte = new (index) LeagueTableElement(); + SlObject(lte, slt); + } + } +}; + +static const SaveLoad _league_tables_desc[] = { + SLE_SSTR(LeagueTable, title, SLE_STR | SLF_ALLOW_CONTROL), + SLE_SSTR(LeagueTable, header, SLE_STR | SLF_ALLOW_CONTROL), + SLE_SSTR(LeagueTable, footer, SLE_STR | SLF_ALLOW_CONTROL), +}; + +struct LEATChunkHandler : ChunkHandler { + LEATChunkHandler() : ChunkHandler('LEAT', CH_TABLE) {} + + void Save() const override + { + SlTableHeader(_league_tables_desc); + + for (LeagueTable *lt : LeagueTable::Iterate()) { + SlSetArrayIndex(lt->index); + SlObject(lt, _league_tables_desc); + } + } + + void Load() const override + { + const std::vector slt = SlTableHeader(_league_tables_desc); + + int index; + while ((index = SlIterateArray()) != -1) { + LeagueTable *lt = new (index) LeagueTable(); + SlObject(lt, slt); + } + } +}; + +static const LEAEChunkHandler LEAE; +static const LEATChunkHandler LEAT; +static const ChunkHandlerRef league_chunk_handlers[] = { + LEAE, + LEAT, +}; + +extern const ChunkHandlerTable _league_chunk_handlers(league_chunk_handlers); diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index 9ff7e130a5269..fc6059f97a9eb 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.cpp @@ -36,47 +36,60 @@ class SlLinkgraphEdge : public DefaultSaveLoadHandler { SLE_CONDVAR(Edge, travel_time_sum, SLE_UINT64, SLV_LINKGRAPH_TRAVEL_TIME, SL_MAX_VERSION), SLE_VAR(Edge, last_unrestricted_update, SLE_INT32), SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION), - SLE_VAR(Edge, next_edge, SLE_UINT16), + SLE_VAR(Edge, dest_node, SLE_UINT16), + SLE_CONDVARNAME(Edge, dest_node, "next_edge", SLE_UINT16, SL_MIN_VERSION, SLV_LINKGRAPH_EDGES), }; inline const static SaveLoadCompatTable compat_description = _linkgraph_edge_sl_compat; void Save(Node *bn) const override { - uint16 size = 0; - for (NodeID to = _linkgraph_from; to != INVALID_NODE; to = _linkgraph->edges[_linkgraph_from][to].next_edge) { - size++; - } - - SlSetStructListLength(size); - for (NodeID to = _linkgraph_from; to != INVALID_NODE; to = _linkgraph->edges[_linkgraph_from][to].next_edge) { - SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetDescription()); + SlSetStructListLength(bn->edges.size()); + for (Edge &e : bn->edges) { + SlObject(&e, this->GetDescription()); } } void Load(Node *bn) const override { - uint16 max_size = _linkgraph->Size(); - - if (IsSavegameVersionBefore(SLV_191)) { - /* We used to save the full matrix ... */ - for (NodeID to = 0; to < max_size; ++to) { - SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetLoadDescription()); + if (IsSavegameVersionBefore(SLV_LINKGRAPH_EDGES)) { + uint16 max_size = _linkgraph->Size(); + std::vector edges(max_size); + + if (IsSavegameVersionBefore(SLV_191)) { + /* We used to save the full matrix ... */ + for (NodeID to = 0; to < max_size; ++to) { + SlObject(&_linkgraph->nodes[_linkgraph_from].edges[to], this->GetLoadDescription()); + } + } else { + size_t used_size = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? max_size : SlGetStructListLength(UINT16_MAX); + + /* ... but as that wasted a lot of space we save a sparse matrix now. */ + for (NodeID to = _linkgraph_from; to != INVALID_NODE; to = edges[to].dest_node) { + if (used_size == 0) SlErrorCorrupt("Link graph structure overflow"); + used_size--; + + if (to >= max_size) SlErrorCorrupt("Link graph structure overflow"); + SlObject(&edges[to], this->GetLoadDescription()); + } + + if (!IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) && used_size > 0) SlErrorCorrupt("Corrupted link graph"); } - return; - } - - size_t used_size = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? max_size : SlGetStructListLength(UINT16_MAX); - /* ... but as that wasted a lot of space we save a sparse matrix now. */ - for (NodeID to = _linkgraph_from; to != INVALID_NODE; to = _linkgraph->edges[_linkgraph_from][to].next_edge) { - if (used_size == 0) SlErrorCorrupt("Link graph structure overflow"); - used_size--; - - if (to >= max_size) SlErrorCorrupt("Link graph structure overflow"); - SlObject(&_linkgraph->edges[_linkgraph_from][to], this->GetLoadDescription()); + /* Build edge list from edge matrix. */ + for (NodeID to = edges[_linkgraph_from].dest_node; to != INVALID_NODE; to = edges[to].dest_node) { + bn->edges.push_back(edges[to]); + bn->edges.back().dest_node = to; + } + /* Sort by destination. */ + std::sort(bn->edges.begin(), bn->edges.end()); + } else { + /* Edge data is now a simple vector and not any kind of matrix. */ + size_t size = SlGetStructListLength(UINT16_MAX); + for (size_t i = 0; i < size; i++) { + bn->edges.emplace_back(); + SlObject(&bn->edges.back(), this->GetLoadDescription()); + } } - - if (!IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) && used_size > 0) SlErrorCorrupt("Corrupted link graph"); } }; @@ -221,7 +234,7 @@ void AfterLoadLinkGraphs() if (IsSavegameVersionBefore(SLV_191)) { for (LinkGraph *lg : LinkGraph::Iterate()) { for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) { - const Station *st = Station::GetIfValid((*lg)[node_id].Station()); + const Station *st = Station::GetIfValid((*lg)[node_id].station); if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy); } } @@ -229,7 +242,7 @@ void AfterLoadLinkGraphs() for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) { LinkGraph *lg = &(const_cast(lgj->Graph())); for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) { - const Station *st = Station::GetIfValid((*lg)[node_id].Station()); + const Station *st = Station::GetIfValid((*lg)[node_id].station); if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy); } } diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index 07a36d6a38a21..2809ad9cfd854 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -34,8 +34,8 @@ struct MAPSChunkHandler : ChunkHandler { { SlTableHeader(_map_desc); - _map_dim_x = MapSizeX(); - _map_dim_y = MapSizeY(); + _map_dim_x = Map::SizeX(); + _map_dim_y = Map::SizeY(); SlSetArrayIndex(0); SlGlobList(_map_desc); @@ -49,7 +49,7 @@ struct MAPSChunkHandler : ChunkHandler { SlGlobList(slt); if (!IsSavegameVersionBefore(SLV_RIFF_TO_ARRAY) && SlIterateArray() != -1) SlErrorCorrupt("Too many MAPS entries"); - AllocateMap(_map_dim_x, _map_dim_y); + Map::Allocate(_map_dim_x, _map_dim_y); } void LoadCheck(size_t) const override @@ -73,22 +73,22 @@ struct MAPTChunkHandler : ChunkHandler { void Load() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).type() = buf[j]; } } void Save() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); SlSetLength(size); for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).type(); SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } @@ -100,22 +100,22 @@ struct MAPHChunkHandler : ChunkHandler { void Load() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].height = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).height() = buf[j]; } } void Save() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); SlSetLength(size); for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].height; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).height(); SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } @@ -127,22 +127,22 @@ struct MAPOChunkHandler : ChunkHandler { void Load() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m1() = buf[j]; } } void Save() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); SlSetLength(size); for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m1(); SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } @@ -154,25 +154,25 @@ struct MAP2ChunkHandler : ChunkHandler { void Load() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, /* In those versions the m2 was 8 bits */ IsSavegameVersionBefore(SLV_5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16 ); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m2() = buf[j]; } } void Save() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); SlSetLength(size * sizeof(uint16)); for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m2(); SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); } } @@ -184,22 +184,22 @@ struct M3LOChunkHandler : ChunkHandler { void Load() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m3() = buf[j]; } } void Save() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); SlSetLength(size); for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m3(); SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } @@ -211,22 +211,22 @@ struct M3HIChunkHandler : ChunkHandler { void Load() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m4() = buf[j]; } } void Save() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); SlSetLength(size); for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m4(); SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } @@ -238,22 +238,22 @@ struct MAP5ChunkHandler : ChunkHandler { void Load() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m5() = buf[j]; } } void Save() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); SlSetLength(size); for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m5(); SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } @@ -265,23 +265,23 @@ struct MAPEChunkHandler : ChunkHandler { void Load() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); if (IsSavegameVersionBefore(SLV_42)) { for (TileIndex i = 0; i != size;) { /* 1024, otherwise we overflow on 64x64 maps! */ SlCopy(buf.data(), 1024, SLE_UINT8); for (uint j = 0; j != 1024; j++) { - _me[i++].m6 = GB(buf[j], 0, 2); - _me[i++].m6 = GB(buf[j], 2, 2); - _me[i++].m6 = GB(buf[j], 4, 2); - _me[i++].m6 = GB(buf[j], 6, 2); + Tile(i++).m6() = GB(buf[j], 0, 2); + Tile(i++).m6() = GB(buf[j], 2, 2); + Tile(i++).m6() = GB(buf[j], 4, 2); + Tile(i++).m6() = GB(buf[j], 6, 2); } } } else { for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m6 = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m6() = buf[j]; } } } @@ -289,11 +289,11 @@ struct MAPEChunkHandler : ChunkHandler { void Save() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); SlSetLength(size); for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m6; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m6(); SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } @@ -305,22 +305,22 @@ struct MAP7ChunkHandler : ChunkHandler { void Load() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m7() = buf[j]; } } void Save() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); SlSetLength(size); for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m7(); SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } @@ -332,22 +332,22 @@ struct MAP8ChunkHandler : ChunkHandler { void Load() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); for (TileIndex i = 0; i != size;) { SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j]; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) Tile(i++).m8() = buf[j]; } } void Save() const override { std::array buf; - TileIndex size = MapSize(); + TileIndex size = Map::Size(); SlSetLength(size * sizeof(uint16)); for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m8; + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = Tile(i++).m8(); SlCopy(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); } } diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index 8a984348c139b..e537bee019c6e 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -34,18 +34,16 @@ ZoomLevel _saved_scrollpos_zoom; void SaveViewportBeforeSaveGame() { - const Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + const Window *w = GetMainWindow(); - if (w != nullptr) { - _saved_scrollpos_x = w->viewport->scrollpos_x; - _saved_scrollpos_y = w->viewport->scrollpos_y; - _saved_scrollpos_zoom = w->viewport->zoom; - } + _saved_scrollpos_x = w->viewport->scrollpos_x; + _saved_scrollpos_y = w->viewport->scrollpos_y; + _saved_scrollpos_zoom = w->viewport->zoom; } void ResetViewportAfterLoadGame() { - Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + Window *w = GetMainWindow(); w->viewport->scrollpos_x = _saved_scrollpos_x; w->viewport->scrollpos_y = _saved_scrollpos_y; @@ -74,8 +72,8 @@ static const SaveLoad _date_desc[] = { SLEG_CONDVAR("date", _date, SLE_FILE_U16 | SLE_VAR_I32, SL_MIN_VERSION, SLV_31), SLEG_CONDVAR("date", _date, SLE_INT32, SLV_31, SL_MAX_VERSION), SLEG_VAR("date_fract", _date_fract, SLE_UINT16), - SLEG_CONDVAR("tick_counter", _tick_counter, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_SLOWPACE), - SLEG_CONDVAR("tick_counter", _tick_counter, SLE_UINT32, SLV_SLOWPACE, SL_MAX_VERSION), + SLEG_CONDVAR("tick_counter", _tick_counter, SLE_FILE_U16 | SLE_VAR_U64, SL_MIN_VERSION, SLV_U64_TICK_COUNTER), + SLEG_CONDVAR("tick_counter", _tick_counter, SLE_UINT64, SLV_U64_TICK_COUNTER, SL_MAX_VERSION), SLEG_CONDVAR("age_cargo_skip_counter", _age_cargo_skip_counter, SLE_UINT8, SL_MIN_VERSION, SLV_162), SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), SLEG_CONDVAR("cur_tileloop_tile", _cur_tileloop_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), diff --git a/src/saveload/newgrf_sl.cpp b/src/saveload/newgrf_sl.cpp index 5dde97132c453..d15057564a67b 100644 --- a/src/saveload/newgrf_sl.cpp +++ b/src/saveload/newgrf_sl.cpp @@ -32,10 +32,10 @@ void NewGRFMappingChunkHandler::Save() const SlTableHeader(_newgrf_mapping_desc); for (uint i = 0; i < this->mapping.GetMaxMapping(); i++) { - if (this->mapping.mapping_ID[i].grfid == 0 && - this->mapping.mapping_ID[i].entity_id == 0) continue; + if (this->mapping.mappings[i].grfid == 0 && + this->mapping.mappings[i].entity_id == 0) continue; SlSetArrayIndex(i); - SlObject(&this->mapping.mapping_ID[i], _newgrf_mapping_desc); + SlObject(&this->mapping.mappings[i], _newgrf_mapping_desc); } } @@ -55,7 +55,7 @@ void NewGRFMappingChunkHandler::Load() const int index; while ((index = SlIterateArray()) != -1) { if ((uint)index >= max_id) SlErrorCorrupt("Too many NewGRF entity mappings"); - SlObject(&this->mapping.mapping_ID[index], slt); + SlObject(&this->mapping.mappings[index], slt); } } diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index bab302dc8da25..fa87681d8ba6d 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -47,55 +47,55 @@ void FixOldMapArray() { /* TTO/TTD/TTDP savegames could have buoys at tile 0 * (without assigned station struct) */ - MemSetT(&_m[0], 0); - SetTileType(0, MP_WATER); - SetTileOwner(0, OWNER_WATER); + MakeSea(0); } static void FixTTDMapArray() { /* _old_map3 is moved to _m::m3 and _m::m4 */ for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) { - _m[t].m3 = _old_map3[t * 2]; - _m[t].m4 = _old_map3[t * 2 + 1]; + Tile tile(t); + tile.m3() = _old_map3[t * 2]; + tile.m4() = _old_map3[t * 2 + 1]; } for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) { - switch (GetTileType(t)) { + Tile tile(t); + switch (GetTileType(tile)) { case MP_STATION: - _m[t].m4 = 0; // We do not understand this TTDP station mapping (yet) - switch (_m[t].m5) { + tile.m4() = 0; // We do not understand this TTDP station mapping (yet) + switch (tile.m5()) { /* We have drive through stops at a totally different place */ - case 0x53: case 0x54: _m[t].m5 += 170 - 0x53; break; // Bus drive through - case 0x57: case 0x58: _m[t].m5 += 168 - 0x57; break; // Truck drive through - case 0x55: case 0x56: _m[t].m5 += 170 - 0x55; break; // Bus tram stop - case 0x59: case 0x5A: _m[t].m5 += 168 - 0x59; break; // Truck tram stop + case 0x53: case 0x54: tile.m5() += 170 - 0x53; break; // Bus drive through + case 0x57: case 0x58: tile.m5() += 168 - 0x57; break; // Truck drive through + case 0x55: case 0x56: tile.m5() += 170 - 0x55; break; // Bus tram stop + case 0x59: case 0x5A: tile.m5() += 168 - 0x59; break; // Truck tram stop default: break; } break; case MP_RAILWAY: /* We save presignals different from TTDPatch, convert them */ - if (GB(_m[t].m5, 6, 2) == 1) { // RAIL_TILE_SIGNALS + if (GB(tile.m5(), 6, 2) == 1) { // RAIL_TILE_SIGNALS /* This byte is always zero in TTD for this type of tile */ - if (_m[t].m4) { // Convert the presignals to our own format - _m[t].m4 = (_m[t].m4 >> 1) & 7; + if (tile.m4()) { // Convert the presignals to our own format + tile.m4() = (tile.m4() >> 1) & 7; } } /* TTDPatch stores PBS things in L6 and all elsewhere; so we'll just * clear it for ourselves and let OTTD's rebuild PBS itself */ - _m[t].m4 &= 0xF; // Only keep the lower four bits; upper four is PBS + tile.m4() &= 0xF; // Only keep the lower four bits; upper four is PBS break; case MP_WATER: /* if water class == 3, make river there */ - if (GB(_m[t].m3, 0, 2) == 3) { - SetTileType(t, MP_WATER); - SetTileOwner(t, OWNER_WATER); - _m[t].m2 = 0; - _m[t].m3 = 2; // WATER_CLASS_RIVER - _m[t].m4 = Random(); - _m[t].m5 = 0; + if (GB(tile.m3(), 0, 2) == 3) { + SetTileType(tile, MP_WATER); + SetTileOwner(tile, OWNER_WATER); + tile.m2() = 0; + tile.m3() = 2; // WATER_CLASS_RIVER + tile.m4() = Random(); + tile.m5() = 0; } break; @@ -194,7 +194,8 @@ void FixOldVehicles() RoadVehicle *rv = RoadVehicle::From(v); if (rv->state != RVSB_IN_DEPOT && rv->state != RVSB_WORMHOLE) { ClrBit(rv->state, 2); - if (IsTileType(rv->tile, MP_STATION) && _m[rv->tile].m5 >= 168) { + Tile tile(rv->tile); + if (IsTileType(tile, MP_STATION) && tile.m5() >= 168) { /* Update the vehicle's road state to show we're in a drive through road stop. */ SetBit(rv->state, RVS_IN_DT_ROAD_STOP); } @@ -220,13 +221,14 @@ void FixOldVehicles() static bool FixTTOMapArray() { for (TileIndex t = 0; t < OLD_MAP_SIZE; t++) { - TileType tt = GetTileType(t); + Tile tile(t); + TileType tt = GetTileType(tile); if (tt == 11) { /* TTO has a different way of storing monorail. * Instead of using bits in m3 it uses a different tile type. */ - _m[t].m3 = 1; // rail type = monorail (in TTD) - SetTileType(t, MP_RAILWAY); - _m[t].m2 = 1; // set monorail ground to RAIL_GROUND_GRASS + tile.m3() = 1; // rail type = monorail (in TTD) + SetTileType(tile, MP_RAILWAY); + tile.m2() = 1; // set monorail ground to RAIL_GROUND_GRASS tt = MP_RAILWAY; } @@ -235,18 +237,18 @@ static bool FixTTOMapArray() break; case MP_RAILWAY: - switch (GB(_m[t].m5, 6, 2)) { + switch (GB(tile.m5(), 6, 2)) { case 0: // RAIL_TILE_NORMAL break; case 1: // RAIL_TILE_SIGNALS - _m[t].m4 = (~_m[t].m5 & 1) << 2; // signal variant (present only in OTTD) - SB(_m[t].m2, 6, 2, GB(_m[t].m5, 3, 2)); // signal status - _m[t].m3 |= 0xC0; // both signals are present - _m[t].m5 = HasBit(_m[t].m5, 5) ? 2 : 1; // track direction (only X or Y) - _m[t].m5 |= 0x40; // RAIL_TILE_SIGNALS + tile.m4() = (~tile.m5() & 1) << 2; // signal variant (present only in OTTD) + SB(tile.m2(), 6, 2, GB(tile.m5(), 3, 2)); // signal status + tile.m3() |= 0xC0; // both signals are present + tile.m5() = HasBit(tile.m5(), 5) ? 2 : 1; // track direction (only X or Y) + tile.m5() |= 0x40; // RAIL_TILE_SIGNALS break; case 3: // RAIL_TILE_DEPOT - _m[t].m2 = 0; + tile.m2() = 0; break; default: return false; @@ -254,12 +256,12 @@ static bool FixTTOMapArray() break; case MP_ROAD: // road (depot) or level crossing - switch (GB(_m[t].m5, 4, 4)) { + switch (GB(tile.m5(), 4, 4)) { case 0: // ROAD_TILE_NORMAL - if (_m[t].m2 == 4) _m[t].m2 = 5; // 'small trees' -> ROADSIDE_TREES + if (tile.m2() == 4) tile.m2() = 5; // 'small trees' -> ROADSIDE_TREES break; case 1: // ROAD_TILE_CROSSING (there aren't monorail crossings in TTO) - _m[t].m3 = _m[t].m1; // set owner of road = owner of rail + tile.m3() = tile.m1(); // set owner of road = owner of rail break; case 2: // ROAD_TILE_DEPOT break; @@ -269,69 +271,69 @@ static bool FixTTOMapArray() break; case MP_HOUSE: - _m[t].m3 = _m[t].m2 & 0xC0; // construction stage - _m[t].m2 &= 0x3F; // building type - if (_m[t].m2 >= 5) _m[t].m2++; // skip "large office block on snow" + tile.m3() = tile.m2() & 0xC0; // construction stage + tile.m2() &= 0x3F; // building type + if (tile.m2() >= 5) tile.m2()++; // skip "large office block on snow" break; case MP_TREES: - _m[t].m3 = GB(_m[t].m5, 3, 3); // type of trees - _m[t].m5 &= 0xC7; // number of trees and growth status + tile.m3() = GB(tile.m5(), 3, 3); // type of trees + tile.m5() &= 0xC7; // number of trees and growth status break; case MP_STATION: - _m[t].m3 = (_m[t].m5 >= 0x08 && _m[t].m5 <= 0x0F) ? 1 : 0; // monorail -> 1, others 0 (rail, road, airport, dock) - if (_m[t].m5 >= 8) _m[t].m5 -= 8; // shift for monorail - if (_m[t].m5 >= 0x42) _m[t].m5++; // skip heliport + tile.m3() = (tile.m5() >= 0x08 && tile.m5() <= 0x0F) ? 1 : 0; // monorail -> 1, others 0 (rail, road, airport, dock) + if (tile.m5() >= 8) tile.m5() -= 8; // shift for monorail + if (tile.m5() >= 0x42) tile.m5()++; // skip heliport break; case MP_WATER: - _m[t].m3 = _m[t].m2 = 0; + tile.m3() = tile.m2() = 0; break; case MP_VOID: - _m[t].m2 = _m[t].m3 = _m[t].m5 = 0; + tile.m2() = tile.m3() = tile.m5() = 0; break; case MP_INDUSTRY: - _m[t].m3 = 0; - switch (_m[t].m5) { + tile.m3() = 0; + switch (tile.m5()) { case 0x24: // farm silo - _m[t].m5 = 0x25; + tile.m5() = 0x25; break; case 0x25: case 0x27: // farm case 0x28: case 0x29: case 0x2A: case 0x2B: // factory - _m[t].m5--; + tile.m5()--; break; default: - if (_m[t].m5 >= 0x2C) _m[t].m5 += 3; // iron ore mine, steel mill or bank + if (tile.m5() >= 0x2C) tile.m5() += 3; // iron ore mine, steel mill or bank break; } break; case MP_TUNNELBRIDGE: - if (HasBit(_m[t].m5, 7)) { // bridge - byte m5 = _m[t].m5; - _m[t].m5 = m5 & 0xE1; // copy bits 7..5, 1 - if (GB(m5, 1, 2) == 1) _m[t].m5 |= 0x02; // road bridge - if (GB(m5, 1, 2) == 3) _m[t].m2 |= 0xA0; // monorail bridge -> tubular, steel bridge + if (HasBit(tile.m5(), 7)) { // bridge + byte m5 = tile.m5(); + tile.m5() = m5 & 0xE1; // copy bits 7..5, 1 + if (GB(m5, 1, 2) == 1) tile.m5() |= 0x02; // road bridge + if (GB(m5, 1, 2) == 3) tile.m2() |= 0xA0; // monorail bridge -> tubular, steel bridge if (!HasBit(m5, 6)) { // bridge head - _m[t].m3 = (GB(m5, 1, 2) == 3) ? 1 : 0; // track subtype (1 for monorail, 0 for others) + tile.m3() = (GB(m5, 1, 2) == 3) ? 1 : 0; // track subtype (1 for monorail, 0 for others) } else { // middle bridge part - _m[t].m3 = HasBit(m5, 2) ? 0x10 : 0; // track subtype on bridge - if (GB(m5, 3, 2) == 3) _m[t].m3 |= 1; // track subtype under bridge - if (GB(m5, 3, 2) == 1) _m[t].m5 |= 0x08; // set for road/water under (0 for rail/clear) + tile.m3() = HasBit(m5, 2) ? 0x10 : 0; // track subtype on bridge + if (GB(m5, 3, 2) == 3) tile.m3() |= 1; // track subtype under bridge + if (GB(m5, 3, 2) == 1) tile.m5() |= 0x08; // set for road/water under (0 for rail/clear) } } else { // tunnel entrance/exit - _m[t].m2 = 0; - _m[t].m3 = HasBit(_m[t].m5, 3); // monorail - _m[t].m5 &= HasBit(_m[t].m5, 3) ? 0x03 : 0x07 ; // direction, transport type (== 0 for rail) + tile.m2() = 0; + tile.m3() = HasBit(tile.m5(), 3); // monorail + tile.m5() &= HasBit(tile.m5(), 3) ? 0x03 : 0x07 ; // direction, transport type (== 0 for rail) } break; case MP_OBJECT: - _m[t].m2 = 0; - _m[t].m3 = 0; + tile.m2() = 0; + tile.m3() = 0; break; default: @@ -386,11 +388,13 @@ static bool FixTTOEngines() } /* Load the default engine set. Many of them will be overridden later */ - uint j = 0; - for (uint i = 0; i < lengthof(_orig_rail_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_TRAIN, i); - for (uint i = 0; i < lengthof(_orig_road_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_ROAD, i); - for (uint i = 0; i < lengthof(_orig_ship_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_SHIP, i); - for (uint i = 0; i < lengthof(_orig_aircraft_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_AIRCRAFT, i); + { + uint j = 0; + for (uint i = 0; i < lengthof(_orig_rail_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_TRAIN, i); + for (uint i = 0; i < lengthof(_orig_road_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_ROAD, i); + for (uint i = 0; i < lengthof(_orig_ship_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_SHIP, i); + for (uint i = 0; i < lengthof(_orig_aircraft_vehicle_info); i++, j++) new (GetTempDataEngine(j)) Engine(VEH_AIRCRAFT, i); + } Date aging_date = std::min(_date + DAYS_TILL_ORIGINAL_BASE_YEAR, ConvertYMDToDate(2050, 0, 1)); @@ -401,7 +405,8 @@ static bool FixTTOEngines() if (oi == 255) { /* Default engine is used */ _date += DAYS_TILL_ORIGINAL_BASE_YEAR; - StartupOneEngine(e, aging_date); + StartupOneEngine(e, aging_date, 0); + CalcEngineReliability(e, false); e->intro_date -= DAYS_TILL_ORIGINAL_BASE_YEAR; _date -= DAYS_TILL_ORIGINAL_BASE_YEAR; @@ -1466,15 +1471,14 @@ static bool LoadOldGameDifficulty(LoadgameState *ls, int num) static bool LoadOldMapPart1(LoadgameState *ls, int num) { if (_savegame_type == SGT_TTO) { - MemSetT(_m, 0, OLD_MAP_SIZE); - MemSetT(_me, 0, OLD_MAP_SIZE); + Map::Allocate(OLD_MAP_SIZE, OLD_MAP_SIZE); } for (uint i = 0; i < OLD_MAP_SIZE; i++) { - _m[i].m1 = ReadByte(ls); + Tile(i).m1() = ReadByte(ls); } for (uint i = 0; i < OLD_MAP_SIZE; i++) { - _m[i].m2 = ReadByte(ls); + Tile(i).m2() = ReadByte(ls); } if (_savegame_type != SGT_TTO) { @@ -1484,10 +1488,10 @@ static bool LoadOldMapPart1(LoadgameState *ls, int num) } for (uint i = 0; i < OLD_MAP_SIZE / 4; i++) { byte b = ReadByte(ls); - _me[i * 4 + 0].m6 = GB(b, 0, 2); - _me[i * 4 + 1].m6 = GB(b, 2, 2); - _me[i * 4 + 2].m6 = GB(b, 4, 2); - _me[i * 4 + 3].m6 = GB(b, 6, 2); + Tile(i * 4 + 0).m6() = GB(b, 0, 2); + Tile(i * 4 + 1).m6() = GB(b, 2, 2); + Tile(i * 4 + 2).m6() = GB(b, 4, 2); + Tile(i * 4 + 3).m6() = GB(b, 6, 2); } } @@ -1499,10 +1503,10 @@ static bool LoadOldMapPart2(LoadgameState *ls, int num) uint i; for (i = 0; i < OLD_MAP_SIZE; i++) { - _m[i].type = ReadByte(ls); + Tile(i).type() = ReadByte(ls); } for (i = 0; i < OLD_MAP_SIZE; i++) { - _m[i].m5 = ReadByte(ls); + Tile(i).m5() = ReadByte(ls); } return true; @@ -1609,7 +1613,7 @@ static const OldChunks main_chunk[] = { OCL_NULL( 2 ), ///< land_code, no longer in use OCL_VAR ( OC_FILE_U16 | OC_VAR_U8, 1, &_age_cargo_skip_counter ), - OCL_VAR ( OC_UINT16, 1, &_tick_counter ), + OCL_VAR ( OC_FILE_U16 | OC_VAR_U64, 1, &_tick_counter ), OCL_VAR ( OC_TILE, 1, &_cur_tileloop_tile ), OCL_ASSERT( OC_TTO, 0x3A2E ), diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index c8a1a0d29c908..604c6292e108b 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -210,7 +210,6 @@ struct SaveLoadParams { StringID error_str; ///< the translatable error message to show char *extra_msg; ///< the error message - uint16 game_speed; ///< The game speed when saving started. bool saveinprogress; ///< Whether there is currently a save in progress. }; @@ -240,6 +239,7 @@ static const std::vector &ChunkHandlers() extern const ChunkHandlerTable _cargomonitor_chunk_handlers; extern const ChunkHandlerTable _goal_chunk_handlers; extern const ChunkHandlerTable _story_page_chunk_handlers; + extern const ChunkHandlerTable _league_chunk_handlers; extern const ChunkHandlerTable _ai_chunk_handlers; extern const ChunkHandlerTable _game_chunk_handlers; extern const ChunkHandlerTable _animated_tile_chunk_handlers; @@ -271,6 +271,7 @@ static const std::vector &ChunkHandlers() _cargomonitor_chunk_handlers, _goal_chunk_handlers, _story_page_chunk_handlers, + _league_chunk_handlers, _engine_chunk_handlers, _town_chunk_handlers, _sign_chunk_handlers, @@ -366,6 +367,8 @@ void NORETURN SlErrorCorrupt(const char *msg) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, msg); } +void NORETURN SlErrorCorruptFmt(const char *format, ...) WARN_FORMAT(1, 2); + /** * Issue an SlErrorCorrupt with a format string. * @param format format string @@ -1922,26 +1925,26 @@ std::vector SlTableHeader(const SaveLoadTable &slt) Debug(sl, _sl.action == SLA_LOAD ? 2 : 6, "Field '{}' of type 0x{:02x} not found, skipping", key, type); std::shared_ptr handler = nullptr; - SaveLoadType slt; + SaveLoadType saveload_type; switch (type & SLE_FILE_TYPE_MASK) { case SLE_FILE_STRING: /* Strings are always marked with SLE_FILE_HAS_LENGTH_FIELD, as they are a list of chars. */ - slt = SL_STR; + saveload_type = SL_STR; break; case SLE_FILE_STRUCT: /* Structs are always marked with SLE_FILE_HAS_LENGTH_FIELD as SL_STRUCT is seen as a list of 0/1 in length. */ - slt = SL_STRUCTLIST; + saveload_type = SL_STRUCTLIST; handler = std::make_shared(); break; default: - slt = (type & SLE_FILE_HAS_LENGTH_FIELD) ? SL_ARR : SL_VAR; + saveload_type = (type & SLE_FILE_HAS_LENGTH_FIELD) ? SL_ARR : SL_VAR; break; } /* We don't know this field, so read to nothing. */ - saveloads.push_back({key, slt, ((VarType)type & SLE_FILE_TYPE_MASK) | SLE_VAR_NULL, 1, SL_MIN_VERSION, SL_MAX_VERSION, 0, nullptr, 0, handler}); + saveloads.push_back({key, saveload_type, ((VarType)type & SLE_FILE_TYPE_MASK) | SLE_VAR_NULL, 1, SL_MIN_VERSION, SL_MAX_VERSION, 0, nullptr, 0, handler}); continue; } @@ -2911,15 +2914,9 @@ static inline void ClearSaveLoadState() _sl.lf = nullptr; } -/** - * Update the gui accordingly when starting saving - * and set locks on saveload. Also turn off fast-forward cause with that - * saving takes Aaaaages - */ +/** Update the gui accordingly when starting saving and set locks on saveload. */ static void SaveFileStart() { - _sl.game_speed = _game_speed; - _game_speed = 100; SetMouseCursorBusy(true); InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_START); @@ -2929,7 +2926,6 @@ static void SaveFileStart() /** Update the gui accordingly when saving is done and release locks on saveload. */ static void SaveFileDone() { - if (_game_mode != GM_MENU) _game_speed = _sl.game_speed; SetMouseCursorBusy(false); InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_FINISH); @@ -3316,7 +3312,7 @@ SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop, ClearSaveLoadState(); /* Skip the "colour" character */ - if (fop != SLO_CHECK) Debug(sl, 0, "{}", GetSaveLoadErrorString()); + if (fop != SLO_CHECK) Debug(sl, 0, "{}", GetSaveLoadErrorString() + 3); /* A saver/loader exception!! reinitialize all variables to prevent crash! */ return (fop == SLO_LOAD) ? SL_REINIT : SL_ERROR; diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 2d726793b69c6..c1c8eed645316 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -340,7 +340,13 @@ enum SaveLoadVersion : uint16 { SLV_LINKGRAPH_TRAVEL_TIME, ///< 297 PR#9457 v12.0-RC1 Store travel time in the linkgraph. SLV_DOCK_DOCKINGTILES, ///< 298 PR#9578 All tiles around docks may be docking tiles. SLV_REPAIR_OBJECT_DOCKING_TILES, ///< 299 PR#9594 v12.0 Fixing issue with docking tiles overlapping objects. - SLV_SLOWPACE, + + SLV_U64_TICK_COUNTER, ///< 300 PR#10035 Make _tick_counter 64bit to avoid wrapping. + SLV_LAST_LOADING_TICK, ///< 301 PR#9693 Store tick of last loading for vehicles. + SLV_MULTITRACK_LEVEL_CROSSINGS, ///< 302 PR#9931 v13.0 Multi-track level crossings. + SLV_NEWGRF_ROAD_STOPS, ///< 303 PR#10144 NewGRF road stops. + SLV_LINKGRAPH_EDGES, ///< 304 PR#10314 Explicitly store link graph edges destination, PR#10471 int64 instead of uint64 league rating + SLV_SLOWPACE, ///< 305 SlowPace merge SL_MAX_VERSION, ///< Highest possible saveload version }; @@ -684,6 +690,7 @@ struct SaveLoadCompat { /** * Storage of simple variables, references (pointers), and arrays. * @param cmd Load/save type. @see SaveLoadType + * @param name Field name for table chunks. * @param base Name of the class or struct containing the variable. * @param variable Name of the variable in the class or struct referenced by \a base. * @param type Storage of the data in memory and in the savegame. @@ -692,7 +699,20 @@ struct SaveLoadCompat { * @param extra Extra data to pass to the address callback function. * @note In general, it is better to use one of the SLE_* macros below. */ -#define SLE_GENERAL(cmd, base, variable, type, length, from, to, extra) SaveLoad {#variable, cmd, type, length, from, to, cpp_sizeof(base, variable), [] (void *b, size_t) -> void * { assert(b != nullptr); return const_cast(static_cast(std::addressof(static_cast(b)->variable))); }, extra, nullptr} +#define SLE_GENERAL_NAME(cmd, name, base, variable, type, length, from, to, extra) SaveLoad {name, cmd, type, length, from, to, cpp_sizeof(base, variable), [] (void *b, size_t) -> void * { assert(b != nullptr); return const_cast(static_cast(std::addressof(static_cast(b)->variable))); }, extra, nullptr} + +/** + * Storage of simple variables, references (pointers), and arrays with a custom name. + * @param cmd Load/save type. @see SaveLoadType + * @param base Name of the class or struct containing the variable. + * @param variable Name of the variable in the class or struct referenced by \a base. + * @param type Storage of the data in memory and in the savegame. + * @param from First savegame version that has the field. + * @param to Last savegame version that has the field. + * @param extra Extra data to pass to the address callback function. + * @note In general, it is better to use one of the SLE_* macros below. + */ +#define SLE_GENERAL(cmd, base, variable, type, length, from, to, extra) SLE_GENERAL_NAME(cmd, #variable, base, variable, type, length, from, to, extra) /** * Storage of a variable in some savegame versions. @@ -704,6 +724,17 @@ struct SaveLoadCompat { */ #define SLE_CONDVAR(base, variable, type, from, to) SLE_GENERAL(SL_VAR, base, variable, type, 0, from, to, 0) +/** + * Storage of a variable in some savegame versions. + * @param base Name of the class or struct containing the variable. + * @param variable Name of the variable in the class or struct referenced by \a base. + * @param name Field name for table chunks. + * @param type Storage of the data in memory and in the savegame. + * @param from First savegame version that has the field. + * @param to Last savegame version that has the field. + */ +#define SLE_CONDVARNAME(base, variable, name, type, from, to) SLE_GENERAL_NAME(SL_VAR, name, base, variable, type, 0, from, to, 0) + /** * Storage of a reference in some savegame versions. * @param base Name of the class or struct containing the variable. @@ -1065,7 +1096,7 @@ static inline bool SlIsObjectCurrentlyValid(SaveLoadVersion version_from, SaveLo */ static inline VarType GetVarMemType(VarType type) { - return type & 0xF0; // GB(type, 4, 4) << 4; + return GB(type, 4, 4) << 4; } /** @@ -1076,7 +1107,7 @@ static inline VarType GetVarMemType(VarType type) */ static inline VarType GetVarFileType(VarType type) { - return type & 0xF; // GB(type, 0, 4); + return GB(type, 0, 4); } /** @@ -1132,7 +1163,6 @@ std::vector SlCompatTableHeader(const SaveLoadTable &slt, const SaveLo void SlObject(void *object, const SaveLoadTable &slt); void NORETURN SlError(StringID string, const char *extra_msg = nullptr); void NORETURN SlErrorCorrupt(const char *msg); -void NORETURN SlErrorCorruptFmt(const char *format, ...) WARN_FORMAT(1, 2); bool SaveloadCrashWithMissingNewGRFs(); diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 20d70066e927e..e72231bb8aa80 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -17,6 +17,7 @@ #include "../roadstop_base.h" #include "../vehicle_base.h" #include "../newgrf_station.h" +#include "../newgrf_roadstop.h" #include "table/strings.h" @@ -90,9 +91,10 @@ void MoveBuoysToWaypoints() if (train) { /* When we make a rail waypoint of the station, convert the map as well. */ for (TileIndex t : train_st) { - if (!IsTileType(t, MP_STATION) || GetStationIndex(t) != index) continue; + Tile tile(t); + if (!IsTileType(tile, MP_STATION) || GetStationIndex(tile) != index) continue; - SB(_me[t].m6, 3, 3, STATION_WAYPOINT); + SB(tile.m6(), 3, 3, STATION_WAYPOINT); wp->rect.BeforeAddTile(t, StationRect::ADD_FORCE); } @@ -109,11 +111,16 @@ void AfterLoadStations() { /* Update the speclists of all stations to point to the currently loaded custom stations. */ for (BaseStation *st : BaseStation::Iterate()) { - for (uint i = 0; i < st->num_specs; i++) { + for (uint i = 0; i < st->speclist.size(); i++) { if (st->speclist[i].grfid == 0) continue; st->speclist[i].spec = StationClass::GetByGrf(st->speclist[i].grfid, st->speclist[i].localidx, nullptr); } + for (uint i = 0; i < st->roadstop_speclist.size(); i++) { + if (st->roadstop_speclist[i].grfid == 0) continue; + + st->roadstop_speclist[i].spec = RoadStopClass::GetByGrf(st->roadstop_speclist[i].grfid, st->roadstop_speclist[i].localidx, nullptr); + } if (Station::IsExpected(st)) { Station *sta = Station::From(st); @@ -122,6 +129,7 @@ void AfterLoadStations() } StationUpdateCachedTriggers(st); + RoadStopUpdateCachedTriggers(st); } } @@ -201,26 +209,52 @@ class SlStationSpecList : public DefaultSaveLoadHandlernum_specs); - for (uint i = 0; i < bst->num_specs; i++) { + SlSetStructListLength(bst->speclist.size()); + for (uint i = 0; i < bst->speclist.size(); i++) { SlObject(&bst->speclist[i], this->GetDescription()); } } void Load(BaseStation *bst) const override { - if (!IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH)) { - bst->num_specs = (uint8)SlGetStructListLength(UINT8_MAX); + uint8 num_specs = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? last_num_specs : (uint8)SlGetStructListLength(UINT8_MAX); + + bst->speclist.resize(num_specs); + for (uint i = 0; i < num_specs; i++) { + SlObject(&bst->speclist[i], this->GetLoadDescription()); } + } +}; - if (bst->num_specs != 0) { - /* Allocate speclist memory when loading a game */ - bst->speclist = CallocT(bst->num_specs); - for (uint i = 0; i < bst->num_specs; i++) { - SlObject(&bst->speclist[i], this->GetLoadDescription()); - } +uint8 SlStationSpecList::last_num_specs; + +class SlRoadStopSpecList : public DefaultSaveLoadHandler { +public: + inline static const SaveLoad description[] = { + SLE_VAR(RoadStopSpecList, grfid, SLE_UINT32), + SLE_VAR(RoadStopSpecList, localidx, SLE_UINT8), + }; + inline const static SaveLoadCompatTable compat_description = _station_road_stop_spec_list_sl_compat; + + void Save(BaseStation *bst) const override + { + SlSetStructListLength(bst->roadstop_speclist.size()); + for (uint i = 0; i < bst->roadstop_speclist.size(); i++) { + SlObject(&bst->roadstop_speclist[i], this->GetDescription()); + } + } + + void Load(BaseStation *bst) const override + { + uint8 num_specs = (uint8)SlGetStructListLength(UINT8_MAX); + + bst->roadstop_speclist.resize(num_specs); + for (uint i = 0; i < num_specs; i++) { + SlObject(&bst->roadstop_speclist[i], this->GetLoadDescription()); } } }; @@ -393,7 +427,7 @@ class SlStationGoods : public DefaultSaveLoadHandlerGetNumCargo(); - for (CargoID i = 0; i < num_cargo; i++) { + for (size_t i = 0; i < num_cargo; i++) { GoodsEntry *ge = &st->goods[i]; SlObject(ge, this->GetLoadDescription()); if (IsSavegameVersionBefore(SLV_183)) { @@ -476,7 +510,7 @@ static const SaveLoad _old_station_desc[] = { /* Used by newstations for graphic variations */ SLE_CONDVAR(Station, random_bits, SLE_UINT16, SLV_27, SL_MAX_VERSION), SLE_CONDVAR(Station, waiting_triggers, SLE_UINT8, SLV_27, SL_MAX_VERSION), - SLE_CONDVAR(Station, num_specs, SLE_UINT8, SLV_27, SL_MAX_VERSION), + SLEG_CONDVAR("num_specs", SlStationSpecList::last_num_specs, SLE_UINT8, SLV_27, SL_MAX_VERSION), SLE_CONDREFLIST(Station, loading_vehicles, REF_VEHICLE, SLV_57, SL_MAX_VERSION), @@ -517,6 +551,35 @@ struct STNSChunkHandler : ChunkHandler { } }; +class SlRoadStopTileData : public DefaultSaveLoadHandler { +public: + inline static const SaveLoad description[] = { + SLE_VAR(RoadStopTileData, tile, SLE_UINT32), + SLE_VAR(RoadStopTileData, random_bits, SLE_UINT8), + SLE_VAR(RoadStopTileData, animation_frame, SLE_UINT8), + }; + inline const static SaveLoadCompatTable compat_description = {}; + + static uint8 last_num_specs; ///< Number of specs of the last loaded station. + + void Save(BaseStation *bst) const override + { + SlSetStructListLength(bst->custom_roadstop_tile_data.size()); + for (uint i = 0; i < bst->custom_roadstop_tile_data.size(); i++) { + SlObject(&bst->custom_roadstop_tile_data[i], this->GetDescription()); + } + } + + void Load(BaseStation *bst) const override + { + uint32 num_tiles = (uint32)SlGetStructListLength(UINT32_MAX); + bst->custom_roadstop_tile_data.resize(num_tiles); + for (uint i = 0; i < num_tiles; i++) { + SlObject(&bst->custom_roadstop_tile_data[i], this->GetLoadDescription()); + } + } +}; + /** * SaveLoad handler for the BaseStation, which all other stations / waypoints * make use of. @@ -536,7 +599,7 @@ class SlStationBase : public DefaultSaveLoadHandler /* Used by newstations for graphic variations */ SLE_VAR(BaseStation, random_bits, SLE_UINT16), SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8), - SLE_CONDVAR(BaseStation, num_specs, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH), + SLEG_CONDVAR("num_specs", SlStationSpecList::last_num_specs, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH), }; inline const static SaveLoadCompatTable compat_description = _station_base_sl_compat; @@ -594,6 +657,7 @@ class SlStationNormal : public DefaultSaveLoadHandlercache.num_houses = 0; } - for (TileIndex t = 0; t < MapSize(); t++) { + for (TileIndex t = 0; t < Map::Size(); t++) { if (!IsTileType(t, MP_HOUSE)) continue; HouseID house_id = GetHouseType(t); @@ -66,7 +66,7 @@ void RebuildTownCaches() */ void UpdateHousesAndTowns() { - for (TileIndex t = 0; t < MapSize(); t++) { + for (TileIndex t = 0; t < Map::Size(); t++) { if (!IsTileType(t, MP_HOUSE)) continue; HouseID house_id = GetCleanHouseType(t); @@ -79,7 +79,7 @@ void UpdateHousesAndTowns() } /* Check for cases when a NewGRF has set a wrong house substitute type. */ - for (TileIndex t = 0; t < MapSize(); t++) { + for (TileIndex t = 0; t < Map::Size(); t++) { if (!IsTileType(t, MP_HOUSE)) continue; HouseID house_type = GetCleanHouseType(t); @@ -148,7 +148,7 @@ class SlTownSupplied : public DefaultSaveLoadHandler { void Load(Town *t) const override { size_t num_cargo = this->GetNumCargo(); - for (CargoID i = 0; i < num_cargo; i++) { + for (size_t i = 0; i < num_cargo; i++) { SlObject(&t->supplied[i], this->GetLoadDescription()); } } diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 75ecf8d05de4c..a20aad345cf1c 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -454,13 +454,17 @@ void AfterLoadVehicles(bool part_of_load) if (Aircraft::From(v)->IsNormalAircraft()) { v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_cache.sprite_seq); - /* The plane's shadow will have the same image as the plane, but no colour */ + /* The aircraft's shadow will have the same image as the aircraft, but no colour */ Vehicle *shadow = v->Next(); + if (shadow == nullptr) SlErrorCorrupt("Missing shadow for aircraft"); + shadow->sprite_cache.sprite_seq.CopyWithoutPalette(v->sprite_cache.sprite_seq); /* In the case of a helicopter we will update the rotor sprites */ if (v->subtype == AIR_HELICOPTER) { Vehicle *rotor = shadow->Next(); + if (rotor == nullptr) SlErrorCorrupt("Missing rotor for helicopter"); + GetRotorImage(Aircraft::From(v), EIT_ON_MAP, &rotor->sprite_cache.sprite_seq); } @@ -707,6 +711,7 @@ class SlVehicleCommon : public DefaultSaveLoadHandler SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, SLV_60, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, SLV_67, SL_MAX_VERSION), + SLE_CONDVAR(Vehicle, last_loading_tick, SLE_UINT64, SLV_LAST_LOADING_TICK, SL_MAX_VERSION), SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, SLV_67, SL_MAX_VERSION), }; #if defined(_MSC_VER) && (_MSC_VER == 1915 || _MSC_VER == 1916) diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp index e81148fa5c12a..e8f66fb5d0784 100644 --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.cpp @@ -74,10 +74,11 @@ void MoveWaypointsToBaseStations() if (wp.delete_ctr != 0) continue; // The waypoint was deleted /* Waypoint indices were not added to the map prior to this. */ - _m[wp.xy].m2 = (StationID)wp.index; + Tile tile = wp.xy; + tile.m2() = (StationID)wp.index; - if (HasBit(_m[wp.xy].m3, 4)) { - wp.spec = StationClass::Get(STAT_CLASS_WAYP)->GetSpec(_m[wp.xy].m4 + 1); + if (HasBit(tile.m3(), 4)) { + wp.spec = StationClass::Get(STAT_CLASS_WAYP)->GetSpec(tile.m4() + 1); } } } else { @@ -102,16 +103,16 @@ void MoveWaypointsToBaseStations() TileIndex t = wp.xy; /* Sometimes waypoint (sign) locations became disconnected from their actual location in * the map array. If this is the case, try to locate the actual location in the map array */ - if (!IsTileType(t, MP_RAILWAY) || GetRailTileType(t) != 2 /* RAIL_TILE_WAYPOINT */ || _m[t].m2 != wp.index) { + if (!IsTileType(t, MP_RAILWAY) || GetRailTileType(t) != 2 /* RAIL_TILE_WAYPOINT */ || Tile(t).m2() != wp.index) { Debug(sl, 0, "Found waypoint tile {} with invalid position", t); - for (t = 0; t < MapSize(); t++) { - if (IsTileType(t, MP_RAILWAY) && GetRailTileType(t) == 2 /* RAIL_TILE_WAYPOINT */ && _m[t].m2 == wp.index) { + for (t = 0; t < Map::Size(); t++) { + if (IsTileType(t, MP_RAILWAY) && GetRailTileType(t) == 2 /* RAIL_TILE_WAYPOINT */ && Tile(t).m2() == wp.index) { Debug(sl, 0, "Found actual waypoint position at {}", t); break; } } } - if (t == MapSize()) { + if (t == Map::Size()) { SlErrorCorrupt("Waypoint with invalid tile"); } @@ -125,19 +126,20 @@ void MoveWaypointsToBaseStations() new_wp->string_id = STR_SV_STNAME_WAYPOINT; /* The tile might've been reserved! */ - bool reserved = !IsSavegameVersionBefore(SLV_100) && HasBit(_m[t].m5, 4); + Tile tile(t); + bool reserved = !IsSavegameVersionBefore(SLV_100) && HasBit(tile.m5(), 4); /* The tile really has our waypoint, so reassign the map array */ - MakeRailWaypoint(t, GetTileOwner(t), new_wp->index, (Axis)GB(_m[t].m5, 0, 1), 0, GetRailType(t)); + MakeRailWaypoint(tile, GetTileOwner(tile), new_wp->index, (Axis)GB(tile.m5(), 0, 1), 0, GetRailType(tile)); new_wp->facilities |= FACIL_TRAIN; - new_wp->owner = GetTileOwner(t); + new_wp->owner = GetTileOwner(tile); - SetRailStationReservation(t, reserved); + SetRailStationReservation(tile, reserved); if (wp.spec != nullptr) { - SetCustomStationSpecIndex(t, AllocateSpecToStation(wp.spec, new_wp, true)); + SetCustomStationSpecIndex(tile, AllocateSpecToStation(wp.spec, new_wp, true)); } - new_wp->rect.BeforeAddTile(t, StationRect::ADD_FORCE); + new_wp->rect.BeforeAddTile(tile, StationRect::ADD_FORCE); wp.new_index = new_wp->index; } diff --git a/src/screenshot.cpp b/src/screenshot.cpp index ddb22f13e1853..aed36ee7cbdf6 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.cpp @@ -8,6 +8,7 @@ /** @file screenshot.cpp The creation of screenshots! */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "fileio_func.h" #include "viewport_func.h" #include "gfx_func.h" @@ -27,6 +28,7 @@ #include "tile_map.h" #include "landscape.h" #include "video/video_driver.hpp" +#include "smallmap_gui.h" #include "table/strings.h" @@ -136,7 +138,7 @@ static bool MakeBMPImage(const char *name, ScreenshotCallback *callb, void *user /* Setup the file header */ BitmapFileHeader bfh; bfh.type = TO_LE16('MB'); - bfh.size = TO_LE32(sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + pal_size + bytewidth * h); + bfh.size = TO_LE32(sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + pal_size + static_cast(bytewidth) * h); bfh.reserved = 0; bfh.off_bits = TO_LE32(sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + pal_size); @@ -373,7 +375,7 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user maxlines = Clamp(65536 / w, 16, 128); /* now generate the bitmap bits */ - void *buff = CallocT(w * maxlines * bpp); // by default generate 128 lines at a time. + void *buff = CallocT(static_cast(w) * maxlines * bpp); // by default generate 128 lines at a time. y = 0; do { @@ -480,7 +482,7 @@ static bool MakePCXImage(const char *name, ScreenshotCallback *callb, void *user maxlines = Clamp(65536 / w, 16, 128); /* now generate the bitmap bits */ - uint8 *buff = CallocT(w * maxlines); // by default generate 128 lines at a time. + uint8 *buff = CallocT(static_cast(w) * maxlines); // by default generate 128 lines at a time. y = 0; do { @@ -616,7 +618,7 @@ static void CurrentScreenCallback(void *userdata, void *buf, uint y, uint pitch, static void LargeWorldCallback(void *userdata, void *buf, uint y, uint pitch, uint n) { Viewport *vp = (Viewport *)userdata; - DrawPixelInfo dpi, *old_dpi; + DrawPixelInfo dpi; int wx, left; /* We are no longer rendering to the screen */ @@ -629,8 +631,7 @@ static void LargeWorldCallback(void *userdata, void *buf, uint y, uint pitch, ui _screen.pitch = pitch; _screen_disable_anim = true; - old_dpi = _cur_dpi; - _cur_dpi = &dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &dpi); dpi.dst_ptr = buf; dpi.height = n; @@ -654,8 +655,6 @@ static void LargeWorldCallback(void *userdata, void *buf, uint y, uint pitch, ui ); } - _cur_dpi = old_dpi; - /* Switch back to rendering to the screen */ _screen = old_screen; _screen_disable_anim = old_disable_anim; @@ -680,8 +679,16 @@ static const char *MakeScreenshotName(const char *default_fn, const char *ext, b } } - /* Add extension to screenshot file */ size_t len = strlen(_screenshot_name); + + /* Handle user-specified filenames ending in # with automatic numbering */ + if (StrEndsWith(_screenshot_name, "#")) { + generate = true; + len -= 1; + _screenshot_name[len] = '\0'; + } + + /* Add extension to screenshot file */ seprintf(&_screenshot_name[len], lastof(_screenshot_name), ".%s", ext); const char *screenshot_dir = crashlog ? _personal_dir.c_str() : FiosGetScreenshotDir(); @@ -723,7 +730,7 @@ void SetupScreenshotViewport(ScreenshotType t, Viewport *vp, uint32 width, uint3 case SC_CRASHLOG: { assert(width == 0 && height == 0); - Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + Window *w = GetMainWindow(); vp->virtual_left = w->viewport->virtual_left; vp->virtual_top = w->viewport->virtual_top; vp->virtual_width = w->viewport->virtual_width; @@ -744,7 +751,7 @@ void SetupScreenshotViewport(ScreenshotType t, Viewport *vp, uint32 width, uint3 vp->zoom = ZOOM_LVL_WORLD_SCREENSHOT; TileIndex north_tile = _settings_game.construction.freeform_edges ? TileXY(1, 1) : TileXY(0, 0); - TileIndex south_tile = MapSize() - 1; + TileIndex south_tile = Map::Size() - 1; /* We need to account for a hill or high building at tile 0,0. */ int extra_height_top = TilePixelHeight(north_tile) + 150; @@ -767,7 +774,7 @@ void SetupScreenshotViewport(ScreenshotType t, Viewport *vp, uint32 width, uint3 default: { vp->zoom = (t == SC_ZOOMEDIN) ? _settings_client.gui.zoom_min : ZOOM_LVL_VIEWPORT; - Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + Window *w = GetMainWindow(); vp->virtual_left = w->viewport->virtual_left; vp->virtual_top = w->viewport->virtual_top; @@ -820,8 +827,8 @@ static void HeightmapCallback(void *userdata, void *buffer, uint y, uint pitch, { byte *buf = (byte *)buffer; while (n > 0) { - TileIndex ti = TileXY(MapMaxX(), y); - for (uint x = MapMaxX(); true; x--) { + TileIndex ti = TileXY(Map::MaxX(), y); + for (uint x = Map::MaxX(); true; x--) { *buf = 256 * TileHeight(ti) / (1 + _heightmap_highest_peak); buf++; if (x == 0) break; @@ -847,13 +854,13 @@ bool MakeHeightmapScreenshot(const char *filename) } _heightmap_highest_peak = 0; - for (TileIndex tile = 0; tile < MapSize(); tile++) { + for (TileIndex tile = 0; tile < Map::Size(); tile++) { uint h = TileHeight(tile); _heightmap_highest_peak = std::max(h, _heightmap_highest_peak); } const ScreenshotFormat *sf = _screenshot_formats + _cur_screenshot_format; - return sf->proc(filename, HeightmapCallback, nullptr, MapSizeX(), MapSizeY(), 8, palette); + return sf->proc(filename, HeightmapCallback, nullptr, Map::SizeX(), Map::SizeY(), 8, palette); } static ScreenshotType _confirmed_screenshot_type; ///< Screenshot type the current query is about to confirm. @@ -880,8 +887,8 @@ void MakeScreenshotWithConfirm(ScreenshotType t) SetupScreenshotViewport(t, &vp); bool heightmap_or_minimap = t == SC_HEIGHTMAP || t == SC_MINIMAP; - uint64_t width = (heightmap_or_minimap ? MapSizeX() : vp.width); - uint64_t height = (heightmap_or_minimap ? MapSizeY() : vp.height); + uint64_t width = (heightmap_or_minimap ? Map::SizeX() : vp.width); + uint64_t height = (heightmap_or_minimap ? Map::SizeY() : vp.height); if (width * height > 8192 * 8192) { /* Ask for confirmation */ @@ -995,57 +1002,16 @@ bool MakeScreenshot(ScreenshotType t, std::string name, uint32 width, uint32 hei } -/** - * Return the owner of a tile to display it with in the small map in mode "Owner". - * - * @param tile The tile of which we would like to get the colour. - * @return The owner of tile in the small map in mode "Owner" - */ -static Owner GetMinimapOwner(TileIndex tile) -{ - Owner o; - - if (IsTileType(tile, MP_VOID)) { - return OWNER_END; - } else { - switch (GetTileType(tile)) { - case MP_INDUSTRY: o = OWNER_DEITY; break; - case MP_HOUSE: o = OWNER_TOWN; break; - default: o = GetTileOwner(tile); break; - /* FIXME: For MP_ROAD there are multiple owners. - * GetTileOwner returns the rail owner (level crossing) resp. the owner of ROADTYPE_ROAD (normal road), - * even if there are no ROADTYPE_ROAD bits on the tile. - */ - } - - return o; - } -} - static void MinimapScreenCallback(void *userdata, void *buf, uint y, uint pitch, uint n) { - /* Fill with the company colours */ - byte owner_colours[OWNER_END + 1]; - for (const Company *c : Company::Iterate()) { - owner_colours[c->index] = MKCOLOUR(_colour_gradient[c->colour][5]); - } - - /* Fill with some special colours */ - owner_colours[OWNER_TOWN] = PC_DARK_RED; - owner_colours[OWNER_NONE] = PC_GRASS_LAND; - owner_colours[OWNER_WATER] = PC_WATER; - owner_colours[OWNER_DEITY] = PC_DARK_GREY; // industry - owner_colours[OWNER_END] = PC_BLACK; - uint32 *ubuf = (uint32 *)buf; uint num = (pitch * n); for (uint i = 0; i < num; i++) { uint row = y + (int)(i / pitch); - uint col = (MapSizeX() - 1) - (i % pitch); + uint col = (Map::SizeX() - 1) - (i % pitch); TileIndex tile = TileXY(col, row); - Owner o = GetMinimapOwner(tile); - byte val = owner_colours[o]; + byte val = GetSmallMapOwnerPixels(tile, GetTileType(tile), IncludeHeightmap::Never) & 0xFF; uint32 colour_buf = 0; colour_buf = (_cur_palette.palette[val].b << 0); @@ -1063,5 +1029,5 @@ static void MinimapScreenCallback(void *userdata, void *buf, uint y, uint pitch, bool MakeMinimapWorldScreenshot() { const ScreenshotFormat *sf = _screenshot_formats + _cur_screenshot_format; - return sf->proc(MakeScreenshotName(SCREENSHOT_NAME, sf->extension), MinimapScreenCallback, nullptr, MapSizeX(), MapSizeY(), 32, _cur_palette.palette); + return sf->proc(MakeScreenshotName(SCREENSHOT_NAME, sf->extension), MinimapScreenCallback, nullptr, Map::SizeX(), Map::SizeY(), 32, _cur_palette.palette); } diff --git a/src/script/CMakeLists.txt b/src/script/CMakeLists.txt index d1054ca5f84e1..d945e54ab923e 100644 --- a/src/script/CMakeLists.txt +++ b/src/script/CMakeLists.txt @@ -9,6 +9,8 @@ add_files( script_config.cpp script_config.hpp script_fatalerror.hpp + script_gui.h + script_gui.cpp script_info.cpp script_info.hpp script_info_dummy.cpp diff --git a/src/script/api/CMakeLists.txt b/src/script/api/CMakeLists.txt index 594d3c46a7765..de559d2229287 100644 --- a/src/script/api/CMakeLists.txt +++ b/src/script/api/CMakeLists.txt @@ -177,6 +177,7 @@ add_files( script_industrytypelist.hpp script_info_docs.hpp script_infrastructure.hpp + script_league.hpp script_list.hpp script_log.hpp script_map.hpp @@ -247,6 +248,7 @@ add_files( script_industrytype.cpp script_industrytypelist.cpp script_infrastructure.cpp + script_league.cpp script_list.cpp script_log.cpp script_map.cpp diff --git a/src/script/api/Doxyfile_AI.in b/src/script/api/Doxyfile_AI.in index f0707e0d866c5..cde1f21350d58 100644 --- a/src/script/api/Doxyfile_AI.in +++ b/src/script/api/Doxyfile_AI.in @@ -121,7 +121,6 @@ VERBATIM_HEADERS = NO # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output @@ -151,7 +150,7 @@ LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO -PAPER_TYPE = a4wide +PAPER_TYPE = a4 EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = NO diff --git a/src/script/api/Doxyfile_GS.in b/src/script/api/Doxyfile_GS.in index 7dae7aad6625a..b017bc94c5e4d 100644 --- a/src/script/api/Doxyfile_GS.in +++ b/src/script/api/Doxyfile_GS.in @@ -121,7 +121,6 @@ VERBATIM_HEADERS = NO # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output @@ -151,7 +150,7 @@ LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO -PAPER_TYPE = a4wide +PAPER_TYPE = a4 EXTRA_PACKAGES = LATEX_HEADER = PDF_HYPERLINKS = NO diff --git a/src/script/api/ai_changelog.hpp b/src/script/api/ai_changelog.hpp index f728ab18fe696..21534121cff25 100644 --- a/src/script/api/ai_changelog.hpp +++ b/src/script/api/ai_changelog.hpp @@ -13,13 +13,27 @@ * functions may still be available if you return an older API version * in GetAPIVersion() in info.nut. * - * \b 13.0 + * \b 14.0 * * This version is not yet released. The following changes are not set in stone yet. * + * API additions: + * \li AITown::ROAD_LAYOUT_RANDOM + * \li AIVehicle::IsPrimaryVehicle + * + * API removals: + * \li AIError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore. + * + * \b 13.0 + * + * API additions: + * \li AICargo::GetWeight * \li AIIndustryType::ResolveNewGRFID * \li AIObjectType::ResolveNewGRFID * + * Other changes: + * \li AIRoad::HasRoadType now correctly checks RoadType against RoadType + * * \b 12.0 * * API additions: diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp index 159671807d0d1..30ac4b7612945 100644 --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.hpp @@ -13,12 +13,29 @@ * functions may still be available if you return an older API version * in GetAPIVersion() in info.nut. * - * \b 13.0 + * \b 14.0 * * This version is not yet released. The following changes are not set in stone yet. * + * API additions: + * \li GSCompanyMode::IsValid + * \li GSCompanyMode::IsDeity + * \li GSTown::ROAD_LAYOUT_RANDOM + * \li GSVehicle::IsPrimaryVehicle + * + * API removals: + * \li GSError::ERR_PRECONDITION_TOO_MANY_PARAMETERS, that error is never returned anymore. + * + * \b 13.0 + * + * API additions: + * \li GSCargo::GetWeight * \li GSIndustryType::ResolveNewGRFID * \li GSObjectType::ResolveNewGRFID + * \li GSLeagueTable + * + * Other changes: + * \li GSRoad::HasRoadType now correctly checks RoadType against RoadType * * \b 12.0 * diff --git a/src/script/api/script_admin.cpp b/src/script/api/script_admin.cpp index 24aa0bcaf32b4..42615d2aedae2 100644 --- a/src/script/api/script_admin.cpp +++ b/src/script/api/script_admin.cpp @@ -28,9 +28,7 @@ SQInteger res; sq_getinteger(vm, index, &res); - char buf[10]; - seprintf(buf, lastof(buf), "%d", (int32)res); - data = buf; + data = fmt::format("{}", res); return true; } @@ -44,7 +42,7 @@ return false; } - data = std::string("\"") + buf + "\""; + data = fmt::format("\"{}\"", buf); return true; } diff --git a/src/script/api/script_airport.cpp b/src/script/api/script_airport.cpp index 4a4c3b99b2215..6513a1d205d4c 100644 --- a/src/script/api/script_airport.cpp +++ b/src/script/api/script_airport.cpp @@ -49,21 +49,21 @@ return ::IsTileType(tile, MP_STATION) && ::IsAirport(tile); } -/* static */ int32 ScriptAirport::GetAirportWidth(AirportType type) +/* static */ SQInteger ScriptAirport::GetAirportWidth(AirportType type) { if (!IsAirportInformationAvailable(type)) return -1; return ::AirportSpec::Get(type)->size_x; } -/* static */ int32 ScriptAirport::GetAirportHeight(AirportType type) +/* static */ SQInteger ScriptAirport::GetAirportHeight(AirportType type) { if (!IsAirportInformationAvailable(type)) return -1; return ::AirportSpec::Get(type)->size_y; } -/* static */ int32 ScriptAirport::GetAirportCoverageRadius(AirportType type) +/* static */ SQInteger ScriptAirport::GetAirportCoverageRadius(AirportType type) { if (!IsAirportInformationAvailable(type)) return -1; @@ -72,7 +72,7 @@ /* static */ bool ScriptAirport::BuildAirport(TileIndex tile, AirportType type, StationID station_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsValidAirportType(type)); EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id)); @@ -82,20 +82,21 @@ /* static */ bool ScriptAirport::RemoveAirport(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)) EnforcePrecondition(false, IsAirportTile(tile) || IsHangarTile(tile)); return ScriptObject::Command::Do(tile); } -/* static */ int32 ScriptAirport::GetNumHangars(TileIndex tile) +/* static */ SQInteger ScriptAirport::GetNumHangars(TileIndex tile) { + EnforceDeityOrCompanyModeValid(-1); if (!::IsValidTile(tile)) return -1; if (!::IsTileType(tile, MP_STATION)) return -1; const Station *st = ::Station::GetByTile(tile); - if (st->owner != ScriptObject::GetCompany() && ScriptObject::GetCompany() != OWNER_DEITY) return -1; + if (st->owner != ScriptObject::GetCompany() && ScriptCompanyMode::IsValid()) return -1; if ((st->facilities & FACIL_AIRPORT) == 0) return -1; return st->airport.GetNumHangars(); @@ -103,12 +104,13 @@ /* static */ TileIndex ScriptAirport::GetHangarOfAirport(TileIndex tile) { + EnforceDeityOrCompanyModeValid(INVALID_TILE); if (!::IsValidTile(tile)) return INVALID_TILE; if (!::IsTileType(tile, MP_STATION)) return INVALID_TILE; if (GetNumHangars(tile) < 1) return INVALID_TILE; const Station *st = ::Station::GetByTile(tile); - if (st->owner != ScriptObject::GetCompany() && ScriptObject::GetCompany() != OWNER_DEITY) return INVALID_TILE; + if (st->owner != ScriptObject::GetCompany() && ScriptCompanyMode::IsValid()) return INVALID_TILE; if ((st->facilities & FACIL_AIRPORT) == 0) return INVALID_TILE; return st->airport.GetHangarTile(0); @@ -126,11 +128,8 @@ } -/* static */ int ScriptAirport::GetNoiseLevelIncrease(TileIndex tile, AirportType type) +/* static */ SQInteger ScriptAirport::GetNoiseLevelIncrease(TileIndex tile, AirportType type) { - extern Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it, uint &mindist); - extern uint8 GetAirportNoiseLevelForDistance(const AirportSpec *as, uint distance); - if (!::IsValidTile(tile)) return -1; if (!IsAirportInformationAvailable(type)) return -1; @@ -149,8 +148,6 @@ /* static */ TownID ScriptAirport::GetNearestTown(TileIndex tile, AirportType type) { - extern Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it, uint &mindist); - if (!::IsValidTile(tile)) return INVALID_TOWN; if (!IsAirportInformationAvailable(type)) return INVALID_TOWN; @@ -161,9 +158,9 @@ return AirportGetNearestTown(as, AirportTileTableIterator(as->table[0], tile), dist)->index; } -/* static */ uint16 ScriptAirport::GetMaintenanceCostFactor(AirportType type) +/* static */ SQInteger ScriptAirport::GetMaintenanceCostFactor(AirportType type) { - if (!IsAirportInformationAvailable(type)) return INVALID_TOWN; + if (!IsAirportInformationAvailable(type)) return 0; return AirportSpec::Get(type)->maintenance_cost; } diff --git a/src/script/api/script_airport.hpp b/src/script/api/script_airport.hpp index 0748fa67fc5c0..9534f05d21c1b 100644 --- a/src/script/api/script_airport.hpp +++ b/src/script/api/script_airport.hpp @@ -96,7 +96,7 @@ class ScriptAirport : public ScriptObject { * @pre IsAirportInformationAvailable(type). * @return The width in tiles. */ - static int32 GetAirportWidth(AirportType type); + static SQInteger GetAirportWidth(AirportType type); /** * Get the height of this type of airport. @@ -104,7 +104,7 @@ class ScriptAirport : public ScriptObject { * @pre IsAirportInformationAvailable(type). * @return The height in tiles. */ - static int32 GetAirportHeight(AirportType type); + static SQInteger GetAirportHeight(AirportType type); /** * Get the coverage radius of this type of airport. @@ -112,7 +112,7 @@ class ScriptAirport : public ScriptObject { * @pre IsAirportInformationAvailable(type). * @return The radius in tiles. */ - static int32 GetAirportCoverageRadius(AirportType type); + static SQInteger GetAirportCoverageRadius(AirportType type); /** * Get the number of hangars of the airport. @@ -120,7 +120,7 @@ class ScriptAirport : public ScriptObject { * @pre ScriptMap::IsValidTile(tile). * @return The number of hangars of the airport. */ - static int32 GetNumHangars(TileIndex tile); + static SQInteger GetNumHangars(TileIndex tile); /** * Get the first hangar tile of the airport. @@ -142,7 +142,7 @@ class ScriptAirport : public ScriptObject { * @pre ScriptMap::IsValidTile(tile). * @pre AirportAvailable(type). * @pre station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_FLAT_LAND_REQUIRED * @exception ScriptError::ERR_LOCAL_AUTHORITY_REFUSES @@ -156,7 +156,7 @@ class ScriptAirport : public ScriptObject { * Removes an airport. * @param tile Any tile of the airport. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return Whether the airport has been/can be removed or not. */ @@ -180,7 +180,7 @@ class ScriptAirport : public ScriptObject { * @return The amount of noise added to the nearest town. * @note The noise will be added to the town with TownID GetNearestTown(tile, type). */ - static int GetNoiseLevelIncrease(TileIndex tile, AirportType type); + static SQInteger GetNoiseLevelIncrease(TileIndex tile, AirportType type); /** * Get the TownID of the town whose local authority will influence @@ -198,7 +198,7 @@ class ScriptAirport : public ScriptObject { * @pre IsAirportInformationAvailable(type) * @return Maintenance cost factor of the airport type. */ - static uint16 GetMaintenanceCostFactor(AirportType type); + static SQInteger GetMaintenanceCostFactor(AirportType type); /** * Get the monthly maintenance cost of an airport type. diff --git a/src/script/api/script_base.cpp b/src/script/api/script_base.cpp index 996d4d488fef0..ab5dd848bc13f 100644 --- a/src/script/api/script_base.cpp +++ b/src/script/api/script_base.cpp @@ -10,44 +10,39 @@ #include "../../stdafx.h" #include "script_base.hpp" #include "script_error.hpp" -#include "../../network/network.h" -#include "../../core/random_func.hpp" #include "../../safeguards.h" -/* static */ uint32 ScriptBase::Rand() +/* static */ SQInteger ScriptBase::Rand() { - /* We pick RandomRange if we are in SP (so when saved, we do the same over and over) - * but we pick InteractiveRandomRange if we are a network_server or network-client. */ - if (_networking) return ::InteractiveRandom(); - return ::Random(); + return ScriptObject::GetRandomizer().Next(); } -/* static */ uint32 ScriptBase::RandItem(int unused_param) +/* static */ SQInteger ScriptBase::RandItem(SQInteger unused_param) { return ScriptBase::Rand(); } -/* static */ uint ScriptBase::RandRange(uint max) +/* static */ SQInteger ScriptBase::RandRange(SQInteger max) { - /* We pick RandomRange if we are in SP (so when saved, we do the same over and over) - * but we pick InteractiveRandomRange if we are a network_server or network-client. */ - if (_networking) return ::InteractiveRandomRange(max); - return ::RandomRange(max); + max = Clamp(max, 0, UINT32_MAX); + return ScriptObject::GetRandomizer().Next(max); } -/* static */ uint32 ScriptBase::RandRangeItem(int unused_param, uint max) +/* static */ SQInteger ScriptBase::RandRangeItem(SQInteger unused_param, SQInteger max) { return ScriptBase::RandRange(max); } -/* static */ bool ScriptBase::Chance(uint out, uint max) +/* static */ bool ScriptBase::Chance(SQInteger out, SQInteger max) { + out = Clamp(out, 0, UINT32_MAX); + max = Clamp(max, 0, UINT32_MAX); EnforcePrecondition(false, out <= max); return ScriptBase::RandRange(max) < out; } -/* static */ bool ScriptBase::ChanceItem(int unused_param, uint out, uint max) +/* static */ bool ScriptBase::ChanceItem(SQInteger unused_param, SQInteger out, SQInteger max) { return ScriptBase::Chance(out, max); } diff --git a/src/script/api/script_base.hpp b/src/script/api/script_base.hpp index b8eebdf1b0e70..3b0422a7e2ba5 100644 --- a/src/script/api/script_base.hpp +++ b/src/script/api/script_base.hpp @@ -18,9 +18,6 @@ * * @note The random functions are not called Random and RandomRange, because * RANDOM_DEBUG does some tricky stuff, which messes with those names. - * @note In MP we cannot use Random because that will cause desyncs (scripts are - * ran on the server only, not on all clients). This means that - * we use InteractiveRandom in MP. Rand() takes care of this for you. */ class ScriptBase : public ScriptObject { public: @@ -28,50 +25,56 @@ class ScriptBase : public ScriptObject { * Get a random value. * @return A random value between 0 and MAX(uint32). */ - static uint32 Rand(); + static SQInteger Rand(); /** * Get a random value. * @param unused_param This parameter is not used, but is needed to work with lists. * @return A random value between 0 and MAX(uint32). */ - static uint32 RandItem(int unused_param); + static SQInteger RandItem(SQInteger unused_param); /** * Get a random value in a range. * @param max The first number this function will never return (the maximum it returns is max - 1). + * The value will be clamped to 0 .. MAX(uint32). * @return A random value between 0 .. max - 1. */ - static uint RandRange(uint max); + static SQInteger RandRange(SQInteger max); /** * Get a random value in a range. * @param unused_param This parameter is not used, but is needed to work with lists. * @param max The first number this function will never return (the maximum it returns is max - 1). + * The value will be clamped to 0 .. MAX(uint32). * @return A random value between 0 .. max - 1. */ - static uint RandRangeItem(int unused_param, uint max); + static SQInteger RandRangeItem(SQInteger unused_param, SQInteger max); /** * Returns approximately 'out' times true when called 'max' times. * After all, it is a random function. * @param out How many times it should return true. + * The value will be clamped to 0 .. MAX(uint32). * @param max Out of this many times. + * The value will be clamped to 0 .. MAX(uint32). * @pre \a out is at most equal to \a max. * @return True if the chance worked out. */ - static bool Chance(uint out, uint max); + static bool Chance(SQInteger out, SQInteger max); /** * Returns approximately 'out' times true when called 'max' times. * After all, it is a random function. * @param unused_param This parameter is not used, but is needed to work with lists. * @param out How many times it should return true. + * The value will be clamped to 0 .. MAX(uint32). * @param max Out of this many times. + * The value will be clamped to 0 .. MAX(uint32). * @pre \a out is at most equal to \a max. * @return True if the chance worked out. */ - static bool ChanceItem(int unused_param, uint out, uint max); + static bool ChanceItem(SQInteger unused_param, SQInteger out, SQInteger max); }; #endif /* SCRIPT_BASE_HPP */ diff --git a/src/script/api/script_basestation.cpp b/src/script/api/script_basestation.cpp index 788d5495009a0..408543ae8a07b 100644 --- a/src/script/api/script_basestation.cpp +++ b/src/script/api/script_basestation.cpp @@ -21,8 +21,9 @@ /* static */ bool ScriptBaseStation::IsValidBaseStation(StationID station_id) { + EnforceDeityOrCompanyModeValid(false); const BaseStation *st = ::BaseStation::GetIfValid(station_id); - return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || st->owner == OWNER_NONE); + return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity() || st->owner == OWNER_NONE); } /* static */ char *ScriptBaseStation::GetName(StationID station_id) @@ -37,10 +38,10 @@ { CCountedPtr counter(name); - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidBaseStation(station_id)); EnforcePrecondition(false, name != nullptr); - const char *text = name->GetDecodedText(); + const std::string &text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_STATION_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); diff --git a/src/script/api/script_basestation.hpp b/src/script/api/script_basestation.hpp index 85a34eac4f490..9f39368a306af 100644 --- a/src/script/api/script_basestation.hpp +++ b/src/script/api/script_basestation.hpp @@ -50,8 +50,8 @@ class ScriptBaseStation : public ScriptObject { * @param station_id The basestation to set the name of. * @param name The new name of the station (can be either a raw string, or a ScriptText object). * @pre IsValidBaseStation(station_id). - * @pre name != nullptr && len(name) != 0. - * @game @pre Valid ScriptCompanyMode active in scope. + * @pre name != null && len(name) != 0. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE * @return True if the name was changed. */ diff --git a/src/script/api/script_bridge.cpp b/src/script/api/script_bridge.cpp index b0fda24128dd9..1ec873204ed52 100644 --- a/src/script/api/script_bridge.cpp +++ b/src/script/api/script_bridge.cpp @@ -72,13 +72,14 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) /* static */ bool ScriptBridge::BuildBridge(ScriptVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end) { + EnforceDeityOrCompanyModeValid(false); EnforcePrecondition(false, start != end); EnforcePrecondition(false, ::IsValidTile(start) && ::IsValidTile(end)); EnforcePrecondition(false, TileX(start) == TileX(end) || TileY(start) == TileY(end)); EnforcePrecondition(false, vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER); EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_RAIL || ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType())); EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_ROAD || ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType())); - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD); + EnforcePrecondition(false, ScriptCompanyMode::IsValid() || vehicle_type == ScriptVehicle::VT_ROAD); switch (vehicle_type) { case ScriptVehicle::VT_ROAD: @@ -95,6 +96,8 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) /* static */ bool ScriptBridge::_BuildBridgeRoad1() { + EnforceDeityOrCompanyModeValid(false); + /* Build the piece of road on the 'start' side of the bridge */ TileIndex end = ScriptObject::GetCallbackVariable(0); TileIndex start = ScriptObject::GetCallbackVariable(1); @@ -107,6 +110,8 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) /* static */ bool ScriptBridge::_BuildBridgeRoad2() { + EnforceDeityOrCompanyModeValid(false); + /* Build the piece of road on the 'end' side of the bridge */ TileIndex end = ScriptObject::GetCallbackVariable(0); TileIndex start = ScriptObject::GetCallbackVariable(1); @@ -119,7 +124,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) /* static */ bool ScriptBridge::RemoveBridge(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsBridgeTile(tile)); return ScriptObject::Command::Do(tile); } @@ -132,32 +137,34 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) return GetString(vehicle_type == ScriptVehicle::VT_WATER ? STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT : ::GetBridgeSpec(bridge_id)->transport_name[vehicle_type]); } -/* static */ int32 ScriptBridge::GetMaxSpeed(BridgeID bridge_id) +/* static */ SQInteger ScriptBridge::GetMaxSpeed(BridgeID bridge_id) { if (!IsValidBridge(bridge_id)) return -1; return ::GetBridgeSpec(bridge_id)->speed; // km-ish/h } -/* static */ Money ScriptBridge::GetPrice(BridgeID bridge_id, uint length) +/* static */ Money ScriptBridge::GetPrice(BridgeID bridge_id, SQInteger length) { if (!IsValidBridge(bridge_id)) return -1; + length = Clamp(length, 0, INT32_MAX); + return ::CalcBridgeLenCostFactor(length) * _price[PR_BUILD_BRIDGE] * ::GetBridgeSpec(bridge_id)->price >> 8; } -/* static */ int32 ScriptBridge::GetMaxLength(BridgeID bridge_id) +/* static */ SQInteger ScriptBridge::GetMaxLength(BridgeID bridge_id) { if (!IsValidBridge(bridge_id)) return -1; - return std::min(::GetBridgeSpec(bridge_id)->max_length, _settings_game.construction.max_bridge_length) + 2; + return std::min(::GetBridgeSpec(bridge_id)->max_length, _settings_game.construction.max_bridge_length) + 2; } -/* static */ int32 ScriptBridge::GetMinLength(BridgeID bridge_id) +/* static */ SQInteger ScriptBridge::GetMinLength(BridgeID bridge_id) { if (!IsValidBridge(bridge_id)) return -1; - return ::GetBridgeSpec(bridge_id)->min_length + 2; + return static_cast(::GetBridgeSpec(bridge_id)->min_length) + 2; } /* static */ TileIndex ScriptBridge::GetOtherBridgeEnd(TileIndex tile) diff --git a/src/script/api/script_bridge.hpp b/src/script/api/script_bridge.hpp index 26d7e11619b0e..cce84f812dae0 100644 --- a/src/script/api/script_bridge.hpp +++ b/src/script/api/script_bridge.hpp @@ -80,16 +80,17 @@ class ScriptBridge : public ScriptObject { * This is mph / 1.6, which is roughly km/h. * To get km/h multiply this number by 1.00584. */ - static int32 GetMaxSpeed(BridgeID bridge_id); + static SQInteger GetMaxSpeed(BridgeID bridge_id); /** * Get the new cost of a bridge, excluding the road and/or rail. * @param bridge_id The bridge to get the new cost of. * @param length The length of the bridge. + * The value will be clamped to 0 .. MAX(int32). * @pre IsValidBridge(bridge_id). * @return The new cost the bridge has. */ - static Money GetPrice(BridgeID bridge_id, uint length); + static Money GetPrice(BridgeID bridge_id, SQInteger length); /** * Get the maximum length of a bridge. @@ -97,7 +98,7 @@ class ScriptBridge : public ScriptObject { * @pre IsValidBridge(bridge_id). * @returns The maximum length the bridge has. */ - static int32 GetMaxLength(BridgeID bridge_id); + static SQInteger GetMaxLength(BridgeID bridge_id); /** * Get the minimum length of a bridge. @@ -105,7 +106,7 @@ class ScriptBridge : public ScriptObject { * @pre IsValidBridge(bridge_id). * @returns The minimum length the bridge has. */ - static int32 GetMinLength(BridgeID bridge_id); + static SQInteger GetMinLength(BridgeID bridge_id); /** * Internal function to help BuildBridge in case of road. @@ -136,7 +137,7 @@ class ScriptBridge : public ScriptObject { * @pre vehicle_type == ScriptVehicle::VT_WATER || * (vehicle_type == ScriptVehicle::VT_ROAD && ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType())) || * (vehicle_type == ScriptVehicle::VT_RAIL && ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType())). - * @game @pre Outside CompanyMode: vehicle_type == ScriptVehicle::VT_ROAD. + * @game @pre ScriptCompanyMode::IsValid() || vehicle_type == ScriptVehicle::VT_ROAD. * @exception ScriptError::ERR_ALREADY_BUILT * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_LAND_SLOPED_WRONG @@ -145,7 +146,7 @@ class ScriptBridge : public ScriptObject { * @exception ScriptBridge::ERR_BRIDGE_CANNOT_END_IN_WATER * @exception ScriptBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT * @return Whether the bridge has been/can be build or not. - * @game @note Building a bridge (without CompanyMode) results in a bridge owned by towns. + * @game @note Building a bridge as deity (ScriptCompanyMode::IsDeity()) results in a bridge owned by towns. * @note No matter if the road pieces were build or not, if building the * bridge succeeded, this function returns true. */ @@ -155,7 +156,7 @@ class ScriptBridge : public ScriptObject { * Removes a bridge, by executing it on either the start or end tile. * @param tile An end or start tile of the bridge. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return Whether the bridge has been/can be removed or not. */ diff --git a/src/script/api/script_bridgelist.cpp b/src/script/api/script_bridgelist.cpp index a81c186edb334..bc78e7bf36ca9 100644 --- a/src/script/api/script_bridgelist.cpp +++ b/src/script/api/script_bridgelist.cpp @@ -21,11 +21,11 @@ ScriptBridgeList::ScriptBridgeList() } } -ScriptBridgeList_Length::ScriptBridgeList_Length(uint length) +ScriptBridgeList_Length::ScriptBridgeList_Length(SQInteger length) { for (byte j = 0; j < MAX_BRIDGES; j++) { if (ScriptBridge::IsValidBridge(j)) { - if (length >= (uint)ScriptBridge::GetMinLength(j) && length <= (uint)ScriptBridge::GetMaxLength(j)) this->AddItem(j); + if (length >= ScriptBridge::GetMinLength(j) && length <= ScriptBridge::GetMaxLength(j)) this->AddItem(j); } } } diff --git a/src/script/api/script_bridgelist.hpp b/src/script/api/script_bridgelist.hpp index 78088fe695216..17991f41f1755 100644 --- a/src/script/api/script_bridgelist.hpp +++ b/src/script/api/script_bridgelist.hpp @@ -32,7 +32,7 @@ class ScriptBridgeList_Length : public ScriptList { /** * @param length The length of the bridge you want to build. */ - ScriptBridgeList_Length(uint length); + ScriptBridgeList_Length(SQInteger length); }; #endif /* SCRIPT_BRIDGELIST_HPP */ diff --git a/src/script/api/script_cargo.cpp b/src/script/api/script_cargo.cpp index 5e092b52a0677..7354c848c0b06 100644 --- a/src/script/api/script_cargo.cpp +++ b/src/script/api/script_cargo.cpp @@ -70,9 +70,12 @@ return (ScriptCargo::TownEffect)::CargoSpec::Get(cargo_type)->town_effect; } -/* static */ Money ScriptCargo::GetCargoIncome(CargoID cargo_type, uint32 distance, uint32 days_in_transit) +/* static */ Money ScriptCargo::GetCargoIncome(CargoID cargo_type, SQInteger distance, SQInteger days_in_transit) { if (!IsValidCargo(cargo_type)) return -1; + + distance = Clamp(distance, 0, UINT32_MAX); + return ::GetTransportedGoodsIncome(1, distance, Clamp(days_in_transit * 2 / 5, 0, 255), cargo_type); } @@ -81,3 +84,12 @@ if (!ScriptCargo::IsValidCargo(cargo_type)) return INVALID_DISTRIBUTION_TYPE; return (ScriptCargo::DistributionType)_settings_game.linkgraph.GetDistributionType(cargo_type); } + +/* static */ SQInteger ScriptCargo::GetWeight(CargoID cargo_type, SQInteger amount) +{ + if (!IsValidCargo(cargo_type)) return -1; + + amount = Clamp(amount, 0, UINT32_MAX); + + return ::CargoSpec::Get(cargo_type)->WeightOfNUnits(amount); +} diff --git a/src/script/api/script_cargo.hpp b/src/script/api/script_cargo.hpp index 1bfd8c5531eac..c5b5c1b5f0bf9 100644 --- a/src/script/api/script_cargo.hpp +++ b/src/script/api/script_cargo.hpp @@ -142,10 +142,12 @@ class ScriptCargo : public ScriptObject { * @param cargo_type The cargo to transport. * @pre ScriptCargo::IsValidCargo(cargo_type). * @param distance The distance the cargo travels from begin to end. - * @param days_in_transit Amount of (game) days the cargo is in transit. The max value of this variable is 637. Any value higher returns the same as 637 would. + * The value will be clamped to 0 .. MAX(uint32). + * @param days_in_transit Amount of (game) days the cargo is in transit. + * The max value of this variable is 637. Any value higher returns the same as 637 would. * @return The amount of money that would be earned by this trip. */ - static Money GetCargoIncome(CargoID cargo_type, uint32 distance, uint32 days_in_transit); + static Money GetCargoIncome(CargoID cargo_type, SQInteger distance, SQInteger days_in_transit); /** * Get the cargo distribution type for a cargo. @@ -153,6 +155,17 @@ class ScriptCargo : public ScriptObject { * @return The cargo distribution type for the given cargo. */ static DistributionType GetDistributionType(CargoID cargo_type); + + /** + * Get the weight in tonnes for the given amount of + * cargo for the specified type. + * @param cargo_type The cargo to check on. + * @param amount The quantity of cargo. + * The value will be clamped to 0 .. MAX(uint32). + * @pre ScriptCargo::IsValidCargo(cargo_type). + * @return The weight in tonnes for that quantity of cargo. + */ + static SQInteger GetWeight(CargoID cargo_type, SQInteger amount); }; #endif /* SCRIPT_CARGO_HPP */ diff --git a/src/script/api/script_cargomonitor.cpp b/src/script/api/script_cargomonitor.cpp index dcb18b1ddb563..96828c83b6dc9 100644 --- a/src/script/api/script_cargomonitor.cpp +++ b/src/script/api/script_cargomonitor.cpp @@ -15,7 +15,7 @@ #include "../../safeguards.h" -/* static */ int32 ScriptCargoMonitor::GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring) +/* static */ SQInteger ScriptCargoMonitor::GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring) { CompanyID cid = static_cast(company); if (cid >= MAX_COMPANIES) return -1; @@ -26,7 +26,7 @@ return GetDeliveryAmount(monitor, keep_monitoring); } -/* static */ int32 ScriptCargoMonitor::GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring) +/* static */ SQInteger ScriptCargoMonitor::GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring) { CompanyID cid = static_cast(company); if (cid >= MAX_COMPANIES) return -1; @@ -37,7 +37,7 @@ return GetDeliveryAmount(monitor, keep_monitoring); } -/* static */ int32 ScriptCargoMonitor::GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring) +/* static */ SQInteger ScriptCargoMonitor::GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring) { CompanyID cid = static_cast(company); if (cid >= MAX_COMPANIES) return -1; @@ -48,7 +48,7 @@ return GetPickupAmount(monitor, keep_monitoring); } -/* static */ int32 ScriptCargoMonitor::GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring) +/* static */ SQInteger ScriptCargoMonitor::GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring) { CompanyID cid = static_cast(company); if (cid >= MAX_COMPANIES) return -1; diff --git a/src/script/api/script_cargomonitor.hpp b/src/script/api/script_cargomonitor.hpp index 58ed427bea491..f16b99cd955b1 100644 --- a/src/script/api/script_cargomonitor.hpp +++ b/src/script/api/script_cargomonitor.hpp @@ -51,7 +51,7 @@ class ScriptCargoMonitor : public ScriptObject { * @return Amount of delivered cargo of the given cargo type to the given town by the given company since the last call, or * \c -1 if a parameter is out-of-bound. */ - static int32 GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring); + static SQInteger GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring); /** * Get the amount of cargo delivered to an industry by a company since the last query, and update the monitoring state. @@ -62,7 +62,7 @@ class ScriptCargoMonitor : public ScriptObject { * @return Amount of delivered cargo of the given cargo type to the given industry by the given company since the last call, or * \c -1 if a parameter is out-of-bound. */ - static int32 GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring); + static SQInteger GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring); /** * Get the amount of cargo picked up (and delivered) from a town by a company since the last query, and update the monitoring state. @@ -74,7 +74,7 @@ class ScriptCargoMonitor : public ScriptObject { * \c -1 if a parameter is out-of-bound. * @note Amounts of picked-up cargo are added during final delivery of it, to prevent users from getting credit for picking up without delivering it. */ - static int32 GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring); + static SQInteger GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring); /** * Get the amount of cargo picked up (and delivered) from an industry by a company since the last query, and update the monitoring state. @@ -86,7 +86,7 @@ class ScriptCargoMonitor : public ScriptObject { * \c -1 if a parameter is out-of-bound. * @note Amounts of picked-up cargo are added during final delivery of it, to prevent users from getting credit for picking up without delivering it. */ - static int32 GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring); + static SQInteger GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring); /** Stop monitoring everything. */ static void StopAllMonitoring(); diff --git a/src/script/api/script_clientlist.hpp b/src/script/api/script_clientlist.hpp index 39a85fd6e087c..ea7859a6afe42 100644 --- a/src/script/api/script_clientlist.hpp +++ b/src/script/api/script_clientlist.hpp @@ -5,7 +5,7 @@ * 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 script_clientlist.hpp List all the TODO. */ +/** @file script_clientlist.hpp List all the clients in a game or in a company. */ #ifndef SCRIPT_CLIENTLIST_HPP #define SCRIPT_CLIENTLIST_HPP @@ -32,7 +32,7 @@ class ScriptClientList : public ScriptList { class ScriptClientList_Company : public ScriptList { public: /** - * @param company_id The company to list clients for. + * @param company The company to list clients for. */ ScriptClientList_Company(ScriptCompany::CompanyID company); }; diff --git a/src/script/api/script_company.cpp b/src/script/api/script_company.cpp index 6a06852da53e4..af73ae0f40ff1 100644 --- a/src/script/api/script_company.cpp +++ b/src/script/api/script_company.cpp @@ -47,8 +47,9 @@ { CCountedPtr counter(name); + EnforceCompanyModeValid(false); EnforcePrecondition(false, name != nullptr); - const char *text = name->GetDecodedText(); + const std::string &text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_COMPANY_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -68,8 +69,9 @@ { CCountedPtr counter(name); + EnforceCompanyModeValid(false); EnforcePrecondition(false, name != nullptr); - const char *text = name->GetDecodedText(); + const std::string &text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_PRESIDENT_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -94,12 +96,14 @@ /* static */ bool ScriptCompany::SetPresidentGender(Gender gender) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, gender == GENDER_MALE || gender == GENDER_FEMALE); EnforcePrecondition(false, GetPresidentGender(ScriptCompany::COMPANY_SELF) != gender); + Randomizer &randomizer = ScriptObject::GetRandomizer(); CompanyManagerFace cmf; - GenderEthnicity ge = (GenderEthnicity)((gender == GENDER_FEMALE ? (1 << ::GENDER_FEMALE) : 0) | (::InteractiveRandom() & (1 << ETHNICITY_BLACK))); - RandomCompanyManagerFaceBits(cmf, ge, false); + GenderEthnicity ge = (GenderEthnicity)((gender == GENDER_FEMALE ? (1 << ::GENDER_FEMALE) : 0) | (randomizer.Next() & (1 << ETHNICITY_BLACK))); + RandomCompanyManagerFaceBits(cmf, ge, false, randomizer); return ScriptObject::Command::Do(cmf); } @@ -113,11 +117,12 @@ return HasBit(ge, ::GENDER_FEMALE) ? GENDER_FEMALE : GENDER_MALE; } -/* static */ Money ScriptCompany::GetQuarterlyIncome(ScriptCompany::CompanyID company, uint32 quarter) +/* static */ Money ScriptCompany::GetQuarterlyIncome(ScriptCompany::CompanyID company, SQInteger quarter) { company = ResolveCompanyID(company); if (company == COMPANY_INVALID) return -1; if (quarter > EARLIEST_QUARTER) return -1; + if (quarter < CURRENT_QUARTER) return -1; if (quarter == CURRENT_QUARTER) { return ::Company::Get(company)->cur_economy.income; @@ -125,11 +130,12 @@ return ::Company::Get(company)->old_economy[quarter - 1].income; } -/* static */ Money ScriptCompany::GetQuarterlyExpenses(ScriptCompany::CompanyID company, uint32 quarter) +/* static */ Money ScriptCompany::GetQuarterlyExpenses(ScriptCompany::CompanyID company, SQInteger quarter) { company = ResolveCompanyID(company); if (company == COMPANY_INVALID) return -1; if (quarter > EARLIEST_QUARTER) return -1; + if (quarter < CURRENT_QUARTER) return -1; if (quarter == CURRENT_QUARTER) { return ::Company::Get(company)->cur_economy.expenses; @@ -137,11 +143,12 @@ return ::Company::Get(company)->old_economy[quarter - 1].expenses; } -/* static */ int32 ScriptCompany::GetQuarterlyCargoDelivered(ScriptCompany::CompanyID company, uint32 quarter) +/* static */ SQInteger ScriptCompany::GetQuarterlyCargoDelivered(ScriptCompany::CompanyID company, SQInteger quarter) { company = ResolveCompanyID(company); if (company == COMPANY_INVALID) return -1; if (quarter > EARLIEST_QUARTER) return -1; + if (quarter < CURRENT_QUARTER) return -1; if (quarter == CURRENT_QUARTER) { return ::Company::Get(company)->cur_economy.delivered_cargo.GetSum(); @@ -149,21 +156,22 @@ return ::Company::Get(company)->old_economy[quarter - 1].delivered_cargo.GetSum(); } -/* static */ int32 ScriptCompany::GetQuarterlyPerformanceRating(ScriptCompany::CompanyID company, uint32 quarter) +/* static */ SQInteger ScriptCompany::GetQuarterlyPerformanceRating(ScriptCompany::CompanyID company, SQInteger quarter) { company = ResolveCompanyID(company); if (company == COMPANY_INVALID) return -1; if (quarter > EARLIEST_QUARTER) return -1; - if (quarter == CURRENT_QUARTER) return -1; + if (quarter <= CURRENT_QUARTER) return -1; return ::Company::Get(company)->old_economy[quarter - 1].performance_history; } -/* static */ Money ScriptCompany::GetQuarterlyCompanyValue(ScriptCompany::CompanyID company, uint32 quarter) +/* static */ Money ScriptCompany::GetQuarterlyCompanyValue(ScriptCompany::CompanyID company, SQInteger quarter) { company = ResolveCompanyID(company); if (company == COMPANY_INVALID) return -1; if (quarter > EARLIEST_QUARTER) return -1; + if (quarter < CURRENT_QUARTER) return -1; if (quarter == CURRENT_QUARTER) { return ::CalculateCompanyValue(::Company::Get(company)); @@ -190,7 +198,7 @@ /* static */ Money ScriptCompany::GetMaxLoanAmount() { - return _economy.max_loan; + return _economy.max_loan * GetPaceFactor(); } /* static */ Money ScriptCompany::GetLoanInterval() @@ -200,7 +208,7 @@ /* static */ bool ScriptCompany::SetLoanAmount(Money loan) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, loan >= 0); EnforcePrecondition(false, ((int64)loan % GetLoanInterval()) == 0); EnforcePrecondition(false, loan <= GetMaxLoanAmount()); @@ -219,7 +227,7 @@ /* static */ bool ScriptCompany::SetMinimumLoanAmount(Money loan) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, loan >= 0); Money over_interval = (int64)loan % GetLoanInterval(); @@ -234,10 +242,8 @@ /* static */ bool ScriptCompany::ChangeBankBalance(CompanyID company, Money delta, ExpensesType expenses_type, TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, expenses_type < (ExpensesType)::EXPENSES_END); - EnforcePrecondition(false, (int64)delta >= INT32_MIN); - EnforcePrecondition(false, (int64)delta <= INT32_MAX); EnforcePrecondition(false, tile == INVALID_TILE || ::IsValidTile(tile)); company = ResolveCompanyID(company); @@ -249,7 +255,7 @@ /* static */ bool ScriptCompany::BuildCompanyHQ(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); return ScriptObject::Command::Do(tile, OBJECT_HQ, 0); @@ -266,6 +272,7 @@ /* static */ bool ScriptCompany::SetAutoRenewStatus(bool autorenew) { + EnforceCompanyModeValid(false); return ScriptObject::Command::Do("company.engine_renew", autorenew ? 1 : 0); } @@ -277,12 +284,15 @@ return ::Company::Get(company)->settings.engine_renew; } -/* static */ bool ScriptCompany::SetAutoRenewMonths(int16 months) +/* static */ bool ScriptCompany::SetAutoRenewMonths(SQInteger months) { + EnforceCompanyModeValid(false); + months = Clamp(months, INT16_MIN, INT16_MAX); + return ScriptObject::Command::Do("company.engine_renew_months", months); } -/* static */ int16 ScriptCompany::GetAutoRenewMonths(CompanyID company) +/* static */ SQInteger ScriptCompany::GetAutoRenewMonths(CompanyID company) { company = ResolveCompanyID(company); if (company == COMPANY_INVALID) return 0; @@ -292,8 +302,10 @@ /* static */ bool ScriptCompany::SetAutoRenewMoney(Money money) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, money >= 0); EnforcePrecondition(false, (int64)money <= UINT32_MAX); + money /= GetPaceFactor(); return ScriptObject::Command::Do("company.engine_renew_money", money); } @@ -302,16 +314,18 @@ company = ResolveCompanyID(company); if (company == COMPANY_INVALID) return 0; - return ::Company::Get(company)->settings.engine_renew_money; + return ::Company::Get(company)->settings.engine_renew_money * GetPaceFactor(); } /* static */ bool ScriptCompany::SetPrimaryLiveryColour(LiveryScheme scheme, Colours colour) { + EnforceCompanyModeValid(false); return ScriptObject::Command::Do((::LiveryScheme)scheme, true, (::Colours)colour); } /* static */ bool ScriptCompany::SetSecondaryLiveryColour(LiveryScheme scheme, Colours colour) { + EnforceCompanyModeValid(false); return ScriptObject::Command::Do((::LiveryScheme)scheme, false, (::Colours)colour); } diff --git a/src/script/api/script_company.hpp b/src/script/api/script_company.hpp index 947698b171a11..c96e7216ca5f3 100644 --- a/src/script/api/script_company.hpp +++ b/src/script/api/script_company.hpp @@ -137,7 +137,8 @@ class ScriptCompany : public ScriptObject { /** * Set the name of your company. * @param name The new name of the company (can be either a raw string, or a ScriptText object). - * @pre name != nullptr && len(name) != 0. + * @pre name != null && len(name) != 0. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE * @return True if the name was changed. */ @@ -154,7 +155,8 @@ class ScriptCompany : public ScriptObject { /** * Set the name of your president. * @param name The new name of the president (can be either a raw string, or a ScriptText object). - * @pre name != nullptr && len(name) != 0. + * @pre name != null && len(name) != 0. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE * @return True if the name was changed. */ @@ -172,6 +174,7 @@ class ScriptCompany : public ScriptObject { * Set the gender of the president of your company. * @param gender The new gender for your president. * @pre GetPresidentGender(ScriptCompany.COMPANY_SELF) != gender. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if the gender was changed. * @note When successful a random face will be created. * @api -game @@ -192,7 +195,7 @@ class ScriptCompany : public ScriptObject { * @pre GetLoanInterval() must be a multiplier of 'loan'. * @pre 'loan' must be below GetMaxLoanAmount(). * @pre 'loan' - GetLoanAmount() + GetBankBalance() must be non-negative. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if the loan could be set to your requested amount. */ static bool SetLoanAmount(Money loan); @@ -202,7 +205,7 @@ class ScriptCompany : public ScriptObject { * @param loan The amount to loan (any positive number). * @pre 'loan' must be non-negative. * @pre 'loan' must be below GetMaxLoanAmount(). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if we could allocate a minimum of 'loan' loan. */ static bool SetMinimumLoanAmount(Money loan); @@ -244,10 +247,8 @@ class ScriptCompany : public ScriptObject { * @param expenses_type The account in the finances window that will register the cost. * @param tile The tile to show text effect on or ScriptMap::TILE_INVALID * @return True, if the bank balance was changed. - * @game @pre No ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsDeity(). * @pre ResolveCompanyID(company) != COMPANY_INVALID. - * @pre delta >= -2**31 - * @pre delta < 2**31 * @note You need to create your own news message to inform about costs/gifts that you create using this command. * @api -ai */ @@ -263,7 +264,7 @@ class ScriptCompany : public ScriptObject { * @pre quarter <= EARLIEST_QUARTER. * @return The gross income of the company in the given quarter. */ - static Money GetQuarterlyIncome(CompanyID company, uint32 quarter); + static Money GetQuarterlyIncome(CompanyID company, SQInteger quarter); /** * Get the expenses of the company in the given quarter. @@ -276,7 +277,7 @@ class ScriptCompany : public ScriptObject { * @pre quarter <= EARLIEST_QUARTER. * @return The expenses of the company in the given quarter. */ - static Money GetQuarterlyExpenses(CompanyID company, uint32 quarter); + static Money GetQuarterlyExpenses(CompanyID company, SQInteger quarter); /** * Get the amount of cargo delivered by the given company in the given quarter. @@ -286,7 +287,7 @@ class ScriptCompany : public ScriptObject { * @pre quarter <= EARLIEST_QUARTER. * @return The amount of cargo delivered by the given company in the given quarter. */ - static int32 GetQuarterlyCargoDelivered(CompanyID company, uint32 quarter); + static SQInteger GetQuarterlyCargoDelivered(CompanyID company, SQInteger quarter); /** * Get the performance rating of the given company in the given quarter. @@ -298,7 +299,7 @@ class ScriptCompany : public ScriptObject { * @note The performance rating is calculated after every quarter, so the value for CURRENT_QUARTER is undefined. * @return The performance rating of the given company in the given quarter. */ - static int32 GetQuarterlyPerformanceRating(CompanyID company, uint32 quarter); + static SQInteger GetQuarterlyPerformanceRating(CompanyID company, SQInteger quarter); /** * Get the value of the company in the given quarter. @@ -308,13 +309,13 @@ class ScriptCompany : public ScriptObject { * @pre quarter <= EARLIEST_QUARTER. * @return The value of the company in the given quarter. */ - static Money GetQuarterlyCompanyValue(CompanyID company, uint32 quarter); + static Money GetQuarterlyCompanyValue(CompanyID company, SQInteger quarter); /** * Build your company's HQ on the given tile. * @param tile The tile to build your HQ on, this tile is the most northern tile of your HQ. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_FLAT_LAND_REQUIRED * @return True if the HQ could be build. @@ -335,6 +336,7 @@ class ScriptCompany : public ScriptObject { /** * Set whether autorenew is enabled for your company. * @param autorenew The new autorenew status. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if autorenew status has been modified. * @api -game */ @@ -351,10 +353,12 @@ class ScriptCompany : public ScriptObject { /** * Set the number of months before/after max age to autorenew an engine for your company. * @param months The new months between autorenew. + * The value will be clamped to MIN(int16) .. MAX(int16). + * @game @pre ScriptCompanyMode::IsValid(). * @return True if autorenew months has been modified. * @api -game */ - static bool SetAutoRenewMonths(int16 months); + static bool SetAutoRenewMonths(SQInteger months); /** * Return the number of months before/after max age to autorenew an engine for a company. @@ -362,11 +366,12 @@ class ScriptCompany : public ScriptObject { * @pre ResolveCompanyID(company) != COMPANY_INVALID. * @return The months before/after max age of engine. */ - static int16 GetAutoRenewMonths(CompanyID company); + static SQInteger GetAutoRenewMonths(CompanyID company); /** * Set the minimum money needed to autorenew an engine for your company. * @param money The new minimum required money for autorenew to work. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if autorenew money has been modified. * @pre money >= 0 * @pre money < 2**32 @@ -386,6 +391,7 @@ class ScriptCompany : public ScriptObject { * Set primary colour for your company. * @param scheme Livery scheme to set. * @param colour Colour to set. + * @game @pre ScriptCompanyMode::IsValid(). * @return False if unable to set primary colour of the livery scheme (e.g. colour in use). */ static bool SetPrimaryLiveryColour(LiveryScheme scheme, Colours colour); @@ -394,6 +400,7 @@ class ScriptCompany : public ScriptObject { * Set secondary colour for your company. * @param scheme Livery scheme to set. * @param colour Colour to set. + * @game @pre ScriptCompanyMode::IsValid(). * @return False if unable to set secondary colour of the livery scheme. */ static bool SetSecondaryLiveryColour(LiveryScheme scheme, Colours colour); diff --git a/src/script/api/script_companymode.cpp b/src/script/api/script_companymode.cpp index 83beec5ebb85f..3a5c5f48f7f04 100644 --- a/src/script/api/script_companymode.cpp +++ b/src/script/api/script_companymode.cpp @@ -13,16 +13,26 @@ #include "../../safeguards.h" -ScriptCompanyMode::ScriptCompanyMode(int company) +ScriptCompanyMode::ScriptCompanyMode(SQInteger company) { if (company < OWNER_BEGIN || company >= MAX_COMPANIES) company = INVALID_COMPANY; if (!::Company::IsValidID(company)) company = INVALID_COMPANY; this->last_company = ScriptObject::GetCompany(); - ScriptObject::SetCompany((CompanyID)company); + ScriptObject::SetCompany((::CompanyID)company); } ScriptCompanyMode::~ScriptCompanyMode() { ScriptObject::SetCompany(this->last_company); } + +/* static */ bool ScriptCompanyMode::IsValid() +{ + return ::Company::IsValidID(ScriptObject::GetCompany()); +} + +/* static */ bool ScriptCompanyMode::IsDeity() +{ + return ScriptObject::GetCompany() == OWNER_DEITY; +} diff --git a/src/script/api/script_companymode.hpp b/src/script/api/script_companymode.hpp index e00cc7bfb0023..8378e11c4c540 100644 --- a/src/script/api/script_companymode.hpp +++ b/src/script/api/script_companymode.hpp @@ -40,13 +40,29 @@ class ScriptCompanyMode : public ScriptObject { * @note When the instance is destroyed, it restores the company that was * current when the instance was created! */ - ScriptCompanyMode(int company); + ScriptCompanyMode(SQInteger company); /** * Destroying this instance reset the company to that what it was * in when the instance was created. */ ~ScriptCompanyMode(); + + /** + * Check whether a company mode is valid. In other words, are commands + * being executed under some company and does the company still exist? + * @return true When a company mode is valid. + * @post !ScriptCompanyMode::IsDeity(). + */ + static bool IsValid(); + + /** + * Check whether the company mode is not active, i.e. whether we are a deity. + * In other words, are commands are not being executed under some company. + * @return true When we are a deity, i.e. company mode is not active. + * @post !ScriptCompanyMode::IsValid(). + */ + static bool IsDeity(); }; #endif /* SCRIPT_COMPANYMODE_HPP */ diff --git a/src/script/api/script_controller.cpp b/src/script/api/script_controller.cpp index 232ce5a3b629e..44a4b152b88c6 100644 --- a/src/script/api/script_controller.cpp +++ b/src/script/api/script_controller.cpp @@ -18,7 +18,7 @@ #include "../script_info.hpp" #include "../script_instance.hpp" #include "script_log.hpp" -#include "../../ai/ai_gui.hpp" +#include "../script_gui.h" #include "../../settings_type.h" #include "../../network/network.h" #include "../../misc_cmd.h" @@ -57,7 +57,7 @@ /* Inform script developer that their script has been paused and * needs manual action to continue. */ - ShowAIDebugWindow(ScriptObject::GetRootCompany()); + ShowScriptDebugWindow(ScriptObject::GetRootCompany()); if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { ScriptObject::Command::Do(PM_PAUSED_NORMAL, true); diff --git a/src/script/api/script_controller.hpp b/src/script/api/script_controller.hpp index d0bb129e9db1c..89d46f8c90554 100644 --- a/src/script/api/script_controller.hpp +++ b/src/script/api/script_controller.hpp @@ -48,6 +48,7 @@ class ScriptController { friend class ScriptInstance; public: +#ifndef DOXYGEN_API /** * Initializer of the ScriptController. * @param company The company this Script is normally serving. @@ -59,6 +60,7 @@ class ScriptController { */ ~ScriptController(); +#else /** * This function is called to start your script. Your script starts here. If you * return from this function, your script dies, so make sure that doesn't @@ -67,7 +69,6 @@ class ScriptController { */ void Start(); -#ifdef DOXYGEN_API /** * Save the state of the script. * diff --git a/src/script/api/script_date.cpp b/src/script/api/script_date.cpp index ae3dff78c6231..27289d75d06cb 100644 --- a/src/script/api/script_date.cpp +++ b/src/script/api/script_date.cpp @@ -25,7 +25,7 @@ return (ScriptDate::Date)_date; } -/* static */ int32 ScriptDate::GetYear(ScriptDate::Date date) +/* static */ SQInteger ScriptDate::GetYear(ScriptDate::Date date) { if (date < 0) return DATE_INVALID; @@ -34,7 +34,7 @@ return ymd.year; } -/* static */ int32 ScriptDate::GetMonth(ScriptDate::Date date) +/* static */ SQInteger ScriptDate::GetMonth(ScriptDate::Date date) { if (date < 0) return DATE_INVALID; @@ -43,7 +43,7 @@ return ymd.month + 1; } -/* static */ int32 ScriptDate::GetDayOfMonth(ScriptDate::Date date) +/* static */ SQInteger ScriptDate::GetDayOfMonth(ScriptDate::Date date) { if (date < 0) return DATE_INVALID; @@ -52,7 +52,7 @@ return ymd.day; } -/* static */ ScriptDate::Date ScriptDate::GetDate(int32 year, int32 month, int32 day_of_month) +/* static */ ScriptDate::Date ScriptDate::GetDate(SQInteger year, SQInteger month, SQInteger day_of_month) { if (month < 1 || month > 12) return DATE_INVALID; if (day_of_month < 1 || day_of_month > 31) return DATE_INVALID; @@ -61,7 +61,7 @@ return (ScriptDate::Date)::ConvertYMDToDate(year, month - 1, day_of_month); } -/* static */ int32 ScriptDate::GetSystemTime() +/* static */ SQInteger ScriptDate::GetSystemTime() { time_t t; time(&t); diff --git a/src/script/api/script_date.hpp b/src/script/api/script_date.hpp index 5daa5fb03f15b..4373706aa7a78 100644 --- a/src/script/api/script_date.hpp +++ b/src/script/api/script_date.hpp @@ -55,21 +55,21 @@ class ScriptDate : public ScriptObject { * @param date The date to get the year of. * @return The year. */ - static int32 GetYear(Date date); + static SQInteger GetYear(Date date); /** * Get the month of the given date. * @param date The date to get the month of. * @return The month. */ - static int32 GetMonth(Date date); + static SQInteger GetMonth(Date date); /** * Get the day (of the month) of the given date. * @param date The date to get the day of. * @return The day. */ - static int32 GetDayOfMonth(Date date); + static SQInteger GetDayOfMonth(Date date); /** * Get the date given a year, month and day of month. @@ -78,7 +78,7 @@ class ScriptDate : public ScriptObject { * @param day_of_month The day of month of the to-be determined date. * @return The date. */ - static Date GetDate(int32 year, int32 month, int32 day_of_month); + static Date GetDate(SQInteger year, SQInteger month, SQInteger day_of_month); /** * Get the time of the host system. @@ -86,7 +86,7 @@ class ScriptDate : public ScriptObject { * @api -ai * @note This uses the clock of the host system, which can skew or be set back. Use with caution. */ - static int32 GetSystemTime(); + static SQInteger GetSystemTime(); }; #endif /* SCRIPT_DATE_HPP */ diff --git a/src/script/api/script_depotlist.cpp b/src/script/api/script_depotlist.cpp index 4b07636ce5f5b..2e1dc6fc98819 100644 --- a/src/script/api/script_depotlist.cpp +++ b/src/script/api/script_depotlist.cpp @@ -16,6 +16,7 @@ ScriptDepotList::ScriptDepotList(ScriptTile::TransportType transport_type) { + EnforceDeityOrCompanyModeValid_Void(); ::TileType tile_type; switch (transport_type) { default: return; @@ -27,7 +28,7 @@ ScriptDepotList::ScriptDepotList(ScriptTile::TransportType transport_type) case ScriptTile::TRANSPORT_AIR: { /* Hangars are not seen as real depots by the depot code. */ for (const Station *st : Station::Iterate()) { - if (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) { + if (st->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity()) { for (uint i = 0; i < st->airport.GetNumHangars(); i++) { this->AddItem(st->airport.GetHangarTile(i)); } @@ -39,6 +40,6 @@ ScriptDepotList::ScriptDepotList(ScriptTile::TransportType transport_type) /* Handle 'standard' depots. */ for (const Depot *depot : Depot::Iterate()) { - if ((::GetTileOwner(depot->xy) == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && ::IsTileType(depot->xy, tile_type)) this->AddItem(depot->xy); + if ((::GetTileOwner(depot->xy) == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity()) && ::IsTileType(depot->xy, tile_type)) this->AddItem(depot->xy); } } diff --git a/src/script/api/script_engine.cpp b/src/script/api/script_engine.cpp index 7530693d070b0..17845ae4fecab 100644 --- a/src/script/api/script_engine.cpp +++ b/src/script/api/script_engine.cpp @@ -24,17 +24,19 @@ /* static */ bool ScriptEngine::IsValidEngine(EngineID engine_id) { + EnforceDeityOrCompanyModeValid(false); const Engine *e = ::Engine::GetIfValid(engine_id); if (e == nullptr || !e->IsEnabled()) return false; /* AIs have only access to engines they can purchase or still have in use. * Deity has access to all engined that will be or were available ever. */ CompanyID company = ScriptObject::GetCompany(); - return company == OWNER_DEITY || ::IsEngineBuildable(engine_id, e->type, company) || ::Company::Get(company)->group_all[e->type].num_engines[engine_id] > 0; + return ScriptCompanyMode::IsDeity() || ::IsEngineBuildable(engine_id, e->type, company) || ::Company::Get(company)->group_all[e->type].num_engines[engine_id] > 0; } /* static */ bool ScriptEngine::IsBuildable(EngineID engine_id) { + EnforceDeityOrCompanyModeValid(false); const Engine *e = ::Engine::GetIfValid(engine_id); return e != nullptr && ::IsEngineBuildable(engine_id, e->type, ScriptObject::GetCompany()); } @@ -83,7 +85,7 @@ } -/* static */ int32 ScriptEngine::GetCapacity(EngineID engine_id) +/* static */ SQInteger ScriptEngine::GetCapacity(EngineID engine_id) { if (!IsValidEngine(engine_id)) return -1; @@ -107,7 +109,7 @@ } } -/* static */ int32 ScriptEngine::GetReliability(EngineID engine_id) +/* static */ SQInteger ScriptEngine::GetReliability(EngineID engine_id) { if (!IsValidEngine(engine_id)) return -1; if (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL && IsWagon(engine_id)) return -1; @@ -115,12 +117,12 @@ return ::ToPercent16(::Engine::Get(engine_id)->reliability); } -/* static */ int32 ScriptEngine::GetMaxSpeed(EngineID engine_id) +/* static */ SQInteger ScriptEngine::GetMaxSpeed(EngineID engine_id) { if (!IsValidEngine(engine_id)) return -1; const Engine *e = ::Engine::Get(engine_id); - int32 max_speed = e->GetDisplayMaxSpeed(); // km-ish/h + uint max_speed = e->GetDisplayMaxSpeed(); // km-ish/h if (e->type == VEH_AIRCRAFT) max_speed /= _settings_game.vehicle.plane_speed; return max_speed; } @@ -132,7 +134,7 @@ return ::Engine::Get(engine_id)->GetCost(); } -/* static */ int32 ScriptEngine::GetMaxAge(EngineID engine_id) +/* static */ SQInteger ScriptEngine::GetMaxAge(EngineID engine_id) { if (!IsValidEngine(engine_id)) return -1; if (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL && IsWagon(engine_id)) return -1; @@ -147,7 +149,7 @@ return ::Engine::Get(engine_id)->GetRunningCost(); } -/* static */ int32 ScriptEngine::GetPower(EngineID engine_id) +/* static */ SQInteger ScriptEngine::GetPower(EngineID engine_id) { if (!IsValidEngine(engine_id)) return -1; if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL && GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return -1; @@ -156,7 +158,7 @@ return ::Engine::Get(engine_id)->GetPower(); } -/* static */ int32 ScriptEngine::GetWeight(EngineID engine_id) +/* static */ SQInteger ScriptEngine::GetWeight(EngineID engine_id) { if (!IsValidEngine(engine_id)) return -1; if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL && GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return -1; @@ -164,7 +166,7 @@ return ::Engine::Get(engine_id)->GetDisplayWeight(); } -/* static */ int32 ScriptEngine::GetMaxTractiveEffort(EngineID engine_id) +/* static */ SQInteger ScriptEngine::GetMaxTractiveEffort(EngineID engine_id) { if (!IsValidEngine(engine_id)) return -1; if (GetVehicleType(engine_id) != ScriptVehicle::VT_RAIL && GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return -1; @@ -265,24 +267,19 @@ return (ScriptAirport::PlaneType)::AircraftVehInfo(engine_id)->subtype; } -/* static */ uint ScriptEngine::GetMaximumOrderDistance(EngineID engine_id) +/* static */ SQInteger ScriptEngine::GetMaximumOrderDistance(EngineID engine_id) { if (!IsValidEngine(engine_id)) return 0; + if (GetVehicleType(engine_id) != ScriptVehicle::VT_AIR) return 0; - switch (GetVehicleType(engine_id)) { - case ScriptVehicle::VT_AIR: - return ::Engine::Get(engine_id)->GetRange() * ::Engine::Get(engine_id)->GetRange(); - - default: - return 0; - } + return (SQInteger)::Engine::Get(engine_id)->GetRange() * ::Engine::Get(engine_id)->GetRange(); } /* static */ bool ScriptEngine::EnableForCompany(EngineID engine_id, ScriptCompany::CompanyID company) { company = ScriptCompany::ResolveCompanyID(company); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, IsValidEngine(engine_id)); EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); @@ -293,7 +290,7 @@ { company = ScriptCompany::ResolveCompanyID(company); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, IsValidEngine(engine_id)); EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); diff --git a/src/script/api/script_engine.hpp b/src/script/api/script_engine.hpp index f6bdbedbf236e..73414c1b4c01d 100644 --- a/src/script/api/script_engine.hpp +++ b/src/script/api/script_engine.hpp @@ -24,7 +24,7 @@ class ScriptEngine : public ScriptObject { /** * Checks whether the given engine type is valid. * An engine is valid for a company if it has at least one vehicle of this engine or it's currently buildable. - * @game Outside ScriptCompanyMode scope the function reports all engines valid, which were or will be available at some point. + * @game Outside ScriptCompanyMode scope (ScriptCompanyMode::IsDeity) the function reports all engines valid, which were or will be available at some point. * @param engine_id The engine to check. * @return True if and only if the engine type is valid. */ @@ -32,7 +32,7 @@ class ScriptEngine : public ScriptObject { /** * Checks whether the given engine type is buildable for a company. - * @game Outside ScriptCompanyMode scope the function checks whether the engine is currently buildable by all companies (no exclusive preview). + * @game Outside ScriptCompanyMode scope (ScriptCompanyMode::IsDeity) the function checks whether the engine is currently buildable by all companies (no exclusive preview). * @param engine_id The engine to check. * @return True if and only if the engine type is buildable. */ @@ -89,7 +89,7 @@ class ScriptEngine : public ScriptObject { * @pre IsValidEngine(engine_id). * @return The capacity of the engine. */ - static int32 GetCapacity(EngineID engine_id); + static SQInteger GetCapacity(EngineID engine_id); /** * Get the reliability of an engine. The value is between 0 and 100, where @@ -100,7 +100,7 @@ class ScriptEngine : public ScriptObject { * @pre GetVehicleType(engine_id) != ScriptVehicle::VT_TRAIN || !IsWagon(engine_id). * @return The reliability the engine has. */ - static int32 GetReliability(EngineID engine_id); + static SQInteger GetReliability(EngineID engine_id); /** * Get the maximum speed of an engine. @@ -111,7 +111,7 @@ class ScriptEngine : public ScriptObject { * This is mph / 1.6, which is roughly km/h. * To get km/h multiply this number by 1.00584. */ - static int32 GetMaxSpeed(EngineID engine_id); + static SQInteger GetMaxSpeed(EngineID engine_id); /** * Get the new cost of an engine. @@ -128,7 +128,7 @@ class ScriptEngine : public ScriptObject { * @returns The maximum age of a new engine in days. * @note Age is in days; divide by 366 to get per year. */ - static int32 GetMaxAge(EngineID engine_id); + static SQInteger GetMaxAge(EngineID engine_id); /** * Get the running cost of an engine. @@ -146,7 +146,7 @@ class ScriptEngine : public ScriptObject { * @pre (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL || GetVehicleType(engine_id) == ScriptVehicle::VT_ROAD) && !IsWagon(engine_id). * @return The power of the engine in hp. */ - static int32 GetPower(EngineID engine_id); + static SQInteger GetPower(EngineID engine_id); /** * Get the weight of an engine. @@ -155,7 +155,7 @@ class ScriptEngine : public ScriptObject { * @pre (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL || GetVehicleType(engine_id) == ScriptVehicle::VT_ROAD). * @return The weight of the engine in metric tons. */ - static int32 GetWeight(EngineID engine_id); + static SQInteger GetWeight(EngineID engine_id); /** * Get the maximum tractive effort of an engine. @@ -164,7 +164,7 @@ class ScriptEngine : public ScriptObject { * @pre (GetVehicleType(engine_id) == ScriptVehicle::VT_RAIL || GetVehicleType(engine_id) == ScriptVehicle::VT_ROAD) && !IsWagon(engine_id). * @return The maximum tractive effort of the engine in kN. */ - static int32 GetMaxTractiveEffort(EngineID engine_id); + static SQInteger GetMaxTractiveEffort(EngineID engine_id); /** * Get the date this engine was designed. @@ -286,7 +286,7 @@ class ScriptEngine : public ScriptObject { * not be compared with map distances * @see ScriptOrder::GetOrderDistance */ - static uint GetMaximumOrderDistance(EngineID engine_id); + static SQInteger GetMaximumOrderDistance(EngineID engine_id); /** * Allows a company to use an engine before its intro date or after retirement. diff --git a/src/script/api/script_enginelist.cpp b/src/script/api/script_enginelist.cpp index c6f594cc7e9c3..9ba725dfd0339 100644 --- a/src/script/api/script_enginelist.cpp +++ b/src/script/api/script_enginelist.cpp @@ -15,7 +15,8 @@ ScriptEngineList::ScriptEngineList(ScriptVehicle::VehicleType vehicle_type) { + EnforceDeityOrCompanyModeValid_Void(); for (const Engine *e : Engine::IterateType((::VehicleType)vehicle_type)) { - if (ScriptObject::GetCompany() == OWNER_DEITY || HasBit(e->company_avail, ScriptObject::GetCompany())) this->AddItem(e->index); + if (ScriptCompanyMode::IsDeity() || HasBit(e->company_avail, ScriptObject::GetCompany())) this->AddItem(e->index); } } diff --git a/src/script/api/script_error.hpp b/src/script/api/script_error.hpp index 87d4196fdd910..f4adb84cec539 100644 --- a/src/script/api/script_error.hpp +++ b/src/script/api/script_error.hpp @@ -11,6 +11,7 @@ #define SCRIPT_ERROR_HPP #include "script_object.hpp" +#include "script_companymode.hpp" #include /** @@ -42,15 +43,42 @@ * @param string The string that is checked. */ #define EnforcePreconditionEncodedText(returnval, string) \ - if ((string) == nullptr) { \ - ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_TOO_MANY_PARAMETERS); \ - return returnval; \ - } \ - if (StrEmpty(string)) { \ + if (string.empty()) { \ ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_FAILED); \ return returnval; \ } +/** + * Helper to enforce the precondition that the company mode is valid. + * @param returnval The value to return on failure. + */ +#define EnforceCompanyModeValid(returnval) \ + EnforcePreconditionCustomError(returnval, ScriptCompanyMode::IsValid(), ScriptError::ERR_PRECONDITION_INVALID_COMPANY) + +/** + * Helper to enforce the precondition that we are in a deity mode. + * @param returnval The value to return on failure. + */ +#define EnforceDeityMode(returnval) \ + EnforcePreconditionCustomError(returnval, ScriptCompanyMode::IsDeity(), ScriptError::ERR_PRECONDITION_INVALID_COMPANY) + +/** + * Helper to enforce the precondition that the company mode is valid or that we are a deity. + * @param returnval The value to return on failure. + */ +#define EnforceDeityOrCompanyModeValid(returnval) \ + EnforcePreconditionCustomError(returnval, ScriptCompanyMode::IsDeity() || ScriptCompanyMode::IsValid(), ScriptError::ERR_PRECONDITION_INVALID_COMPANY) + +/** + * Helper to enforce the precondition that the company mode is valid or that we are a deity. + */ +#define EnforceDeityOrCompanyModeValid_Void() \ + if (!(ScriptCompanyMode::IsDeity() || ScriptCompanyMode::IsValid())) { \ + ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); \ + return; \ + } + + /** * Class that handles all error related functions. * @api ai game @@ -94,8 +122,6 @@ class ScriptError : public ScriptObject { ERR_PRECONDITION_FAILED, // [] /** A string supplied was too long */ ERR_PRECONDITION_STRING_TOO_LONG, // [] - /** A string had too many parameters */ - ERR_PRECONDITION_TOO_MANY_PARAMETERS, // [] /** The company you use is invalid */ ERR_PRECONDITION_INVALID_COMPANY, // [] /** An error returned by a NewGRF. No possibility to get the exact error in an script readable format */ diff --git a/src/script/api/script_event.hpp b/src/script/api/script_event.hpp index 8e8f1817015dc..2ff813aa8161d 100644 --- a/src/script/api/script_event.hpp +++ b/src/script/api/script_event.hpp @@ -61,6 +61,7 @@ class ScriptEvent : public ScriptObject { /** * Constructor of ScriptEvent, to get the type of event. + * @param type The type of event to construct. */ ScriptEvent(ScriptEvent::ScriptEventType type) : type(type) diff --git a/src/script/api/script_event_types.cpp b/src/script/api/script_event_types.cpp index e9349a035fb23..9eb01a3682df7 100644 --- a/src/script/api/script_event_types.cpp +++ b/src/script/api/script_event_types.cpp @@ -111,12 +111,14 @@ int32 ScriptEventEnginePreview::GetVehicleType() bool ScriptEventEnginePreview::AcceptPreview() { + EnforceCompanyModeValid(false); if (!this->IsEngineValid()) return false; return ScriptObject::Command::Do(this->engine); } bool ScriptEventCompanyAskMerger::AcceptMerger() { + EnforceCompanyModeValid(false); return ScriptObject::Command::Do((::CompanyID)this->owner); } diff --git a/src/script/api/script_event_types.hpp b/src/script/api/script_event_types.hpp index 3ed6c5b10aaf1..24e50ae4b0045 100644 --- a/src/script/api/script_event_types.hpp +++ b/src/script/api/script_event_types.hpp @@ -33,6 +33,7 @@ class ScriptEventVehicleCrashed : public ScriptEvent { CRASH_FLOODED, ///< Vehicle was flooded }; +#ifndef DOXYGEN_API /** * @param vehicle The vehicle that crashed. * @param crash_site Where the vehicle crashed. @@ -44,6 +45,7 @@ class ScriptEventVehicleCrashed : public ScriptEvent { vehicle(vehicle), crash_reason(crash_reason) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -82,6 +84,7 @@ class ScriptEventVehicleCrashed : public ScriptEvent { */ class ScriptEventSubsidyOffer : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param subsidy_id The index of this subsidy in the _subsidies array. */ @@ -89,6 +92,7 @@ class ScriptEventSubsidyOffer : public ScriptEvent { ScriptEvent(ET_SUBSIDY_OFFER), subsidy_id(subsidy_id) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -113,6 +117,7 @@ class ScriptEventSubsidyOffer : public ScriptEvent { */ class ScriptEventSubsidyOfferExpired : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param subsidy_id The index of this subsidy in the _subsidies array. */ @@ -120,6 +125,7 @@ class ScriptEventSubsidyOfferExpired : public ScriptEvent { ScriptEvent(ET_SUBSIDY_OFFER_EXPIRED), subsidy_id(subsidy_id) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -144,6 +150,7 @@ class ScriptEventSubsidyOfferExpired : public ScriptEvent { */ class ScriptEventSubsidyAwarded : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param subsidy_id The index of this subsidy in the _subsidies array. */ @@ -151,6 +158,7 @@ class ScriptEventSubsidyAwarded : public ScriptEvent { ScriptEvent(ET_SUBSIDY_AWARDED), subsidy_id(subsidy_id) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -175,6 +183,7 @@ class ScriptEventSubsidyAwarded : public ScriptEvent { */ class ScriptEventSubsidyExpired : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param subsidy_id The index of this subsidy in the _subsidies array. */ @@ -182,6 +191,7 @@ class ScriptEventSubsidyExpired : public ScriptEvent { ScriptEvent(ET_SUBSIDY_EXPIRED), subsidy_id(subsidy_id) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -208,6 +218,7 @@ class ScriptEventSubsidyExpired : public ScriptEvent { */ class ScriptEventEnginePreview : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param engine The engine offered to test. */ @@ -215,6 +226,7 @@ class ScriptEventEnginePreview : public ScriptEvent { ScriptEvent(ET_ENGINE_PREVIEW), engine(engine) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -277,6 +289,7 @@ class ScriptEventEnginePreview : public ScriptEvent { /** * Accept the engine preview. + * @game @pre ScriptCompanyMode::IsValid(). * @return True when the accepting succeeded. */ bool AcceptPreview(); @@ -297,6 +310,7 @@ class ScriptEventEnginePreview : public ScriptEvent { */ class ScriptEventCompanyNew : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param owner The new company. */ @@ -304,6 +318,7 @@ class ScriptEventCompanyNew : public ScriptEvent { ScriptEvent(ET_COMPANY_NEW), owner((ScriptCompany::CompanyID)owner) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -329,6 +344,7 @@ class ScriptEventCompanyNew : public ScriptEvent { */ class ScriptEventCompanyInTrouble : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param owner The company that is in trouble. */ @@ -336,6 +352,7 @@ class ScriptEventCompanyInTrouble : public ScriptEvent { ScriptEvent(ET_COMPANY_IN_TROUBLE), owner((ScriptCompany::CompanyID)owner) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -360,15 +377,17 @@ class ScriptEventCompanyInTrouble : public ScriptEvent { */ class ScriptEventCompanyAskMerger : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param owner The company that can be bought. * @param value The value/costs of buying the company. */ - ScriptEventCompanyAskMerger(Owner owner, int32 value) : + ScriptEventCompanyAskMerger(Owner owner, Money value) : ScriptEvent(ET_COMPANY_ASK_MERGER), owner((ScriptCompany::CompanyID)owner), value(value) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -388,17 +407,18 @@ class ScriptEventCompanyAskMerger : public ScriptEvent { * Get the value of the new company. * @return The value of the new company. */ - int32 GetValue() { return this->value; } + Money GetValue() { return this->value; } /** * Take over the company for this merger. + * @game @pre ScriptCompanyMode::IsValid(). * @return true if the merger was a success. */ bool AcceptMerger(); private: ScriptCompany::CompanyID owner; ///< The company that is in trouble. - int32 value; ///< The value of the company, i.e. the amount you would pay. + Money value; ///< The value of the company, i.e. the amount you would pay. }; /** @@ -408,6 +428,7 @@ class ScriptEventCompanyAskMerger : public ScriptEvent { */ class ScriptEventCompanyMerger : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param old_owner The company bought off. * @param new_owner The company that bought owner. @@ -417,6 +438,7 @@ class ScriptEventCompanyMerger : public ScriptEvent { old_owner((ScriptCompany::CompanyID)old_owner), new_owner((ScriptCompany::CompanyID)new_owner) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -451,6 +473,7 @@ class ScriptEventCompanyMerger : public ScriptEvent { */ class ScriptEventCompanyBankrupt : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param owner The company that has gone bankrupt. */ @@ -458,6 +481,7 @@ class ScriptEventCompanyBankrupt : public ScriptEvent { ScriptEvent(ET_COMPANY_BANKRUPT), owner((ScriptCompany::CompanyID)owner) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -482,6 +506,7 @@ class ScriptEventCompanyBankrupt : public ScriptEvent { */ class ScriptEventVehicleLost : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param vehicle_id The vehicle that is lost. */ @@ -489,6 +514,7 @@ class ScriptEventVehicleLost : public ScriptEvent { ScriptEvent(ET_VEHICLE_LOST), vehicle_id(vehicle_id) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -513,6 +539,7 @@ class ScriptEventVehicleLost : public ScriptEvent { */ class ScriptEventVehicleWaitingInDepot : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param vehicle_id The vehicle that is waiting in a depot. */ @@ -520,6 +547,7 @@ class ScriptEventVehicleWaitingInDepot : public ScriptEvent { ScriptEvent(ET_VEHICLE_WAITING_IN_DEPOT), vehicle_id(vehicle_id) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -544,6 +572,7 @@ class ScriptEventVehicleWaitingInDepot : public ScriptEvent { */ class ScriptEventVehicleUnprofitable : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param vehicle_id The vehicle that was unprofitable. */ @@ -551,6 +580,7 @@ class ScriptEventVehicleUnprofitable : public ScriptEvent { ScriptEvent(ET_VEHICLE_UNPROFITABLE), vehicle_id(vehicle_id) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -575,6 +605,7 @@ class ScriptEventVehicleUnprofitable : public ScriptEvent { */ class ScriptEventIndustryOpen : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param industry_id The new industry. */ @@ -582,6 +613,7 @@ class ScriptEventIndustryOpen : public ScriptEvent { ScriptEvent(ET_INDUSTRY_OPEN), industry_id(industry_id) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -606,6 +638,7 @@ class ScriptEventIndustryOpen : public ScriptEvent { */ class ScriptEventIndustryClose : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param industry_id The new industry. */ @@ -613,6 +646,7 @@ class ScriptEventIndustryClose : public ScriptEvent { ScriptEvent(ET_INDUSTRY_CLOSE), industry_id(industry_id) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -637,6 +671,7 @@ class ScriptEventIndustryClose : public ScriptEvent { */ class ScriptEventEngineAvailable : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param engine The engine that is available. */ @@ -644,6 +679,7 @@ class ScriptEventEngineAvailable : public ScriptEvent { ScriptEvent(ET_ENGINE_AVAILABLE), engine(engine) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -668,6 +704,7 @@ class ScriptEventEngineAvailable : public ScriptEvent { */ class ScriptEventStationFirstVehicle : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param station The station visited for the first time. * @param vehicle The vehicle visiting the station. @@ -677,6 +714,7 @@ class ScriptEventStationFirstVehicle : public ScriptEvent { station(station), vehicle(vehicle) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -708,6 +746,7 @@ class ScriptEventStationFirstVehicle : public ScriptEvent { */ class ScriptEventDisasterZeppelinerCrashed : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param station The station containing the affected airport */ @@ -715,6 +754,7 @@ class ScriptEventDisasterZeppelinerCrashed : public ScriptEvent { ScriptEvent(ET_DISASTER_ZEPPELINER_CRASHED), station(station) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -739,6 +779,7 @@ class ScriptEventDisasterZeppelinerCrashed : public ScriptEvent { */ class ScriptEventDisasterZeppelinerCleared : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param station The station containing the affected airport */ @@ -746,6 +787,7 @@ class ScriptEventDisasterZeppelinerCleared : public ScriptEvent { ScriptEvent(ET_DISASTER_ZEPPELINER_CLEARED), station(station) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -770,6 +812,7 @@ class ScriptEventDisasterZeppelinerCleared : public ScriptEvent { */ class ScriptEventTownFounded : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param town The town that was created. */ @@ -777,6 +820,7 @@ class ScriptEventTownFounded : public ScriptEvent { ScriptEvent(ET_TOWN_FOUNDED), town(town) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -803,6 +847,7 @@ class ScriptEventTownFounded : public ScriptEvent { */ class ScriptEventAircraftDestTooFar : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param vehicle_id The aircraft whose destination is too far away. */ @@ -810,6 +855,7 @@ class ScriptEventAircraftDestTooFar : public ScriptEvent { ScriptEvent(ET_AIRCRAFT_DEST_TOO_FAR), vehicle_id(vehicle_id) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -834,10 +880,12 @@ class ScriptEventAircraftDestTooFar : public ScriptEvent { */ class ScriptEventAdminPort : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param json The JSON string which got sent. */ ScriptEventAdminPort(const std::string &json); +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -846,10 +894,19 @@ class ScriptEventAdminPort : public ScriptEvent { */ static ScriptEventAdminPort *Convert(ScriptEvent *instance) { return (ScriptEventAdminPort *)instance; } +#ifndef DOXYGEN_API /** - * Get the information that was sent to you back as Squirrel object. + * The GetObject() wrapper from Squirrel. */ SQInteger GetObject(HSQUIRRELVM vm); +#else + /** + * Get the information that was sent to you back as Squirrel object. + * @return The object. + */ + SQObject GetObject(); +#endif /* DOXYGEN_API */ + private: std::string json; ///< The JSON string. @@ -882,6 +939,7 @@ class ScriptEventAdminPort : public ScriptEvent { */ class ScriptEventWindowWidgetClick : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param window The windowclass that was clicked. * @param number The windownumber that was clicked. @@ -893,6 +951,7 @@ class ScriptEventWindowWidgetClick : public ScriptEvent { number(number), widget(widget) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -903,16 +962,19 @@ class ScriptEventWindowWidgetClick : public ScriptEvent { /** * Get the class of the window that was clicked. + * @return The clicked window class. */ ScriptWindow::WindowClass GetWindowClass() { return this->window; } /** * Get the number of the window that was clicked. + * @return The clicked identifying number of the widget within the class. */ uint32 GetWindowNumber() { return this->number; } /** * Get the number of the widget that was clicked. + * @return The number of the clicked widget. */ uint8 GetWidgetNumber() { return this->widget; } @@ -930,6 +992,7 @@ class ScriptEventWindowWidgetClick : public ScriptEvent { */ class ScriptEventGoalQuestionAnswer : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param uniqueid The uniqueID you have given this question. * @param company The company that is replying. @@ -941,6 +1004,7 @@ class ScriptEventGoalQuestionAnswer : public ScriptEvent { company(company), button(button) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -951,16 +1015,19 @@ class ScriptEventGoalQuestionAnswer : public ScriptEvent { /** * Get the unique id of the question. + * @return The unique id. */ uint16 GetUniqueID() { return this->uniqueid; } /** * Get the company that pressed a button. + * @return The company. */ ScriptCompany::CompanyID GetCompany() { return this->company; } /** * Get the button that got pressed. + * @return The button. */ ScriptGoal::QuestionButton GetButton() { return this->button; } @@ -976,6 +1043,7 @@ class ScriptEventGoalQuestionAnswer : public ScriptEvent { */ class ScriptEventCompanyTown : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param event The eventtype. * @param company The company. @@ -986,6 +1054,7 @@ class ScriptEventCompanyTown : public ScriptEvent { company(company), town(town) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -1018,6 +1087,7 @@ class ScriptEventCompanyTown : public ScriptEvent { */ class ScriptEventExclusiveTransportRights : public ScriptEventCompanyTown { public: +#ifndef DOXYGEN_API /** * @param company The company. * @param town The town. @@ -1025,6 +1095,7 @@ class ScriptEventExclusiveTransportRights : public ScriptEventCompanyTown { ScriptEventExclusiveTransportRights(ScriptCompany::CompanyID company, TownID town) : ScriptEventCompanyTown(ET_EXCLUSIVE_TRANSPORT_RIGHTS, company, town) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -1041,6 +1112,7 @@ class ScriptEventExclusiveTransportRights : public ScriptEventCompanyTown { */ class ScriptEventRoadReconstruction : public ScriptEventCompanyTown { public: +#ifndef DOXYGEN_API /** * @param company The company. * @param town The town. @@ -1048,6 +1120,7 @@ class ScriptEventRoadReconstruction : public ScriptEventCompanyTown { ScriptEventRoadReconstruction(ScriptCompany::CompanyID company, TownID town) : ScriptEventCompanyTown(ET_ROAD_RECONSTRUCTION, company, town) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -1063,6 +1136,7 @@ class ScriptEventRoadReconstruction : public ScriptEventCompanyTown { */ class ScriptEventVehicleAutoReplaced : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param old_id The vehicle that has been replaced. * @param new_id The vehicle that has been created in replacement. @@ -1072,6 +1146,7 @@ class ScriptEventVehicleAutoReplaced : public ScriptEvent { old_id(old_id), new_id(new_id) {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -1103,6 +1178,7 @@ class ScriptEventVehicleAutoReplaced : public ScriptEvent { */ class ScriptEventStoryPageButtonClick : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param company_id Which company triggered the event. * @param page_id Which page was the clicked button on. @@ -1113,7 +1189,8 @@ class ScriptEventStoryPageButtonClick : public ScriptEvent { company_id((ScriptCompany::CompanyID)company_id), page_id(page_id), element_id(element_id) - { } + {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -1122,13 +1199,22 @@ class ScriptEventStoryPageButtonClick : public ScriptEvent { */ static ScriptEventStoryPageButtonClick *Convert(ScriptEvent *instance) { return (ScriptEventStoryPageButtonClick *)instance; } - /** Get the CompanyID of the player that selected a tile. */ + /** + * Get the CompanyID of the player that selected a tile. + * @return The ID of the company. + */ ScriptCompany::CompanyID GetCompanyID() { return this->company_id; } - /** Get the StoryPageID of the storybook page the clicked button is located on. */ + /** + * Get the StoryPageID of the storybook page the clicked button is located on. + * @return The ID of the page in the story book the click was on. + */ StoryPageID GetStoryPageID() { return this->page_id; } - /** Get the StoryPageElementID of the button element that was clicked. */ + /** + * Get the StoryPageElementID of the button element that was clicked. + * @return The ID of the element that was clicked. + */ StoryPageElementID GetElementID() { return this->element_id; } private: @@ -1143,6 +1229,7 @@ class ScriptEventStoryPageButtonClick : public ScriptEvent { */ class ScriptEventStoryPageTileSelect : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param company_id Which company triggered the event. * @param page_id Which page is the used selection button on. @@ -1155,7 +1242,8 @@ class ScriptEventStoryPageTileSelect : public ScriptEvent { page_id(page_id), element_id(element_id), tile_index(tile_index) - { } + {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -1164,16 +1252,28 @@ class ScriptEventStoryPageTileSelect : public ScriptEvent { */ static ScriptEventStoryPageTileSelect *Convert(ScriptEvent *instance) { return (ScriptEventStoryPageTileSelect *)instance; } - /** Get the CompanyID of the player that selected a tile. */ + /** + * Get the CompanyID of the player that selected a tile. + * @return The company that selected the tile. + */ ScriptCompany::CompanyID GetCompanyID() { return this->company_id; } - /** Get the StoryPageID of the storybook page the used selection button is located on. */ + /** + * Get the StoryPageID of the storybook page the used selection button is located on. + * @return The ID of the story page selection was done from. + */ StoryPageID GetStoryPageID() { return this->page_id; } - /** Get the StoryPageElementID of the selection button used to select the tile. */ + /** + * Get the StoryPageElementID of the selection button used to select the tile. + * @return The ID of the element that was used to select the tile. + */ StoryPageElementID GetElementID() { return this->element_id; } - /** Get the TileIndex of the tile the player selected */ + /** + * Get the TileIndex of the tile the player selected. + * @return The selected tile. + */ TileIndex GetTile() { return this->tile_index; } private: @@ -1189,6 +1289,7 @@ class ScriptEventStoryPageTileSelect : public ScriptEvent { */ class ScriptEventStoryPageVehicleSelect : public ScriptEvent { public: +#ifndef DOXYGEN_API /** * @param company_id Which company triggered the event. * @param page_id Which page is the used selection button on. @@ -1201,7 +1302,8 @@ class ScriptEventStoryPageVehicleSelect : public ScriptEvent { page_id(page_id), element_id(element_id), vehicle_id(vehicle_id) - { } + {} +#endif /* DOXYGEN_API */ /** * Convert an ScriptEvent to the real instance. @@ -1210,16 +1312,28 @@ class ScriptEventStoryPageVehicleSelect : public ScriptEvent { */ static ScriptEventStoryPageVehicleSelect *Convert(ScriptEvent *instance) { return (ScriptEventStoryPageVehicleSelect *)instance; } - /** Get the CompanyID of the player that selected a tile. */ + /** + * Get the CompanyID of the player that selected a tile. + * @return The company's ID. + */ ScriptCompany::CompanyID GetCompanyID() { return this->company_id; } - /** Get the StoryPageID of the storybook page the used selection button is located on. */ + /** + * Get the StoryPageID of the storybook page the used selection button is located on. + * @return The ID of the storybook page the selected element is on. + */ StoryPageID GetStoryPageID() { return this->page_id; } - /** Get the StoryPageElementID of the selection button used to select the vehicle. */ + /** + * Get the StoryPageElementID of the selection button used to select the vehicle. + * @return The ID of the selected element of the story page. + */ StoryPageElementID GetElementID() { return this->element_id; } - /** Get the VehicleID of the vehicle the player selected */ + /** + * Get the VehicleID of the vehicle the player selected. + * @return The ID of the vehicle. + */ VehicleID GetVehicleID() { return this->vehicle_id; } private: diff --git a/src/script/api/script_game.cpp b/src/script/api/script_game.cpp index 3df6aef154a47..d338837f14982 100644 --- a/src/script/api/script_game.cpp +++ b/src/script/api/script_game.cpp @@ -9,6 +9,7 @@ #include "../../stdafx.h" #include "script_game.hpp" +#include "script_error.hpp" #include "../../command_type.h" #include "../../settings_type.h" #include "../../network/network.h" diff --git a/src/script/api/script_game.hpp b/src/script/api/script_game.hpp index a9e5b7a258fba..b5fd62c524f88 100644 --- a/src/script/api/script_game.hpp +++ b/src/script/api/script_game.hpp @@ -53,6 +53,7 @@ class ScriptGame : public ScriptObject { /** * Get the current landscape. + * @return The type of landscape. */ static LandscapeType GetLandscape(); diff --git a/src/script/api/script_gamesettings.cpp b/src/script/api/script_gamesettings.cpp index 2791aba0060c9..c8d99c36e6b52 100644 --- a/src/script/api/script_gamesettings.cpp +++ b/src/script/api/script_gamesettings.cpp @@ -22,22 +22,27 @@ return sd != nullptr && sd->IsIntSetting(); } -/* static */ int32 ScriptGameSettings::GetValue(const char *setting) +/* static */ SQInteger ScriptGameSettings::GetValue(const char *setting) { if (!IsValid(setting)) return -1; const SettingDesc *sd = GetSettingFromName(setting); + assert(sd != nullptr); return sd->AsIntSetting()->Read(&_settings_game); } -/* static */ bool ScriptGameSettings::SetValue(const char *setting, int value) +/* static */ bool ScriptGameSettings::SetValue(const char *setting, SQInteger value) { + EnforceDeityOrCompanyModeValid(false); if (!IsValid(setting)) return false; const SettingDesc *sd = GetSettingFromName(setting); + assert(sd != nullptr); if ((sd->flags & SF_NO_NETWORK_SYNC) != 0) return false; + value = Clamp(value, INT32_MIN, INT32_MAX); + return ScriptObject::Command::Do(sd->GetName(), value); } diff --git a/src/script/api/script_gamesettings.hpp b/src/script/api/script_gamesettings.hpp index 14b30e5c4d4ca..a2d238c82abb7 100644 --- a/src/script/api/script_gamesettings.hpp +++ b/src/script/api/script_gamesettings.hpp @@ -57,18 +57,19 @@ class ScriptGameSettings : public ScriptObject { * @note Results achieved in the past offer no guarantee for the future. * @return The value for the setting. */ - static int32 GetValue(const char *setting); + static SQInteger GetValue(const char *setting); /** * Sets the value of the game setting. * @param setting The setting to set the value of. * @param value The value to set the setting to. + * The value will be clamped to MIN(int32) .. MAX(int32). * @pre IsValid(setting). * @return True if the action succeeded. * @note Results achieved in the past offer no guarantee for the future. * @api -ai */ - static bool SetValue(const char *setting, int value); + static bool SetValue(const char *setting, SQInteger value); /** * Checks whether the given vehicle-type is disabled for companies. diff --git a/src/script/api/script_goal.cpp b/src/script/api/script_goal.cpp index 70f040dd4542e..ad36c728b9285 100644 --- a/src/script/api/script_goal.cpp +++ b/src/script/api/script_goal.cpp @@ -28,13 +28,13 @@ return ::Goal::IsValidID(goal_id); } -/* static */ ScriptGoal::GoalID ScriptGoal::New(ScriptCompany::CompanyID company, Text *goal, GoalType type, uint32 destination) +/* static */ ScriptGoal::GoalID ScriptGoal::New(ScriptCompany::CompanyID company, Text *goal, GoalType type, SQInteger destination) { CCountedPtr counter(goal); - EnforcePrecondition(GOAL_INVALID, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(GOAL_INVALID); EnforcePrecondition(GOAL_INVALID, goal != nullptr); - const char *text = goal->GetEncodedText(); + const std::string &text = goal->GetEncodedText(); EnforcePreconditionEncodedText(GOAL_INVALID, text); EnforcePrecondition(GOAL_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID); @@ -58,7 +58,7 @@ /* static */ bool ScriptGoal::Remove(GoalID goal_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, IsValidGoal(goal_id)); return ScriptObject::Command::Do(goal_id); @@ -69,11 +69,12 @@ CCountedPtr counter(goal); EnforcePrecondition(false, IsValidGoal(goal_id)); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, goal != nullptr); - EnforcePrecondition(false, !StrEmpty(goal->GetEncodedText())); + const std::string &text = goal->GetEncodedText(); + EnforcePreconditionEncodedText(false, text); - return ScriptObject::Command::Do(goal_id, goal->GetEncodedText()); + return ScriptObject::Command::Do(goal_id, text); } /* static */ bool ScriptGoal::SetProgress(GoalID goal_id, Text *progress) @@ -81,20 +82,15 @@ CCountedPtr counter(progress); EnforcePrecondition(false, IsValidGoal(goal_id)); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - - /* Ensure null as used for empty string. */ - if (progress != nullptr && StrEmpty(progress->GetEncodedText())) { - progress = nullptr; - } + EnforceDeityMode(false); - return ScriptObject::Command::Do(goal_id, progress != nullptr ? std::string{ progress->GetEncodedText() } : std::string{}); + return ScriptObject::Command::Do(goal_id, progress != nullptr ? progress->GetEncodedText() : std::string{}); } /* static */ bool ScriptGoal::SetCompleted(GoalID goal_id, bool completed) { EnforcePrecondition(false, IsValidGoal(goal_id)); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); return ScriptObject::Command::Do(goal_id, completed); } @@ -102,29 +98,30 @@ /* static */ bool ScriptGoal::IsCompleted(GoalID goal_id) { EnforcePrecondition(false, IsValidGoal(goal_id)); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); Goal *g = Goal::Get(goal_id); return g != nullptr && g->completed; } -/* static */ bool ScriptGoal::DoQuestion(uint16 uniqueid, uint32 target, bool is_client, Text *question, QuestionType type, uint32 buttons) +/* static */ bool ScriptGoal::DoQuestion(SQInteger uniqueid, uint32 target, bool is_client, Text *question, QuestionType type, SQInteger buttons) { CCountedPtr counter(question); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, question != nullptr); - const char *text = question->GetEncodedText(); + const std::string &text = question->GetEncodedText(); EnforcePreconditionEncodedText(false, text); uint min_buttons = (type == QT_QUESTION ? 1 : 0); EnforcePrecondition(false, CountBits(buttons) >= min_buttons && CountBits(buttons) <= 3); - EnforcePrecondition(false, buttons < (1 << ::GOAL_QUESTION_BUTTON_COUNT)); + EnforcePrecondition(false, buttons >= 0 && buttons < (1 << ::GOAL_QUESTION_BUTTON_COUNT)); EnforcePrecondition(false, (int)type < ::GQT_END); + EnforcePrecondition(false, uniqueid >= 0 && uniqueid <= UINT16_MAX); return ScriptObject::Command::Do(uniqueid, target, is_client, buttons, (::GoalQuestionType)type, text); } -/* static */ bool ScriptGoal::Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons) +/* static */ bool ScriptGoal::Question(SQInteger uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, SQInteger buttons) { EnforcePrecondition(false, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID); uint8 c = company; @@ -133,18 +130,17 @@ return DoQuestion(uniqueid, c, false, question, type, buttons); } -/* static */ bool ScriptGoal::QuestionClient(uint16 uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, int buttons) +/* static */ bool ScriptGoal::QuestionClient(SQInteger uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, SQInteger buttons) { EnforcePrecondition(false, ScriptGame::IsMultiplayer()); EnforcePrecondition(false, ScriptClient::ResolveClientID(client) != ScriptClient::CLIENT_INVALID); - /* Can only send 16 bits of client_id before proper fix is implemented */ - EnforcePrecondition(false, client < (1 << 16)); return DoQuestion(uniqueid, client, true, question, type, buttons); } -/* static */ bool ScriptGoal::CloseQuestion(uint16 uniqueid) +/* static */ bool ScriptGoal::CloseQuestion(SQInteger uniqueid) { - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); + EnforcePrecondition(false, uniqueid >= 0 && uniqueid <= UINT16_MAX); return ScriptObject::Command::Do(uniqueid, 0); } diff --git a/src/script/api/script_goal.hpp b/src/script/api/script_goal.hpp index 2261dcc00f147..c3b1ad2b29937 100644 --- a/src/script/api/script_goal.hpp +++ b/src/script/api/script_goal.hpp @@ -28,9 +28,9 @@ class ScriptGoal : public ScriptObject { /** * The goal IDs. */ - enum GoalID { + enum GoalID : uint16 { /* Note: these values represent part of the in-game GoalID enum */ - GOAL_INVALID = ::INVALID_GOALTYPE, ///< An invalid goal id. + GOAL_INVALID = ::INVALID_GOAL, ///< An invalid goal id. }; /** @@ -96,20 +96,20 @@ class ScriptGoal : public ScriptObject { * @param type The type of the goal. * @param destination The destination of the \a type type. * @return The new GoalID, or GOAL_INVALID if it failed. - * @pre No ScriptCompanyMode may be in scope. - * @pre goal != nullptr && len(goal) != 0. + * @pre ScriptCompanyMode::IsDeity(). + * @pre goal != null && len(goal) != 0. * @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID. * @pre if type is GT_STORY_PAGE, the company of the goal and the company of the story page need to match: * \li Global goals can only reference global story pages. * \li Company specific goals can reference global story pages and story pages of the same company. */ - static GoalID New(ScriptCompany::CompanyID company, Text *goal, GoalType type, uint32 destination); + static GoalID New(ScriptCompany::CompanyID company, Text *goal, GoalType type, SQInteger destination); /** * Remove a goal from the list. * @param goal_id The goal to remove. * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidGoal(goal_id). */ static bool Remove(GoalID goal_id); @@ -119,8 +119,8 @@ class ScriptGoal : public ScriptObject { * @param goal_id The goal to update. * @param goal The new goal text (can be either a raw string, or a ScriptText object). * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. - * @pre goal != nullptr && len(goal) != 0. + * @pre ScriptCompanyMode::IsDeity(). + * @pre goal != null && len(goal) != 0. * @pre IsValidGoal(goal_id). */ static bool SetText(GoalID goal_id, Text *goal); @@ -131,10 +131,10 @@ class ScriptGoal : public ScriptObject { * the progress string short. * @param goal_id The goal to update. * @param progress The new progress text for the goal (can be either a raw string, - * or a ScriptText object). To clear the progress string you can pass nullptr or an + * or a ScriptText object). To clear the progress string you can pass null or an * empty string. * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidGoal(goal_id). */ static bool SetProgress(GoalID goal_id, Text *progress); @@ -144,7 +144,7 @@ class ScriptGoal : public ScriptObject { * @param goal_id The goal to update. * @param complete The new goal completed status. * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidGoal(goal_id). */ static bool SetCompleted(GoalID goal_id, bool complete); @@ -153,7 +153,7 @@ class ScriptGoal : public ScriptObject { * Checks if a given goal have been marked as completed. * @param goal_id The goal to check complete status. * @return True if the goal is completed, otherwise false. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidGoal(goal_id). */ static bool IsCompleted(GoalID goal_id); @@ -166,14 +166,15 @@ class ScriptGoal : public ScriptObject { * @param type The type of question that is being asked. * @param buttons Any combinations (at least 1, up to 3) of buttons defined in QuestionButton. Like BUTTON_YES + BUTTON_NO. * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. - * @pre question != nullptr && len(question) != 0. + * @pre ScriptCompanyMode::IsDeity(). + * @pre question != null && len(question) != 0. * @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID. * @pre CountBits(buttons) >= 1 && CountBits(buttons) <= 3. - * @note Replies to the question are given by you via the event ScriptEvent_GoalQuestionAnswer. + * @pre uniqueid >= 0 && uniqueid <= MAX(uint16) + * @note Replies to the question are given by you via the event ScriptEventGoalQuestionAnswer. * @note There is no guarantee you ever get a reply on your question. */ - static bool Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons); + static bool Question(SQInteger uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, SQInteger buttons); /** * Ask client a question. @@ -183,33 +184,35 @@ class ScriptGoal : public ScriptObject { * @param type The type of question that is being asked. * @param buttons Any combinations (at least 1, up to 3) of buttons defined in QuestionButton. Like BUTTON_YES + BUTTON_NO. * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre ScriptGame::IsMultiplayer() - * @pre question != nullptr && len(question) != 0. + * @pre question != null && len(question) != 0. * @pre ResolveClientID(client) != CLIENT_INVALID. * @pre CountBits(buttons) >= 1 && CountBits(buttons) <= 3. - * @note Replies to the question are given by you via the event ScriptEvent_GoalQuestionAnswer. + * @pre uniqueid >= 0 && uniqueid <= MAX(uint16) + * @note Replies to the question are given by you via the event ScriptEventGoalQuestionAnswer. * @note There is no guarantee you ever get a reply on your question. */ - static bool QuestionClient(uint16 uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, int buttons); + static bool QuestionClient(SQInteger uniqueid, ScriptClient::ClientID client, Text *question, QuestionType type, SQInteger buttons); /** * Close the question on all clients. * @param uniqueid The uniqueid of the question you want to close. * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). + * @pre uniqueid >= 0 && uniqueid <= MAX(uint16) * @note If you send a question to a single company, and get a reply for them, * the question is already closed on all clients. Only use this function if * you want to timeout a question, or if you send the question to all * companies, but you are only interested in the reply of the first. */ - static bool CloseQuestion(uint16 uniqueid); + static bool CloseQuestion(SQInteger uniqueid); protected: /** * Does common checks and asks the question. */ - static bool DoQuestion(uint16 uniqueid, uint32 target, bool is_client, Text *question, QuestionType type, uint32 buttons); + static bool DoQuestion(SQInteger uniqueid, uint32 target, bool is_client, Text *question, QuestionType type, SQInteger buttons); }; #endif /* SCRIPT_GOAL_HPP */ diff --git a/src/script/api/script_group.cpp b/src/script/api/script_group.cpp index dbf4c0280e064..1f83c55d0c080 100644 --- a/src/script/api/script_group.cpp +++ b/src/script/api/script_group.cpp @@ -25,12 +25,14 @@ /* static */ bool ScriptGroup::IsValidGroup(GroupID group_id) { + EnforceDeityOrCompanyModeValid(false); const Group *g = ::Group::GetIfValid(group_id); return g != nullptr && g->owner == ScriptObject::GetCompany(); } /* static */ ScriptGroup::GroupID ScriptGroup::CreateGroup(ScriptVehicle::VehicleType vehicle_type, GroupID parent_group_id) { + EnforceCompanyModeValid(GROUP_INVALID); if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnGroupID, (::VehicleType)vehicle_type, parent_group_id)) return GROUP_INVALID; /* In case of test-mode, we return GroupID 0 */ @@ -39,6 +41,7 @@ /* static */ bool ScriptGroup::DeleteGroup(GroupID group_id) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidGroup(group_id)); return ScriptObject::Command::Do(group_id); @@ -55,9 +58,10 @@ { CCountedPtr counter(name); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidGroup(group_id)); EnforcePrecondition(false, name != nullptr); - const char *text = name->GetDecodedText(); + const std::string &text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_GROUP_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -74,6 +78,7 @@ /* static */ bool ScriptGroup::SetParent(GroupID group_id, GroupID parent_group_id) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidGroup(group_id)); EnforcePrecondition(false, IsValidGroup(parent_group_id)); @@ -90,6 +95,7 @@ /* static */ bool ScriptGroup::EnableAutoReplaceProtection(GroupID group_id, bool enable) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidGroup(group_id)); return ScriptObject::Command::Do(group_id, GroupFlags::GF_REPLACE_PROTECTION, enable, false); @@ -102,15 +108,17 @@ return HasBit(::Group::Get(group_id)->flags, GroupFlags::GF_REPLACE_PROTECTION); } -/* static */ int32 ScriptGroup::GetNumEngines(GroupID group_id, EngineID engine_id) +/* static */ SQInteger ScriptGroup::GetNumEngines(GroupID group_id, EngineID engine_id) { + EnforceCompanyModeValid(-1); if (!IsValidGroup(group_id) && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return -1; return GetGroupNumEngines(ScriptObject::GetCompany(), group_id, engine_id); } -/* static */ int32 ScriptGroup::GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type) +/* static */ SQInteger ScriptGroup::GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type) { + EnforceCompanyModeValid(-1); bool valid_group = IsValidGroup(group_id); if (!valid_group && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return -1; if (!valid_group && (vehicle_type < ScriptVehicle::VT_RAIL || vehicle_type > ScriptVehicle::VT_AIR)) return -1; @@ -120,14 +128,16 @@ /* static */ bool ScriptGroup::MoveVehicle(GroupID group_id, VehicleID vehicle_id) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT); - EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); + EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id)); return ScriptObject::Command::Do(group_id, vehicle_id, false); } /* static */ bool ScriptGroup::EnableWagonRemoval(bool enable_removal) { + EnforceCompanyModeValid(false); if (HasWagonRemoval() == enable_removal) return true; return ScriptObject::Command::Do("company.renew_keep_length", enable_removal ? 1 : 0); @@ -135,11 +145,13 @@ /* static */ bool ScriptGroup::HasWagonRemoval() { + EnforceCompanyModeValid(false); return ::Company::Get(ScriptObject::GetCompany())->settings.renew_keep_length; } /* static */ bool ScriptGroup::SetAutoReplace(GroupID group_id, EngineID engine_id_old, EngineID engine_id_new) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL); EnforcePrecondition(false, ScriptEngine::IsBuildable(engine_id_new)); @@ -148,6 +160,7 @@ /* static */ EngineID ScriptGroup::GetEngineReplacement(GroupID group_id, EngineID engine_id) { + EnforceCompanyModeValid(::INVALID_ENGINE); if (!IsValidGroup(group_id) && group_id != GROUP_DEFAULT && group_id != GROUP_ALL) return ::INVALID_ENGINE; return ::EngineReplacementForCompany(Company::Get(ScriptObject::GetCompany()), engine_id, group_id); @@ -155,6 +168,7 @@ /* static */ bool ScriptGroup::StopAutoReplace(GroupID group_id, EngineID engine_id) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL); return ScriptObject::Command::Do(group_id, engine_id, ::INVALID_ENGINE, false); @@ -183,7 +197,7 @@ return ::Group::Get(group_id)->statistics.profit_last_year; } -/* static */ uint32 ScriptGroup::GetCurrentUsage(GroupID group_id) +/* static */ SQInteger ScriptGroup::GetCurrentUsage(GroupID group_id) { if (!IsValidGroup(group_id)) return -1; @@ -205,6 +219,7 @@ /* static */ bool ScriptGroup::SetPrimaryColour(GroupID group_id, ScriptCompany::Colours colour) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidGroup(group_id)); return ScriptObject::Command::Do(group_id, true, (::Colours)colour); @@ -212,6 +227,7 @@ /* static */ bool ScriptGroup::SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidGroup(group_id)); return ScriptObject::Command::Do(group_id, false, (::Colours)colour); diff --git a/src/script/api/script_group.hpp b/src/script/api/script_group.hpp index 384fea7a28425..c685813a88a3f 100644 --- a/src/script/api/script_group.hpp +++ b/src/script/api/script_group.hpp @@ -41,6 +41,7 @@ class ScriptGroup : public ScriptObject { * Create a new group. * @param vehicle_type The type of vehicle to create a group for. * @param parent_group_id The parent group id to create this group under, INVALID_GROUP for top-level. + * @game @pre ScriptCompanyMode::IsValid(). * @return The GroupID of the new group, or an invalid GroupID when * it failed. Check the return value using IsValidGroup(). In test-mode * 0 is returned if it was successful; any other value indicates failure. @@ -52,6 +53,7 @@ class ScriptGroup : public ScriptObject { * given group will move to the GROUP_DEFAULT. * @param group_id The group to delete. * @pre IsValidGroup(group_id). + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and only if the group was successfully deleted. */ static bool DeleteGroup(GroupID group_id); @@ -69,7 +71,8 @@ class ScriptGroup : public ScriptObject { * @param group_id The group to set the name for. * @param name The name for the group (can be either a raw string, or a ScriptText object). * @pre IsValidGroup(group_id). - * @pre name != nullptr && len(name) != 0 + * @pre name != null && len(name) != 0 + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE * @return True if and only if the name was changed. */ @@ -89,6 +92,7 @@ class ScriptGroup : public ScriptObject { * @param parent_group_id The parent group to set. * @pre IsValidGroup(group_id). * @pre IsValidGroup(parent_group_id). + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and only if the parent group was changed. */ static bool SetParent(GroupID group_id, GroupID parent_group_id); @@ -107,6 +111,7 @@ class ScriptGroup : public ScriptObject { * @param group_id The group to change the protection for. * @param enable True if protection should be enabled. * @pre IsValidGroup(group_id). + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and only if the protection was successfully changed. */ static bool EnableAutoReplaceProtection(GroupID group_id, bool enable); @@ -124,9 +129,10 @@ class ScriptGroup : public ScriptObject { * @param group_id The group to get the number of engines in. * @param engine_id The engine id to count. * @pre IsValidGroup(group_id) || group_id == GROUP_ALL || group_id == GROUP_DEFAULT. + * @game @pre ScriptCompanyMode::IsValid(). * @return The number of engines with id engine_id in the group with id group_id. */ - static int32 GetNumEngines(GroupID group_id, EngineID engine_id); + static SQInteger GetNumEngines(GroupID group_id, EngineID engine_id); /** * Get the total number of vehicles in a given group and its sub-groups. @@ -135,19 +141,21 @@ class ScriptGroup : public ScriptObject { * @pre IsValidGroup(group_id) || group_id == GROUP_ALL || group_id == GROUP_DEFAULT. * @pre IsValidGroup(group_id) || vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || * vehicle_type == ScriptVehicle::VT_WATER || vehicle_type == ScriptVehicle::VT_AIR + * @game @pre ScriptCompanyMode::IsValid(). * @return The total number of vehicles in the group with id group_id and it's sub-groups. * @note If the group is valid (neither GROUP_ALL nor GROUP_DEFAULT), the value of * vehicle_type is retrieved from the group itself and not from the input value. * But if the group is GROUP_ALL or GROUP_DEFAULT, then vehicle_type must be valid. */ - static int32 GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type); + static SQInteger GetNumVehicles(GroupID group_id, ScriptVehicle::VehicleType vehicle_type); /** * Move a vehicle to a group. * @param group_id The group to move the vehicle to. * @param vehicle_id The vehicle to move to the group. * @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT. - * @pre ScriptVehicle::IsValidVehicle(vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id). + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and only if the vehicle was successfully moved to the group. * @note A vehicle can be in only one group at the same time. To remove it from * a group, move it to another or to GROUP_DEFAULT. Moving the vehicle to the @@ -161,12 +169,14 @@ class ScriptGroup : public ScriptObject { * If enabled, wagons are removed from the end of the vehicle until it * fits in the same number of tiles as it did before. * @param keep_length If true, wagons will be removed if the new engine is longer. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and only if the value was successfully changed. */ static bool EnableWagonRemoval(bool keep_length); /** * Get the current status of wagon removal. + * @game @pre ScriptCompanyMode::IsValid(). * @return Whether or not wagon removal is enabled. */ static bool HasWagonRemoval(); @@ -179,6 +189,7 @@ class ScriptGroup : public ScriptObject { * @param engine_id_new The engine id to replace with. * @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL. * @pre ScriptEngine.IsBuildable(engine_id_new). + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and if the replacing was successfully started. * @note To stop autoreplacing engine_id_old, call StopAutoReplace(group_id, engine_id_old). */ @@ -189,6 +200,7 @@ class ScriptGroup : public ScriptObject { * @param group_id The group to get the replacement from. * @param engine_id The engine that is being replaced. * @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL. + * @game @pre ScriptCompanyMode::IsValid(). * @return The EngineID that is replacing engine_id or an invalid EngineID * in case engine_id is not begin replaced. */ @@ -199,6 +211,7 @@ class ScriptGroup : public ScriptObject { * @param group_id The group to stop replacing the engine in. * @param engine_id The engine id to stop replacing with another engine. * @pre IsValidGroup(group_id) || group_id == GROUP_DEFAULT || group_id == GROUP_ALL. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and if the replacing was successfully stopped. */ static bool StopAutoReplace(GroupID group_id, EngineID engine_id); @@ -225,13 +238,15 @@ class ScriptGroup : public ScriptObject { * @pre IsValidGroup(group_id). * @return The current usage of the group. */ - static uint32 GetCurrentUsage(GroupID group_id); + static SQInteger GetCurrentUsage(GroupID group_id); /** * Set primary colour for a group. * @param group_id The group id to set the colour of. * @param colour Colour to set. * @pre IsValidGroup(group_id). + * @game @pre ScriptCompanyMode::IsValid(). + * @return True iff the colour was set successfully. */ static bool SetPrimaryColour(GroupID group_id, ScriptCompany::Colours colour); @@ -240,6 +255,8 @@ class ScriptGroup : public ScriptObject { * @param group_id The group id to set the colour of. * @param colour Colour to set. * @pre IsValidGroup(group_id). + * @game @pre ScriptCompanyMode::IsValid(). + * @return True iff the colour was set successfully. */ static bool SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour); @@ -247,6 +264,7 @@ class ScriptGroup : public ScriptObject { * Get primary colour of a group. * @param group_id The group id to get the colour of. * @pre IsValidGroup(group_id). + * @return The primary colour of the group. */ static ScriptCompany::Colours GetPrimaryColour(GroupID group_id); @@ -254,6 +272,7 @@ class ScriptGroup : public ScriptObject { * Get secondary colour for a group. * @param group_id The group id to get the colour of. * @pre IsValidGroup(group_id). + * @return The secondary colour of the group. */ static ScriptCompany::Colours GetSecondaryColour(GroupID group_id); }; diff --git a/src/script/api/script_grouplist.cpp b/src/script/api/script_grouplist.cpp index 569b44634cc0a..11099ca67e1bf 100644 --- a/src/script/api/script_grouplist.cpp +++ b/src/script/api/script_grouplist.cpp @@ -9,12 +9,14 @@ #include "../../stdafx.h" #include "script_grouplist.hpp" +#include "script_error.hpp" #include "../../group.h" #include "../../safeguards.h" ScriptGroupList::ScriptGroupList() { + EnforceDeityOrCompanyModeValid_Void(); for (const Group *g : Group::Iterate()) { if (g->owner == ScriptObject::GetCompany()) this->AddItem(g->index); } diff --git a/src/script/api/script_industry.cpp b/src/script/api/script_industry.cpp index ca0eaafc436c5..1f114c1c454b6 100644 --- a/src/script/api/script_industry.cpp +++ b/src/script/api/script_industry.cpp @@ -25,9 +25,9 @@ #include "../../safeguards.h" -/* static */ int32 ScriptIndustry::GetIndustryCount() +/* static */ SQInteger ScriptIndustry::GetIndustryCount() { - return (int32)::Industry::GetNumItems(); + return ::Industry::GetNumItems(); } /* static */ bool ScriptIndustry::IsValidIndustry(IndustryID industry_id) @@ -53,14 +53,10 @@ { CCountedPtr counter(text); - const char *encoded_text = nullptr; - if (text != nullptr) { - encoded_text = text->GetEncodedText(); - EnforcePreconditionEncodedText(false, encoded_text); - } + EnforceDeityMode(false); EnforcePrecondition(false, IsValidIndustry(industry_id)); - return ScriptObject::Command::Do(industry_id, IndustryAction::SetText, INDCTL_NONE, INVALID_OWNER, std::string{ encoded_text ? encoded_text : "" }); + return ScriptObject::Command::Do(industry_id, text != nullptr ? text->GetEncodedText() : std::string{}); } /* static */ ScriptIndustry::CargoAcceptState ScriptIndustry::IsCargoAccepted(IndustryID industry_id, CargoID cargo_id) @@ -80,7 +76,7 @@ return CAS_NOT_ACCEPTED; } -/* static */ int32 ScriptIndustry::GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id) +/* static */ SQInteger ScriptIndustry::GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id) { if (!IsValidIndustry(industry_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo_id)) return -1; @@ -96,7 +92,7 @@ return -1; } -/* static */ int32 ScriptIndustry::GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id) +/* static */ SQInteger ScriptIndustry::GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id) { if (!IsValidIndustry(industry_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo_id)) return -1; @@ -110,7 +106,7 @@ return -1; } -/* static */ int32 ScriptIndustry::GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id) +/* static */ SQInteger ScriptIndustry::GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id) { if (!IsValidIndustry(industry_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo_id)) return -1; @@ -124,7 +120,7 @@ return -1; } -/* static */ int32 ScriptIndustry::GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id) +/* static */ SQInteger ScriptIndustry::GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id) { if (!IsValidIndustry(industry_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo_id)) return -1; @@ -145,22 +141,22 @@ return ::Industry::Get(industry_id)->location.tile; } -/* static */ int32 ScriptIndustry::GetAmountOfStationsAround(IndustryID industry_id) +/* static */ SQInteger ScriptIndustry::GetAmountOfStationsAround(IndustryID industry_id) { if (!IsValidIndustry(industry_id)) return -1; Industry *ind = ::Industry::Get(industry_id); - return (int32)ind->stations_near.size(); + return ind->stations_near.size(); } -/* static */ int32 ScriptIndustry::GetDistanceManhattanToTile(IndustryID industry_id, TileIndex tile) +/* static */ SQInteger ScriptIndustry::GetDistanceManhattanToTile(IndustryID industry_id, TileIndex tile) { if (!IsValidIndustry(industry_id)) return -1; return ScriptMap::DistanceManhattan(tile, GetLocation(industry_id)); } -/* static */ int32 ScriptIndustry::GetDistanceSquareToTile(IndustryID industry_id, TileIndex tile) +/* static */ SQInteger ScriptIndustry::GetDistanceSquareToTile(IndustryID industry_id, TileIndex tile) { if (!IsValidIndustry(industry_id)) return -1; @@ -225,14 +221,14 @@ return ::Industry::Get(industry_id)->type; } -int32 ScriptIndustry::GetLastProductionYear(IndustryID industry_id) +/* static */ SQInteger ScriptIndustry::GetLastProductionYear(IndustryID industry_id) { Industry *i = Industry::GetIfValid(industry_id); if (i == nullptr) return 0; return i->last_prod_year; } -ScriptDate::Date ScriptIndustry::GetCargoLastAcceptedDate(IndustryID industry_id, CargoID cargo_type) +/* static */ ScriptDate::Date ScriptIndustry::GetCargoLastAcceptedDate(IndustryID industry_id, CargoID cargo_type) { Industry *i = Industry::GetIfValid(industry_id); if (i == nullptr) return ScriptDate::DATE_INVALID; @@ -246,19 +242,19 @@ ScriptDate::Date ScriptIndustry::GetCargoLastAcceptedDate(IndustryID industry_id } } -uint32 ScriptIndustry::GetControlFlags(IndustryID industry_id) +/* static */ SQInteger ScriptIndustry::GetControlFlags(IndustryID industry_id) { Industry *i = Industry::GetIfValid(industry_id); if (i == nullptr) return 0; return i->ctlflags; } -bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flags) +/* static */ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, SQInteger control_flags) { - if (ScriptObject::GetCompany() != OWNER_DEITY) return false; + EnforceDeityMode(false); if (!IsValidIndustry(industry_id)) return false; - return ScriptObject::Command::Do(industry_id, IndustryAction::SetControlFlags, (::IndustryControlFlags)control_flags & ::INDCTL_MASK, INVALID_OWNER, {}); + return ScriptObject::Command::Do(industry_id, (::IndustryControlFlags)control_flags & ::INDCTL_MASK); } /* static */ ScriptCompany::CompanyID ScriptIndustry::GetExclusiveSupplier(IndustryID industry_id) @@ -273,11 +269,12 @@ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flag /* static */ bool ScriptIndustry::SetExclusiveSupplier(IndustryID industry_id, ScriptCompany::CompanyID company_id) { + EnforceDeityMode(false); EnforcePrecondition(false, IsValidIndustry(industry_id)); auto company = ScriptCompany::ResolveCompanyID(company_id); ::Owner owner = (company == ScriptCompany::COMPANY_INVALID ? ::INVALID_OWNER : (::Owner)company); - return ScriptObject::Command::Do(industry_id, IndustryAction::SetExclusiveSupplier, INDCTL_NONE, owner, {}); + return ScriptObject::Command::Do(industry_id, owner, false); } /* static */ ScriptCompany::CompanyID ScriptIndustry::GetExclusiveConsumer(IndustryID industry_id) @@ -292,9 +289,10 @@ bool ScriptIndustry::SetControlFlags(IndustryID industry_id, uint32 control_flag /* static */ bool ScriptIndustry::SetExclusiveConsumer(IndustryID industry_id, ScriptCompany::CompanyID company_id) { + EnforceDeityMode(false); EnforcePrecondition(false, IsValidIndustry(industry_id)); auto company = ScriptCompany::ResolveCompanyID(company_id); ::Owner owner = (company == ScriptCompany::COMPANY_INVALID ? ::INVALID_OWNER : (::Owner)company); - return ScriptObject::Command::Do(industry_id, IndustryAction::SetExclusiveConsumer, INDCTL_NONE, owner, {}); + return ScriptObject::Command::Do(industry_id, owner, true); } diff --git a/src/script/api/script_industry.hpp b/src/script/api/script_industry.hpp index 95133da0ec7d0..d7fca868d0051 100644 --- a/src/script/api/script_industry.hpp +++ b/src/script/api/script_industry.hpp @@ -54,7 +54,7 @@ class ScriptIndustry : public ScriptObject { * @return The number of industries. * @note The maximum valid IndustryID can be higher than the value returned. */ - static int32 GetIndustryCount(); + static SQInteger GetIndustryCount(); /** * Checks whether the given industry index is valid. @@ -84,7 +84,8 @@ class ScriptIndustry : public ScriptObject { /** * Set the custom text of an industry, shown in the GUI. * @param industry_id The industry to set the custom text of. - * @param text The text to set it to (can be either a raw string, or a ScriptText object). If null is passed, the text will be removed. + * @param text The text to set it to (can be either a raw string, or a ScriptText object). If null, or an empty string, is passed, the text will be removed. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidIndustry(industry_id). * @return True if the action succeeded. * @api -ai @@ -109,7 +110,7 @@ class ScriptIndustry : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo_id). * @return The amount of cargo that is waiting for processing. */ - static int32 GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id); + static SQInteger GetStockpiledCargo(IndustryID industry_id, CargoID cargo_id); /** * Get the total last month's production of the given cargo at an industry. @@ -119,7 +120,7 @@ class ScriptIndustry : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo_id). * @return The last month's production of the given cargo for this industry. */ - static int32 GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id); + static SQInteger GetLastMonthProduction(IndustryID industry_id, CargoID cargo_id); /** * Get the total amount of cargo transported from an industry last month. @@ -129,7 +130,7 @@ class ScriptIndustry : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo_id). * @return The amount of given cargo transported from this industry last month. */ - static int32 GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id); + static SQInteger GetLastMonthTransported(IndustryID industry_id, CargoID cargo_id); /** * Get the percentage of cargo transported from an industry last month. @@ -139,7 +140,7 @@ class ScriptIndustry : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo_id). * @return The percentage of given cargo transported from this industry last month. */ - static int32 GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id); + static SQInteger GetLastMonthTransportedPercentage(IndustryID industry_id, CargoID cargo_id); /** * Gets the location of the industry. @@ -157,7 +158,7 @@ class ScriptIndustry : public ScriptObject { * @pre IsValidIndustry(industry_id). * @return The number of stations around an industry. */ - static int32 GetAmountOfStationsAround(IndustryID industry_id); + static SQInteger GetAmountOfStationsAround(IndustryID industry_id); /** * Get the manhattan distance from the tile to the ScriptIndustry::GetLocation() @@ -168,7 +169,7 @@ class ScriptIndustry : public ScriptObject { * @pre ScriptMap::IsValidTile(tile). * @return The distance between industry and tile. */ - static int32 GetDistanceManhattanToTile(IndustryID industry_id, TileIndex tile); + static SQInteger GetDistanceManhattanToTile(IndustryID industry_id, TileIndex tile); /** * Get the square distance from the tile to the ScriptIndustry::GetLocation() @@ -179,7 +180,7 @@ class ScriptIndustry : public ScriptObject { * @pre ScriptMap::IsValidTile(tile). * @return The distance between industry and tile. */ - static int32 GetDistanceSquareToTile(IndustryID industry_id, TileIndex tile); + static SQInteger GetDistanceSquareToTile(IndustryID industry_id, TileIndex tile); /** * Is this industry built on water. @@ -238,7 +239,7 @@ class ScriptIndustry : public ScriptObject { * @return Year the industry last had production, 0 if error. * @api -ai */ - static int32 GetLastProductionYear(IndustryID industry_id); + static SQInteger GetLastProductionYear(IndustryID industry_id); /** * Get the last date this industry accepted any cargo delivery. @@ -258,18 +259,18 @@ class ScriptIndustry : public ScriptObject { * @return Bit flags of the IndustryControlFlags enumeration. * @api -ai */ - static uint32 GetControlFlags(IndustryID industry_id); + static SQInteger GetControlFlags(IndustryID industry_id); /** * Change the control flags for an industry. * @param industry_id The index of the industry. * @param control_flags New flags as a combination of IndustryControlFlags values. * @pre IsValidIndustry(industry_id). - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @return True if the action succeeded. * @api -ai */ - static bool SetControlFlags(IndustryID industry_id, uint32 control_flags); + static bool SetControlFlags(IndustryID industry_id, SQInteger control_flags); /** * Find out which company currently has the exclusive rights to deliver cargo to the industry. @@ -286,6 +287,7 @@ class ScriptIndustry : public ScriptObject { * @param industry_id The index of the industry. * @param company_id The company to set (ScriptCompany::COMPANY_INVALID to reset). * @pre IsValidIndustry(industry_id). + * @pre ScriptCompanyMode::IsDeity(). * @return True if the action succeeded. * @api -ai */ @@ -306,6 +308,7 @@ class ScriptIndustry : public ScriptObject { * @param industry_id The index of the industry. * @param company_id The company to set (ScriptCompany::COMPANY_INVALID to reset). * @pre IsValidIndustry(industry_id). + * @pre ScriptCompanyMode::IsDeity(). * @return True if the action succeeded. * @api -ai */ diff --git a/src/script/api/script_industrytype.cpp b/src/script/api/script_industrytype.cpp index 14b9a3f67acaf..3d7073e40b4ba 100644 --- a/src/script/api/script_industrytype.cpp +++ b/src/script/api/script_industrytype.cpp @@ -9,6 +9,7 @@ #include "../../stdafx.h" #include "script_industrytype.hpp" +#include "script_base.hpp" #include "script_map.hpp" #include "script_error.hpp" #include "../../strings_func.h" @@ -95,7 +96,7 @@ { if (!IsValidIndustryType(industry_type)) return false; - const bool deity = ScriptObject::GetCompany() == OWNER_DEITY; + const bool deity = ScriptCompanyMode::IsDeity(); if (::GetIndustryProbabilityCallback(industry_type, deity ? IACT_RANDOMCREATION : IACT_USERCREATION, 1) == 0) return false; if (deity) return true; if (!::GetIndustrySpec(industry_type)->IsRawIndustry()) return true; @@ -108,7 +109,7 @@ { if (!IsValidIndustryType(industry_type)) return false; - const bool deity = ScriptObject::GetCompany() == OWNER_DEITY; + const bool deity = ScriptCompanyMode::IsDeity(); if (!deity && !::GetIndustrySpec(industry_type)->IsRawIndustry()) return false; if (::GetIndustryProbabilityCallback(industry_type, deity ? IACT_RANDOMCREATION : IACT_USERCREATION, 1) == 0) return false; @@ -118,19 +119,21 @@ /* static */ bool ScriptIndustryType::BuildIndustry(IndustryType industry_type, TileIndex tile) { + EnforceDeityOrCompanyModeValid(false); EnforcePrecondition(false, CanBuildIndustry(industry_type)); EnforcePrecondition(false, ScriptMap::IsValidTile(tile)); - uint32 seed = ::InteractiveRandom(); - uint32 layout_index = ::InteractiveRandomRange((uint32)::GetIndustrySpec(industry_type)->layouts.size()); + uint32 seed = ScriptBase::Rand(); + uint32 layout_index = ScriptBase::RandRange((uint32)::GetIndustrySpec(industry_type)->layouts.size()); return ScriptObject::Command::Do(tile, industry_type, layout_index, true, seed); } /* static */ bool ScriptIndustryType::ProspectIndustry(IndustryType industry_type) { + EnforceDeityOrCompanyModeValid(false); EnforcePrecondition(false, CanProspectIndustry(industry_type)); - uint32 seed = ::InteractiveRandom(); + uint32 seed = ScriptBase::Rand(); return ScriptObject::Command::Do(0, industry_type, 0, false, seed); } @@ -155,10 +158,10 @@ return (::GetIndustrySpec(industry_type)->behaviour & INDUSTRYBEH_AI_AIRSHIP_ROUTES) != 0; } -/* static */ IndustryType ScriptIndustryType::ResolveNewGRFID(uint32 grfid, uint16 grf_local_id) +/* static */ IndustryType ScriptIndustryType::ResolveNewGRFID(SQInteger grfid, SQInteger grf_local_id) { EnforcePrecondition(INVALID_INDUSTRYTYPE, IsInsideBS(grf_local_id, 0x00, NUM_INDUSTRYTYPES_PER_GRF)); - grfid = BSWAP32(grfid); // Match people's expectations. + grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations. return _industry_mngr.GetID(grf_local_id, grfid); } diff --git a/src/script/api/script_industrytype.hpp b/src/script/api/script_industrytype.hpp index e68546ccedbae..a581e58444971 100644 --- a/src/script/api/script_industrytype.hpp +++ b/src/script/api/script_industrytype.hpp @@ -111,9 +111,9 @@ class ScriptIndustryType : public ScriptObject { * @pre IsValidIndustryType(industry_type). * @return True if you can build this type of industry at locations of your choice. * @ai @note Returns false if you can only prospect this type of industry, or not build it at all. - * @game @note If no valid ScriptCompanyMode active in scope, this method returns false if you can + * @game @note When ScriptCompanyMode::IsDeity, this method returns false if you can * @game only prospect this type of industry, or not build it at all. - * @game @note If no valid ScriptCompanyMode active in scope, the script can + * @game @note When ScriptCompanyMode::IsDeity, the script can * @game build as long as the industry type can be built. (a NewGRF can for example * @game reject construction based on current year) */ @@ -126,10 +126,10 @@ class ScriptIndustryType : public ScriptObject { * @return True if you can prospect this type of industry. * @ai @note If the setting "Manual primary industry construction method" is set * @ai to either "None" or "as other industries" this function always returns false. - * @game @note If no valid ScriptCompanyMode is active in scope, and if the setting + * @game @note When ScriptCompanyMode::IsDeity, and if the setting * @game "Manual primary industry construction method" is set to either "None" or * @game "as other industries" this function always returns false. - * @game @note If no valid ScriptCompanyMode active in scope, the script can + * @game @note When ScriptCompanyMode::IsDeity, the script can * @game prospect as long as the industry type can be built. (a NewGRF can for * @game example reject construction based on current year) */ @@ -152,7 +152,7 @@ class ScriptIndustryType : public ScriptObject { * @return True if no error occurred while trying to prospect. * @note Even if true is returned there is no guarantee a new industry is build. * @note If true is returned the money is paid, whether a new industry was build or not. - * @game @note if no valid ScriptCompanyMode exist in scope, prospection will not fail + * @game @note When ScriptCompanyMode::IsDeity, prospection will not fail * @game due to the general chance that prospection may fail. However prospection can still * @game fail if OpenTTD is unable to find a suitable location to place the industry. */ @@ -184,12 +184,12 @@ class ScriptIndustryType : public ScriptObject { /** * Get a specific industry-type from a grf. - * @param grf_id The ID of the NewGRF. + * @param grfid The ID of the NewGRF. * @param grf_local_id The ID of the industry, local to the NewGRF. * @pre 0x00 <= grf_local_id < NUM_INDUSTRYTYPES_PER_GRF. * @return the industry-type ID, local to the current game (this diverges from the grf_local_id). */ - static IndustryType ResolveNewGRFID(uint32 grfid, uint16 grf_local_id); + static IndustryType ResolveNewGRFID(SQInteger grfid, SQInteger grf_local_id); }; #endif /* SCRIPT_INDUSTRYTYPE_HPP */ diff --git a/src/script/api/script_info_docs.hpp b/src/script/api/script_info_docs.hpp index 36d2b859ab57e..cae585218004f 100644 --- a/src/script/api/script_info_docs.hpp +++ b/src/script/api/script_info_docs.hpp @@ -218,20 +218,27 @@ class ScriptInfo { * store the current configuration of Scripts. Required. * - description A single line describing the setting. Required. * - min_value The minimum value of this setting. Required for integer - * settings and not allowed for boolean settings. + * settings and not allowed for boolean settings. The value will be + * clamped in the range [MIN(int32), MAX(int32)] (inclusive). * - max_value The maximum value of this setting. Required for integer - * settings and not allowed for boolean settings. + * settings and not allowed for boolean settings. The value will be + * clamped in the range [MIN(int32), MAX(int32)] (inclusive). * - easy_value The default value if the easy difficulty level - * is selected. Required. + * is selected. Required. The value will be clamped in the range + * [MIN(int32), MAX(int32)] (inclusive). * - medium_value The default value if the medium difficulty level - * is selected. Required. + * is selected. Required. The value will be clamped in the range + * [MIN(int32), MAX(int32)] (inclusive). * - hard_value The default value if the hard difficulty level - * is selected. Required. + * is selected. Required. The value will be clamped in the range + * [MIN(int32), MAX(int32)] (inclusive). * - custom_value The default value if the custom difficulty level - * is selected. Required. + * is selected. Required. The value will be clamped in the range + * [MIN(int32), MAX(int32)] (inclusive). * - random_deviation If this property has a nonzero value, then the * actual value of the setting in game will be randomized in the range * [user_configured_value - random_deviation, user_configured_value + random_deviation] (inclusive). + * random_deviation sign is ignored and the value is clamped in the range [0, MAX(int32)] (inclusive). * Not allowed if the CONFIG_RANDOM flag is set, otherwise optional. * - step_size The increase/decrease of the value every time the user * clicks one of the up/down arrow buttons. Optional, default is 1. @@ -247,13 +254,16 @@ class ScriptInfo { * user will see the corresponding name. * @param setting_name The name of the setting. * @param value_names A table that maps values to names. The first - * character of every identifier is ignored and the rest should + * character of every identifier is ignored, the second character + * could be '_' to indicate the value is negative, and the rest should * be an integer of the value you define a name for. The value * is a short description of that value. * To define labels for a setting named "competition_level" you could * for example call it like this: * AddLabels("competition_level", {_0 = "no competition", _1 = "some competition", * _2 = "a lot of competition"}); + * Another example, for a setting with a negative value: + * AddLabels("amount", {__1 = "less than one", _0 = "none", _1 = "more than one"}); * * @note This is a function provided by OpenTTD, you don't have to * include it in your Script but should just call it from GetSettings. diff --git a/src/script/api/script_infrastructure.cpp b/src/script/api/script_infrastructure.cpp index 5ef5470c53b60..0a9de4f34ec09 100644 --- a/src/script/api/script_infrastructure.cpp +++ b/src/script/api/script_infrastructure.cpp @@ -18,7 +18,7 @@ #include "../../safeguards.h" -/* static */ uint32 ScriptInfrastructure::GetRailPieceCount(ScriptCompany::CompanyID company, ScriptRail::RailType railtype) +/* static */ SQInteger ScriptInfrastructure::GetRailPieceCount(ScriptCompany::CompanyID company, ScriptRail::RailType railtype) { company = ScriptCompany::ResolveCompanyID(company); if (company == ScriptCompany::COMPANY_INVALID || (::RailType)railtype >= RAILTYPE_END) return 0; @@ -26,7 +26,7 @@ return ::Company::Get((::CompanyID)company)->infrastructure.rail[railtype]; } -/* static */ uint32 ScriptInfrastructure::GetRoadPieceCount(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype) +/* static */ SQInteger ScriptInfrastructure::GetRoadPieceCount(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype) { company = ScriptCompany::ResolveCompanyID(company); if (company == ScriptCompany::COMPANY_INVALID || (::RoadType)roadtype >= ROADTYPE_END) return 0; @@ -34,7 +34,7 @@ return ::Company::Get((::CompanyID)company)->infrastructure.road[roadtype]; } -/* static */ uint32 ScriptInfrastructure::GetInfrastructurePieceCount(ScriptCompany::CompanyID company, Infrastructure infra_type) +/* static */ SQInteger ScriptInfrastructure::GetInfrastructurePieceCount(ScriptCompany::CompanyID company, Infrastructure infra_type) { company = ScriptCompany::ResolveCompanyID(company); if (company == ScriptCompany::COMPANY_INVALID) return 0; diff --git a/src/script/api/script_infrastructure.hpp b/src/script/api/script_infrastructure.hpp index 8f2d28313718a..9b3a499b7d90a 100644 --- a/src/script/api/script_infrastructure.hpp +++ b/src/script/api/script_infrastructure.hpp @@ -35,7 +35,7 @@ class ScriptInfrastructure : public ScriptObject { * @param railtype Rail type to get the count of. * @return Count for the rail type. */ - static uint32 GetRailPieceCount(ScriptCompany::CompanyID company, ScriptRail::RailType railtype); + static SQInteger GetRailPieceCount(ScriptCompany::CompanyID company, ScriptRail::RailType railtype); /** * Return the number of road pieces of a specific road type for a company. @@ -43,7 +43,7 @@ class ScriptInfrastructure : public ScriptObject { * @param roadtype Road type to get the count of. * @return Count for the road type. */ - static uint32 GetRoadPieceCount(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype); + static SQInteger GetRoadPieceCount(ScriptCompany::CompanyID company, ScriptRoad::RoadType roadtype); /** * Return the number of pieces of an infrastructure category for a company. @@ -52,7 +52,7 @@ class ScriptInfrastructure : public ScriptObject { * @return Count for the wanted category. * @note #INFRASTRUCTURE_RAIL and #INFRASTRUCTURE_ROAD return the total count for all rail/road types. */ - static uint32 GetInfrastructurePieceCount(ScriptCompany::CompanyID company, Infrastructure infra_type); + static SQInteger GetInfrastructurePieceCount(ScriptCompany::CompanyID company, Infrastructure infra_type); /** * Return the monthly maintenance costs of a specific rail type for a company. diff --git a/src/script/api/script_league.cpp b/src/script/api/script_league.cpp new file mode 100644 index 0000000000000..905f8b40eac53 --- /dev/null +++ b/src/script/api/script_league.cpp @@ -0,0 +1,121 @@ +/* + * 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 script_league.cpp Implementation of ScriptLeagueTable. */ + +#include "../../stdafx.h" + +#include "script_league.hpp" + +#include "../script_instance.hpp" +#include "script_error.hpp" +#include "../../league_base.h" +#include "../../league_cmd.h" + +#include "../../safeguards.h" + + +/* static */ bool ScriptLeagueTable::IsValidLeagueTable(LeagueTableID table_id) +{ + return ::LeagueTable::IsValidID(table_id); +} + +/* static */ ScriptLeagueTable::LeagueTableID ScriptLeagueTable::New(Text *title, Text *header, Text *footer) +{ + CCountedPtr title_counter(title); + CCountedPtr header_counter(header); + CCountedPtr footer_counter(footer); + + EnforceDeityMode(LEAGUE_TABLE_INVALID); + EnforcePrecondition(LEAGUE_TABLE_INVALID, title != nullptr); + const std::string &encoded_title = title->GetEncodedText(); + EnforcePreconditionEncodedText(LEAGUE_TABLE_INVALID, encoded_title); + + const std::string &encoded_header = (header != nullptr ? header->GetEncodedText() : std::string{}); + const std::string &encoded_footer = (footer != nullptr ? footer->GetEncodedText() : std::string{}); + + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnLeagueTableID, encoded_title, encoded_header, encoded_footer)) return LEAGUE_TABLE_INVALID; + + /* In case of test-mode, we return LeagueTableID 0 */ + return (ScriptLeagueTable::LeagueTableID)0; +} + +/* static */ bool ScriptLeagueTable::IsValidLeagueTableElement(LeagueTableElementID element_id) +{ + return ::LeagueTableElement::IsValidID(element_id); +} + +/* static */ ScriptLeagueTable::LeagueTableElementID ScriptLeagueTable::NewElement(ScriptLeagueTable::LeagueTableID table, SQInteger rating, ScriptCompany::CompanyID company, Text *text, Text *score, LinkType link_type, LinkTargetID link_target) +{ + CCountedPtr text_counter(text); + CCountedPtr score_counter(score); + + EnforceDeityMode(LEAGUE_TABLE_ELEMENT_INVALID); + + EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, IsValidLeagueTable(table)); + + EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID); + CompanyID c = (::CompanyID)company; + if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY; + + EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, text != nullptr); + const std::string &encoded_text = text->GetEncodedText(); + EnforcePreconditionEncodedText(LEAGUE_TABLE_ELEMENT_INVALID, encoded_text); + + EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, score != nullptr); + const std::string &encoded_score = score->GetEncodedText(); + EnforcePreconditionEncodedText(LEAGUE_TABLE_ELEMENT_INVALID, encoded_score); + + EnforcePrecondition(LEAGUE_TABLE_ELEMENT_INVALID, IsValidLink(Link((::LinkType)link_type, link_target))); + + if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnLeagueTableElementID, table, rating, c, encoded_text, encoded_score, (::LinkType)link_type, (::LinkTargetID)link_target)) return LEAGUE_TABLE_ELEMENT_INVALID; + + /* In case of test-mode, we return LeagueTableElementID 0 */ + return (ScriptLeagueTable::LeagueTableElementID)0; +} + +/* static */ bool ScriptLeagueTable::UpdateElementData(LeagueTableElementID element, ScriptCompany::CompanyID company, Text *text, LinkType link_type, LinkTargetID link_target) +{ + CCountedPtr text_counter(text); + + EnforceDeityMode(false); + EnforcePrecondition(false, IsValidLeagueTableElement(element)); + + EnforcePrecondition(false, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID); + CompanyID c = (::CompanyID)company; + if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY; + + EnforcePrecondition(false, text != nullptr); + const std::string &encoded_text = text->GetEncodedText(); + EnforcePreconditionEncodedText(false, encoded_text); + + EnforcePrecondition(false, IsValidLink(Link((::LinkType)link_type, link_target))); + + return ScriptObject::Command::Do(element, c, encoded_text, (::LinkType)link_type, (::LinkTargetID)link_target); +} + +/* static */ bool ScriptLeagueTable::UpdateElementScore(LeagueTableElementID element, SQInteger rating, Text *score) +{ + CCountedPtr score_counter(score); + + EnforceDeityMode(false); + EnforcePrecondition(false, IsValidLeagueTableElement(element)); + + EnforcePrecondition(false, score != nullptr); + const std::string &encoded_score = score->GetEncodedText(); + EnforcePreconditionEncodedText(false, encoded_score); + + return ScriptObject::Command::Do(element, rating, encoded_score); +} + +/* static */ bool ScriptLeagueTable::RemoveElement(LeagueTableElementID element) +{ + EnforceDeityMode(false); + EnforcePrecondition(false, IsValidLeagueTableElement(element)); + + return ScriptObject::Command::Do(element); +} diff --git a/src/script/api/script_league.hpp b/src/script/api/script_league.hpp new file mode 100644 index 0000000000000..7da4074a271d8 --- /dev/null +++ b/src/script/api/script_league.hpp @@ -0,0 +1,136 @@ +/* + * 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 script_league.hpp Everything to manipulate league tables. */ + +#ifndef SCRIPT_LEAGUE_HPP +#define SCRIPT_LEAGUE_HPP + +#include "script_company.hpp" +#include "script_text.hpp" +#include "../../league_type.h" + +/** + * Class that handles league table related functions. + * + * To create a league table: + * 1. Create the league table + * 2. Create league table elements that will be shown in the table in the order of their rating (higher=better). + * + * @api game + */ +class ScriptLeagueTable : public ScriptObject { +public: + /** + * The league table IDs. + */ + enum LeagueTableID { + LEAGUE_TABLE_INVALID = ::INVALID_LEAGUE_TABLE, ///< An invalid league table id. + }; + + /** + * The league table element IDs. + */ + enum LeagueTableElementID { + LEAGUE_TABLE_ELEMENT_INVALID = ::INVALID_LEAGUE_TABLE_ELEMENT, ///< An invalid league table element id. + }; + + /** + * The type of a link. + */ + enum LinkType : byte { + LINK_NONE = ::LT_NONE, ///< No link + LINK_TILE = ::LT_TILE, ///< Link a tile + LINK_INDUSTRY = ::LT_INDUSTRY, ///< Link an industry + LINK_TOWN = ::LT_TOWN, ///< Link a town + LINK_COMPANY = ::LT_COMPANY, ///< Link a company + LINK_STORY_PAGE = ::LT_STORY_PAGE, ///< Link a story page + }; + + /** + * Check whether this is a valid league table ID. + * @param table_id The LeagueTableID to check. + * @return true iff this league table is valid. + */ + static bool IsValidLeagueTable(LeagueTableID table_id); + + /** + * Check whether this is a valid league table element ID. + * @param element_id The LeagueTableElementID to check. + * @return true iff this league table element is valid. + */ + static bool IsValidLeagueTableElement(LeagueTableElementID element_id); + + /** + * Create a new league table. + * @param title League table title (can be either a raw string, or ScriptText object). + * @param header The optional header text for the table (null is allowed). + * @param footer The optional footer text for the table (null is allowed). + * @return The new LeagueTableID, or LEAGUE_TABLE_INVALID if it failed. + * @pre ScriptCompanyMode::IsDeity. + * @pre title != null && len(title) != 0. + */ + static LeagueTableID New(Text *title, Text *header, Text *footer); + + /** + * Create a new league table element. + * @param table Id of the league table this element belongs to. + * @param rating Value that elements are ordered by. + * @param company Company to show the color blob for or INVALID_COMPANY. + * @param text Text of the element (can be either a raw string, or ScriptText object). + * @param score String representation of the score associated with the element (can be either a raw string, or ScriptText object). + * @param link_type Type of the referenced object. + * @param link_target Id of the referenced object. + * @return The new LeagueTableElementID, or LEAGUE_TABLE_ELEMENT_INVALID if it failed. + * @pre ScriptCompanyMode::IsDeity. + * @pre IsValidLeagueTable(table). + * @pre text != null && len(text) != 0. + * @pre score != null && len(score) != 0. + * @pre IsValidLink(Link(link_type, link_target)). + */ + static LeagueTableElementID NewElement(LeagueTableID table, SQInteger rating, ScriptCompany::CompanyID company, Text *text, Text *score, LinkType link_type, LinkTargetID link_target); + + /** + * Update the attributes of a league table element. + * @param element Id of the element to update + * @param company Company to show the color blob for or INVALID_COMPANY. + * @param text Text of the element (can be either a raw string, or ScriptText object). + * @param link_type Type of the referenced object. + * @param link_target Id of the referenced object. + * @return True if the action succeeded. + * @pre ScriptCompanyMode::IsDeity. + * @pre IsValidLeagueTableElement(element). + * @pre text != null && len(text) != 0. + * @pre IsValidLink(Link(link_type, link_target)). + */ + static bool UpdateElementData(LeagueTableElementID element, ScriptCompany::CompanyID company, Text *text, LinkType link_type, LinkTargetID link_target); + + /** + * Create a new league table element. + * @param element Id of the element to update + * @param rating Value that elements are ordered by. + * @param score String representation of the score associated with the element (can be either a raw string, or ScriptText object). + * @return True if the action succeeded. + * @pre ScriptCompanyMode::IsDeity. + * @pre IsValidLeagueTableElement(element). + * @pre score != null && len(score) != 0. + */ + static bool UpdateElementScore(LeagueTableElementID element, SQInteger rating, Text *score); + + + /** + * Remove a league table element. + * @param element Id of the element to update + * @return True if the action succeeded. + * @pre ScriptCompanyMode::IsDeity. + * @pre IsValidLeagueTableElement(element). + */ + static bool RemoveElement(LeagueTableElementID element); +}; + + +#endif /* SCRIPT_LEAGUE_HPP */ diff --git a/src/script/api/script_list.cpp b/src/script/api/script_list.cpp index f563267045be5..ddee29fbd7d6b 100644 --- a/src/script/api/script_list.cpp +++ b/src/script/api/script_list.cpp @@ -22,7 +22,7 @@ class ScriptListSorter { protected: ScriptList *list; ///< The list that's being sorted. bool has_no_more_items; ///< Whether we have more items to iterate over. - int64 item_next; ///< The next item we will show. + SQInteger item_next; ///< The next item we will show. public: /** @@ -33,7 +33,7 @@ class ScriptListSorter { /** * Get the first item of the sorter. */ - virtual int64 Begin() = 0; + virtual SQInteger Begin() = 0; /** * Stop iterating a sorter. @@ -43,7 +43,7 @@ class ScriptListSorter { /** * Get the next item of the sorter. */ - virtual int64 Next() = 0; + virtual SQInteger Next() = 0; /** * See if the sorter has reached the end. @@ -56,7 +56,7 @@ class ScriptListSorter { /** * Callback from the list if an item gets removed. */ - virtual void Remove(int item) = 0; + virtual void Remove(SQInteger item) = 0; /** * Attach the sorter to a new list. This assumes the content of the old list has been moved to @@ -90,7 +90,7 @@ class ScriptListSorterValueAscending : public ScriptListSorter { this->End(); } - int64 Begin() + SQInteger Begin() { if (this->list->buckets.empty()) return 0; this->has_no_more_items = false; @@ -100,7 +100,7 @@ class ScriptListSorterValueAscending : public ScriptListSorter { this->bucket_list_iter = this->bucket_list->begin(); this->item_next = *this->bucket_list_iter; - int64 item_current = this->item_next; + SQInteger item_current = this->item_next; FindNext(); return item_current; } @@ -135,16 +135,16 @@ class ScriptListSorterValueAscending : public ScriptListSorter { this->item_next = *this->bucket_list_iter; } - int64 Next() + SQInteger Next() { if (this->IsEnd()) return 0; - int64 item_current = this->item_next; + SQInteger item_current = this->item_next; FindNext(); return item_current; } - void Remove(int item) + void Remove(SQInteger item) { if (this->IsEnd()) return; @@ -179,7 +179,7 @@ class ScriptListSorterValueDescending : public ScriptListSorter { this->End(); } - int64 Begin() + SQInteger Begin() { if (this->list->buckets.empty()) return 0; this->has_no_more_items = false; @@ -194,7 +194,7 @@ class ScriptListSorterValueDescending : public ScriptListSorter { --this->bucket_list_iter; this->item_next = *this->bucket_list_iter; - int64 item_current = this->item_next; + SQInteger item_current = this->item_next; FindNext(); return item_current; } @@ -232,16 +232,16 @@ class ScriptListSorterValueDescending : public ScriptListSorter { this->item_next = *this->bucket_list_iter; } - int64 Next() + SQInteger Next() { if (this->IsEnd()) return 0; - int64 item_current = this->item_next; + SQInteger item_current = this->item_next; FindNext(); return item_current; } - void Remove(int item) + void Remove(SQInteger item) { if (this->IsEnd()) return; @@ -271,7 +271,7 @@ class ScriptListSorterItemAscending : public ScriptListSorter { this->End(); } - int64 Begin() + SQInteger Begin() { if (this->list->items.empty()) return 0; this->has_no_more_items = false; @@ -279,7 +279,7 @@ class ScriptListSorterItemAscending : public ScriptListSorter { this->item_iter = this->list->items.begin(); this->item_next = (*this->item_iter).first; - int64 item_current = this->item_next; + SQInteger item_current = this->item_next; FindNext(); return item_current; } @@ -302,16 +302,16 @@ class ScriptListSorterItemAscending : public ScriptListSorter { if (this->item_iter != this->list->items.end()) item_next = (*this->item_iter).first; } - int64 Next() + SQInteger Next() { if (this->IsEnd()) return 0; - int64 item_current = this->item_next; + SQInteger item_current = this->item_next; FindNext(); return item_current; } - void Remove(int item) + void Remove(SQInteger item) { if (this->IsEnd()) return; @@ -344,7 +344,7 @@ class ScriptListSorterItemDescending : public ScriptListSorter { this->End(); } - int64 Begin() + SQInteger Begin() { if (this->list->items.empty()) return 0; this->has_no_more_items = false; @@ -353,7 +353,7 @@ class ScriptListSorterItemDescending : public ScriptListSorter { --this->item_iter; this->item_next = (*this->item_iter).first; - int64 item_current = this->item_next; + SQInteger item_current = this->item_next; FindNext(); return item_current; } @@ -381,16 +381,16 @@ class ScriptListSorterItemDescending : public ScriptListSorter { if (this->item_iter != this->list->items.end()) item_next = (*this->item_iter).first; } - int64 Next() + SQInteger Next() { if (this->IsEnd()) return 0; - int64 item_current = this->item_next; + SQInteger item_current = this->item_next; FindNext(); return item_current; } - void Remove(int item) + void Remove(SQInteger item) { if (this->IsEnd()) return; @@ -419,7 +419,7 @@ ScriptList::~ScriptList() delete this->sorter; } -bool ScriptList::HasItem(int64 item) +bool ScriptList::HasItem(SQInteger item) { return this->items.count(item) == 1; } @@ -433,7 +433,7 @@ void ScriptList::Clear() this->sorter->End(); } -void ScriptList::AddItem(int64 item, int64 value) +void ScriptList::AddItem(SQInteger item, SQInteger value) { this->modifications++; @@ -443,14 +443,14 @@ void ScriptList::AddItem(int64 item, int64 value) this->buckets[value].insert(item); } -void ScriptList::RemoveItem(int64 item) +void ScriptList::RemoveItem(SQInteger item) { this->modifications++; ScriptListMap::iterator item_iter = this->items.find(item); if (item_iter == this->items.end()) return; - int64 value = item_iter->second; + SQInteger value = item_iter->second; this->sorter->Remove(item); ScriptListBucket::iterator bucket_iter = this->buckets.find(value); @@ -460,13 +460,13 @@ void ScriptList::RemoveItem(int64 item) this->items.erase(item_iter); } -int64 ScriptList::Begin() +SQInteger ScriptList::Begin() { this->initialized = true; return this->sorter->Begin(); } -int64 ScriptList::Next() +SQInteger ScriptList::Next() { if (!this->initialized) { Debug(script, 0, "Next() is invalid as Begin() is never called"); @@ -489,25 +489,25 @@ bool ScriptList::IsEnd() return this->sorter->IsEnd(); } -int32 ScriptList::Count() +SQInteger ScriptList::Count() { - return (int32)this->items.size(); + return this->items.size(); } -int64 ScriptList::GetValue(int64 item) +SQInteger ScriptList::GetValue(SQInteger item) { ScriptListMap::const_iterator item_iter = this->items.find(item); return item_iter == this->items.end() ? 0 : item_iter->second; } -bool ScriptList::SetValue(int64 item, int64 value) +bool ScriptList::SetValue(SQInteger item, SQInteger value) { this->modifications++; ScriptListMap::iterator item_iter = this->items.find(item); if (item_iter == this->items.end()) return false; - int64 value_old = item_iter->second; + SQInteger value_old = item_iter->second; if (value_old == value) return true; this->sorter->Remove(item); @@ -586,7 +586,7 @@ void ScriptList::SwapList(ScriptList *list) list->sorter->Retarget(list); } -void ScriptList::RemoveAboveValue(int64 value) +void ScriptList::RemoveAboveValue(SQInteger value) { this->modifications++; @@ -596,7 +596,7 @@ void ScriptList::RemoveAboveValue(int64 value) } } -void ScriptList::RemoveBelowValue(int64 value) +void ScriptList::RemoveBelowValue(SQInteger value) { this->modifications++; @@ -606,7 +606,7 @@ void ScriptList::RemoveBelowValue(int64 value) } } -void ScriptList::RemoveBetweenValue(int64 start, int64 end) +void ScriptList::RemoveBetweenValue(SQInteger start, SQInteger end) { this->modifications++; @@ -616,7 +616,7 @@ void ScriptList::RemoveBetweenValue(int64 start, int64 end) } } -void ScriptList::RemoveValue(int64 value) +void ScriptList::RemoveValue(SQInteger value) { this->modifications++; @@ -626,7 +626,7 @@ void ScriptList::RemoveValue(int64 value) } } -void ScriptList::RemoveTop(int32 count) +void ScriptList::RemoveTop(SQInteger count) { this->modifications++; @@ -663,7 +663,7 @@ void ScriptList::RemoveTop(int32 count) } } -void ScriptList::RemoveBottom(int32 count) +void ScriptList::RemoveBottom(SQInteger count) { this->modifications++; @@ -714,7 +714,7 @@ void ScriptList::RemoveList(ScriptList *list) } } -void ScriptList::KeepAboveValue(int64 value) +void ScriptList::KeepAboveValue(SQInteger value) { this->modifications++; @@ -724,7 +724,7 @@ void ScriptList::KeepAboveValue(int64 value) } } -void ScriptList::KeepBelowValue(int64 value) +void ScriptList::KeepBelowValue(SQInteger value) { this->modifications++; @@ -734,7 +734,7 @@ void ScriptList::KeepBelowValue(int64 value) } } -void ScriptList::KeepBetweenValue(int64 start, int64 end) +void ScriptList::KeepBetweenValue(SQInteger start, SQInteger end) { this->modifications++; @@ -744,7 +744,7 @@ void ScriptList::KeepBetweenValue(int64 start, int64 end) } } -void ScriptList::KeepValue(int64 value) +void ScriptList::KeepValue(SQInteger value) { this->modifications++; @@ -754,14 +754,14 @@ void ScriptList::KeepValue(int64 value) } } -void ScriptList::KeepTop(int32 count) +void ScriptList::KeepTop(SQInteger count) { this->modifications++; this->RemoveBottom(this->Count() - count); } -void ScriptList::KeepBottom(int32 count) +void ScriptList::KeepBottom(SQInteger count) { this->modifications++; diff --git a/src/script/api/script_list.hpp b/src/script/api/script_list.hpp index 0dbb2c45d7073..52bfd64487fe8 100644 --- a/src/script/api/script_list.hpp +++ b/src/script/api/script_list.hpp @@ -42,9 +42,9 @@ class ScriptList : public ScriptObject { int modifications; ///< Number of modification that has been done. To prevent changing data while valuating. public: - typedef std::set ScriptItemList; ///< The list of items inside the bucket - typedef std::map ScriptListBucket; ///< The bucket list per value - typedef std::map ScriptListMap; ///< List per item + typedef std::set ScriptItemList; ///< The list of items inside the bucket + typedef std::map ScriptListBucket; ///< The bucket list per value + typedef std::map ScriptListMap; ///< List per item ScriptListMap items; ///< The items in the list ScriptListBucket buckets; ///< The items in the list, sorted by value @@ -58,16 +58,16 @@ class ScriptList : public ScriptObject { * @param item the item to add. Should be unique, otherwise it is ignored. * @param value the value to assign. */ - void AddItem(int64 item, int64 value); + void AddItem(SQInteger item, SQInteger value); #else - void AddItem(int64 item, int64 value = 0); + void AddItem(SQInteger item, SQInteger value = 0); #endif /* DOXYGEN_API */ /** * Remove a single item from the list. * @param item the item to remove. If not existing, it is ignored. */ - void RemoveItem(int64 item); + void RemoveItem(SQInteger item); /** * Clear the list, making Count() returning 0 and IsEmpty() returning true. @@ -79,21 +79,21 @@ class ScriptList : public ScriptObject { * @param item the item to check for. * @return true if the item is in the list. */ - bool HasItem(int64 item); + bool HasItem(SQInteger item); /** * Go to the beginning of the list and return the item. To get the value use list.GetValue(list.Begin()). * @return the first item. * @note returns 0 if beyond end-of-list. Use IsEnd() to check for end-of-list. */ - int64 Begin(); + SQInteger Begin(); /** * Go to the next item in the list and return the item. To get the value use list.GetValue(list.Next()). * @return the next item. * @note returns 0 if beyond end-of-list. Use IsEnd() to check for end-of-list. */ - int64 Next(); + SQInteger Next(); /** * Check if a list is empty. @@ -112,14 +112,14 @@ class ScriptList : public ScriptObject { * Returns the amount of items in the list. * @return amount of items in the list. */ - int32 Count(); + SQInteger Count(); /** * Get the value that belongs to this item. * @param item the item to get the value from * @return the value that belongs to this item. */ - int64 GetValue(int64 item); + SQInteger GetValue(SQInteger item); /** * Set a value of an item directly. @@ -129,7 +129,7 @@ class ScriptList : public ScriptObject { * @note Changing values of items while looping through a list might cause * entries to be skipped. Be very careful with such operations. */ - bool SetValue(int64 item, int64 value); + bool SetValue(SQInteger item, SQInteger value); /** * Sort this list by the given sorter and direction. @@ -160,43 +160,43 @@ class ScriptList : public ScriptObject { * Removes all items with a higher value than 'value'. * @param value the value above which all items are removed. */ - void RemoveAboveValue(int64 value); + void RemoveAboveValue(SQInteger value); /** * Removes all items with a lower value than 'value'. * @param value the value below which all items are removed. */ - void RemoveBelowValue(int64 value); + void RemoveBelowValue(SQInteger value); /** * Removes all items with a value above start and below end. * @param start the lower bound of the to be removed values (exclusive). * @param end the upper bound of the to be removed values (exclusive). */ - void RemoveBetweenValue(int64 start, int64 end); + void RemoveBetweenValue(SQInteger start, SQInteger end); /** * Remove all items with this value. * @param value the value to remove. */ - void RemoveValue(int64 value); + void RemoveValue(SQInteger value); /** * Remove the first count items. * @param count the amount of items to remove. */ - void RemoveTop(int32 count); + void RemoveTop(SQInteger count); /** * Remove the last count items. * @param count the amount of items to remove. */ - void RemoveBottom(int32 count); + void RemoveBottom(SQInteger count); /** * Remove everything that is in the given list from this list (same item index that is). * @param list the list of items to remove. - * @pre list != nullptr + * @pre list != null */ void RemoveList(ScriptList *list); @@ -204,43 +204,43 @@ class ScriptList : public ScriptObject { * Keep all items with a higher value than 'value'. * @param value the value above which all items are kept. */ - void KeepAboveValue(int64 value); + void KeepAboveValue(SQInteger value); /** * Keep all items with a lower value than 'value'. * @param value the value below which all items are kept. */ - void KeepBelowValue(int64 value); + void KeepBelowValue(SQInteger value); /** * Keep all items with a value above start and below end. * @param start the lower bound of the to be kept values (exclusive). * @param end the upper bound of the to be kept values (exclusive). */ - void KeepBetweenValue(int64 start, int64 end); + void KeepBetweenValue(SQInteger start, SQInteger end); /** * Keep all items with this value. * @param value the value to keep. */ - void KeepValue(int64 value); + void KeepValue(SQInteger value); /** * Keep the first count items, i.e. remove everything except the first count items. * @param count the amount of items to keep. */ - void KeepTop(int32 count); + void KeepTop(SQInteger count); /** * Keep the last count items, i.e. remove everything except the last count items. * @param count the amount of items to keep. */ - void KeepBottom(int32 count); + void KeepBottom(SQInteger count); /** * Keeps everything that is in the given list from this list (same item index that is). * @param list the list of items to keep. - * @pre list != nullptr + * @pre list != null */ void KeepList(ScriptList *list); diff --git a/src/script/api/script_log.cpp b/src/script/api/script_log.cpp index 63c4548aaf675..12c4533ca2f4e 100644 --- a/src/script/api/script_log.cpp +++ b/src/script/api/script_log.cpp @@ -75,7 +75,7 @@ /* Also still print to debug window */ Debug(script, level, "[{}] [{}] {}", (uint)ScriptObject::GetRootCompany(), logc, log->lines[log->pos]); - InvalidateWindowData(WC_AI_DEBUG, 0, ScriptObject::GetRootCompany()); + InvalidateWindowData(WC_SCRIPT_DEBUG, 0, ScriptObject::GetRootCompany()); } /* static */ void ScriptLog::FreeLogPointer() diff --git a/src/script/api/script_map.cpp b/src/script/api/script_map.cpp index da66de10f3b97..fb76ac0bf6b31 100644 --- a/src/script/api/script_map.cpp +++ b/src/script/api/script_map.cpp @@ -18,57 +18,57 @@ return ::IsValidTile(t); } -/* static */ TileIndex ScriptMap::GetMapSize() +/* static */ SQInteger ScriptMap::GetMapSize() { - return ::MapSize(); + return ::Map::Size(); } -/* static */ uint32 ScriptMap::GetMapSizeX() +/* static */ SQInteger ScriptMap::GetMapSizeX() { - return ::MapSizeX(); + return ::Map::SizeX(); } -/* static */ uint32 ScriptMap::GetMapSizeY() +/* static */ SQInteger ScriptMap::GetMapSizeY() { - return ::MapSizeY(); + return ::Map::SizeY(); } -/* static */ int32 ScriptMap::GetTileX(TileIndex t) +/* static */ SQInteger ScriptMap::GetTileX(TileIndex t) { if (!::IsValidTile(t)) return -1; return ::TileX(t); } -/* static */ int32 ScriptMap::GetTileY(TileIndex t) +/* static */ SQInteger ScriptMap::GetTileY(TileIndex t) { if (!::IsValidTile(t)) return -1; return ::TileY(t); } -/* static */ TileIndex ScriptMap::GetTileIndex(uint32 x, uint32 y) +/* static */ TileIndex ScriptMap::GetTileIndex(SQInteger x, SQInteger y) { return ::TileXY(x, y); } -/* static */ int32 ScriptMap::DistanceManhattan(TileIndex t1, TileIndex t2) +/* static */ SQInteger ScriptMap::DistanceManhattan(TileIndex t1, TileIndex t2) { if (!::IsValidTile(t1) || !::IsValidTile(t2)) return -1; return ::DistanceManhattan(t1, t2); } -/* static */ int32 ScriptMap::DistanceMax(TileIndex t1, TileIndex t2) +/* static */ SQInteger ScriptMap::DistanceMax(TileIndex t1, TileIndex t2) { if (!::IsValidTile(t1) || !::IsValidTile(t2)) return -1; return ::DistanceMax(t1, t2); } -/* static */ int32 ScriptMap::DistanceSquare(TileIndex t1, TileIndex t2) +/* static */ SQInteger ScriptMap::DistanceSquare(TileIndex t1, TileIndex t2) { if (!::IsValidTile(t1) || !::IsValidTile(t2)) return -1; return ::DistanceSquare(t1, t2); } -/* static */ int32 ScriptMap::DistanceFromEdge(TileIndex t) +/* static */ SQInteger ScriptMap::DistanceFromEdge(TileIndex t) { if (!::IsValidTile(t)) return -1; return ::DistanceFromEdge(t); diff --git a/src/script/api/script_map.hpp b/src/script/api/script_map.hpp index 30acdb9176b21..8e3fe31d6dbb2 100644 --- a/src/script/api/script_map.hpp +++ b/src/script/api/script_map.hpp @@ -33,21 +33,21 @@ class ScriptMap : public ScriptObject { * @return The size of the map in tiles. * @post Return value is always positive. */ - static TileIndex GetMapSize(); + static SQInteger GetMapSize(); /** * Gets the amount of tiles along the SW and NE border. * @return The length along the SW and NE borders. * @post Return value is always positive. */ - static uint32 GetMapSizeX(); + static SQInteger GetMapSizeX(); /** * Gets the amount of tiles along the SE and NW border. * @return The length along the SE and NW borders. * @post Return value is always positive. */ - static uint32 GetMapSizeY(); + static SQInteger GetMapSizeY(); /** * Gets the place along the SW/NE border (X-value). @@ -56,7 +56,7 @@ class ScriptMap : public ScriptObject { * @return The X-value. * @post Return value is always lower than GetMapSizeX(). */ - static int32 GetTileX(TileIndex tile); + static SQInteger GetTileX(TileIndex tile); /** * Gets the place along the SE/NW border (Y-value). @@ -65,17 +65,18 @@ class ScriptMap : public ScriptObject { * @return The Y-value. * @post Return value is always lower than GetMapSizeY(). */ - static int32 GetTileY(TileIndex tile); + static SQInteger GetTileY(TileIndex tile); /** * Gets the TileIndex given a x,y-coordinate. * @param x The X coordinate. * @param y The Y coordinate. - * @pre x < GetMapSizeX(). - * @pre y < GetMapSizeY(). * @return The TileIndex for the given (x,y) coordinate. + * @post When 0 <= x && x < GetMapSizeX() && 0 <= y && y < GetMapSizeY(), then a valid tile index is returned. + * Otherwise it may be invalid, but could be used to calculated neighbouring tiles, e.g. tile + AIMap.GetTileIndex(-1, -1) gets + * the tile index of the tile to the north. But be aware that even when tile is a valid tile, the result might not be a valid tile. */ - static TileIndex GetTileIndex(uint32 x, uint32 y); + static TileIndex GetTileIndex(SQInteger x, SQInteger y); /** * Calculates the Manhattan distance; the difference of @@ -86,7 +87,7 @@ class ScriptMap : public ScriptObject { * @pre IsValidTile(tile_to). * @return The Manhattan distance between the tiles. */ - static int32 DistanceManhattan(TileIndex tile_from, TileIndex tile_to); + static SQInteger DistanceManhattan(TileIndex tile_from, TileIndex tile_to); /** * Calculates the distance between two tiles via 1D calculation. @@ -98,7 +99,7 @@ class ScriptMap : public ScriptObject { * @pre IsValidTile(tile_to). * @return The maximum distance between the tiles. */ - static int32 DistanceMax(TileIndex tile_from, TileIndex tile_to); + static SQInteger DistanceMax(TileIndex tile_from, TileIndex tile_to); /** * The squared distance between the two tiles. @@ -110,7 +111,7 @@ class ScriptMap : public ScriptObject { * @pre IsValidTile(tile_to). * @return The squared distance between the tiles. */ - static int32 DistanceSquare(TileIndex tile_from, TileIndex tile_to); + static SQInteger DistanceSquare(TileIndex tile_from, TileIndex tile_to); /** * Calculates the shortest distance to the edge. @@ -118,7 +119,7 @@ class ScriptMap : public ScriptObject { * @pre IsValidTile(tile). * @return The distances to the closest edge. */ - static int32 DistanceFromEdge(TileIndex tile); + static SQInteger DistanceFromEdge(TileIndex tile); }; #endif /* SCRIPT_MAP_HPP */ diff --git a/src/script/api/script_marine.cpp b/src/script/api/script_marine.cpp index ba5163e49e8ee..6c04e1904630b 100644 --- a/src/script/api/script_marine.cpp +++ b/src/script/api/script_marine.cpp @@ -78,7 +78,7 @@ /* static */ bool ScriptMarine::BuildWaterDepot(TileIndex tile, TileIndex front) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(front)); EnforcePrecondition(false, (::TileX(front) == ::TileX(tile)) != (::TileY(front) == ::TileY(tile))); @@ -88,7 +88,7 @@ /* static */ bool ScriptMarine::BuildDock(TileIndex tile, StationID station_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id)); @@ -97,7 +97,7 @@ /* static */ bool ScriptMarine::BuildBuoy(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); return ScriptObject::Command::Do(tile); @@ -105,7 +105,7 @@ /* static */ bool ScriptMarine::BuildLock(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); return ScriptObject::Command::Do(tile); @@ -113,7 +113,7 @@ /* static */ bool ScriptMarine::BuildCanal(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); return ScriptObject::Command::Do(tile, tile, WATER_CLASS_CANAL, false); @@ -121,7 +121,7 @@ /* static */ bool ScriptMarine::RemoveWaterDepot(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsWaterDepotTile(tile)); @@ -130,7 +130,7 @@ /* static */ bool ScriptMarine::RemoveDock(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsDockTile(tile)); @@ -139,7 +139,7 @@ /* static */ bool ScriptMarine::RemoveBuoy(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsBuoyTile(tile)); @@ -148,7 +148,7 @@ /* static */ bool ScriptMarine::RemoveLock(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsLockTile(tile)); @@ -157,7 +157,7 @@ /* static */ bool ScriptMarine::RemoveCanal(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsCanalTile(tile)); diff --git a/src/script/api/script_marine.hpp b/src/script/api/script_marine.hpp index b3ba022105356..e6d5a2600b182 100644 --- a/src/script/api/script_marine.hpp +++ b/src/script/api/script_marine.hpp @@ -99,7 +99,7 @@ class ScriptMarine : public ScriptObject { * @param front A tile on the same axis with 'tile' as the depot shall be oriented. * @pre ScriptMap::IsValidTile(tile). * @pre ScriptMap::IsValidTile(front). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_SITE_UNSUITABLE * @exception ScriptMarine::ERR_MARINE_MUST_BE_BUILT_ON_WATER @@ -115,7 +115,7 @@ class ScriptMarine : public ScriptObject { * @param station_id The station to join, ScriptStation::STATION_NEW or ScriptStation::STATION_JOIN_ADJACENT. * @pre ScriptMap::IsValidTile(tile). * @pre station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_SITE_UNSUITABLE * @exception ScriptStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION @@ -128,7 +128,7 @@ class ScriptMarine : public ScriptObject { * Builds a buoy on tile. * @param tile The tile where the buoy will be build. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_SITE_UNSUITABLE * @exception ScriptStation::ERR_STATION_TOO_MANY_STATIONS @@ -140,7 +140,7 @@ class ScriptMarine : public ScriptObject { * Builds a lock on tile. * @param tile The tile where the lock will be build. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_LAND_SLOPED_WRONG * @exception ScriptError::ERR_SITE_UNSUITABLE * @return Whether the lock has been/can be build or not. @@ -151,7 +151,7 @@ class ScriptMarine : public ScriptObject { * Builds a canal on tile. * @param tile The tile where the canal will be build. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_LAND_SLOPED_WRONG * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY @@ -164,7 +164,7 @@ class ScriptMarine : public ScriptObject { * Removes a water depot. * @param tile Any tile of the water depot. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return Whether the water depot has been/can be removed or not. */ @@ -174,7 +174,7 @@ class ScriptMarine : public ScriptObject { * Removes a dock. * @param tile Any tile of the dock. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return Whether the dock has been/can be removed or not. */ @@ -184,7 +184,7 @@ class ScriptMarine : public ScriptObject { * Removes a buoy. * @param tile Any tile of the buoy. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return Whether the buoy has been/can be removed or not. */ @@ -194,7 +194,7 @@ class ScriptMarine : public ScriptObject { * Removes a lock. * @param tile Any tile of the lock. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return Whether the lock has been/can be removed or not. */ @@ -204,7 +204,7 @@ class ScriptMarine : public ScriptObject { * Removes a canal. * @param tile Any tile of the canal. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return Whether the canal has been/can be removed or not. */ diff --git a/src/script/api/script_newgrf.cpp b/src/script/api/script_newgrf.cpp index 9cdeeb1914550..10a0a966c3688 100644 --- a/src/script/api/script_newgrf.cpp +++ b/src/script/api/script_newgrf.cpp @@ -24,9 +24,9 @@ ScriptNewGRFList::ScriptNewGRFList() } } -/* static */ bool ScriptNewGRF::IsLoaded(uint32 grfid) +/* static */ bool ScriptNewGRF::IsLoaded(SQInteger grfid) { - grfid = BSWAP32(grfid); // Match people's expectations. + grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations. for (auto c = _grfconfig; c != nullptr; c = c->next) { if (!HasBit(c->flags, GCF_STATIC) && c->ident.grfid == grfid) { @@ -37,9 +37,9 @@ ScriptNewGRFList::ScriptNewGRFList() return false; } -/* static */ uint32 ScriptNewGRF::GetVersion(uint32 grfid) +/* static */ SQInteger ScriptNewGRF::GetVersion(SQInteger grfid) { - grfid = BSWAP32(grfid); // Match people's expectations. + grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations. for (auto c = _grfconfig; c != nullptr; c = c->next) { if (!HasBit(c->flags, GCF_STATIC) && c->ident.grfid == grfid) { @@ -50,9 +50,9 @@ ScriptNewGRFList::ScriptNewGRFList() return 0; } -/* static */ char *ScriptNewGRF::GetName(uint32 grfid) +/* static */ char *ScriptNewGRF::GetName(SQInteger grfid) { - grfid = BSWAP32(grfid); // Match people's expectations. + grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations. for (auto c = _grfconfig; c != nullptr; c = c->next) { if (!HasBit(c->flags, GCF_STATIC) && c->ident.grfid == grfid) { diff --git a/src/script/api/script_newgrf.hpp b/src/script/api/script_newgrf.hpp index d1a9336eccbad..c11202a112d57 100644 --- a/src/script/api/script_newgrf.hpp +++ b/src/script/api/script_newgrf.hpp @@ -34,7 +34,7 @@ class ScriptNewGRF : public ScriptObject { * @param grfid The grfid to check. * @return True if and only if a NewGRF with the given grfid is loaded in the game. */ - static bool IsLoaded(uint32 grfid); + static bool IsLoaded(SQInteger grfid); /** * Get the version of a loaded NewGRF. @@ -42,15 +42,15 @@ class ScriptNewGRF : public ScriptObject { * @pre ScriptNewGRF::IsLoaded(grfid). * @return Version of the NewGRF or 0 if the NewGRF specifies no version. */ - static uint32 GetVersion(uint32 grfid); + static SQInteger GetVersion(SQInteger grfid); /** * Get the name of a loaded NewGRF. * @param grfid The NewGRF to query. * @pre ScriptNewGRF::IsLoaded(grfid). - * @return The name of the NewGRF or nullptr if no name is defined. + * @return The name of the NewGRF or null if no name is defined. */ - static char *GetName(uint32 grfid); + static char *GetName(SQInteger grfid); }; #endif /* SCRIPT_NEWGRF_HPP */ diff --git a/src/script/api/script_news.cpp b/src/script/api/script_news.cpp index 119cbc735c34e..6d668fea0515d 100644 --- a/src/script/api/script_news.cpp +++ b/src/script/api/script_news.cpp @@ -20,12 +20,13 @@ #include "../../safeguards.h" -/* static */ bool ScriptNews::Create(NewsType type, Text *text, ScriptCompany::CompanyID company, NewsReferenceType ref_type, uint32 reference) +/* static */ bool ScriptNews::Create(NewsType type, Text *text, ScriptCompany::CompanyID company, NewsReferenceType ref_type, SQInteger reference) { CCountedPtr counter(text); + EnforceDeityMode(false); EnforcePrecondition(false, text != nullptr); - const char *encoded = text->GetEncodedText(); + const std::string &encoded = text->GetEncodedText(); EnforcePreconditionEncodedText(false, encoded); EnforcePrecondition(false, type == NT_ECONOMY || type == NT_SUBSIDIES || type == NT_GENERAL); EnforcePrecondition(false, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID); diff --git a/src/script/api/script_news.hpp b/src/script/api/script_news.hpp index 6b7b39af015a1..808964f7ba02e 100644 --- a/src/script/api/script_news.hpp +++ b/src/script/api/script_news.hpp @@ -59,11 +59,12 @@ class ScriptNews : public ScriptObject { * - For #NR_TOWN this parameter should be a valid townID (ScriptTown::IsValidTown). * @return True if the action succeeded. * @pre type must be #NT_ECONOMY, #NT_SUBSIDIES, or #NT_GENERAL. - * @pre text != nullptr. + * @pre text != null. * @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID. * @pre The \a reference condition must be fulfilled. + * @pre ScriptCompanyMode::IsDeity(). */ - static bool Create(NewsType type, Text *text, ScriptCompany::CompanyID company, NewsReferenceType ref_type, uint32 reference); + static bool Create(NewsType type, Text *text, ScriptCompany::CompanyID company, NewsReferenceType ref_type, SQInteger reference); }; #endif /* SCRIPT_NEWS_HPP */ diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index 3cddb12f83be9..f15b9d56ecbef 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.cpp @@ -82,20 +82,18 @@ ScriptObject::ActiveInstance::~ActiveInstance() return GetStorage()->mode_instance; } -/* static */ void ScriptObject::SetLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd) +/* static */ void ScriptObject::SetLastCommand(const CommandDataBuffer &data, Commands cmd) { ScriptStorage *s = GetStorage(); - Debug(script, 6, "SetLastCommand company={:02d} tile={:06x} cmd={} data={}", s->root_company, tile, cmd, FormatArrayAsHex(data)); - s->last_tile = tile; + Debug(script, 6, "SetLastCommand company={:02d} cmd={} data={}", s->root_company, cmd, FormatArrayAsHex(data)); s->last_data = data; s->last_cmd = cmd; } -/* static */ bool ScriptObject::CheckLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd) +/* static */ bool ScriptObject::CheckLastCommand(const CommandDataBuffer &data, Commands cmd) { ScriptStorage *s = GetStorage(); - Debug(script, 6, "CheckLastCommand company={:02d} tile={:06x} cmd={} data={}", s->root_company, tile, cmd, FormatArrayAsHex(data)); - if (s->last_tile != tile) return false; + Debug(script, 6, "CheckLastCommand company={:02d} cmd={} data={}", s->root_company, cmd, FormatArrayAsHex(data)); if (s->last_cmd != cmd) return false; if (s->last_data != data) return false; return true; @@ -103,7 +101,7 @@ ScriptObject::ActiveInstance::~ActiveInstance() /* static */ void ScriptObject::SetDoCommandCosts(Money value) { - GetStorage()->costs = CommandCost(value); + GetStorage()->costs = CommandCost(INVALID_EXPENSES, value); // Expense type is never read. } /* static */ void ScriptObject::IncreaseDoCommandCosts(Money value) @@ -255,7 +253,7 @@ std::tuple ScriptObject::DoCommandPrep() bool networking = _networking && !_generating_world; - if (ScriptObject::GetCompany() != OWNER_DEITY && !::Company::IsValidID(ScriptObject::GetCompany())) { + if (!ScriptCompanyMode::IsDeity() && !ScriptCompanyMode::IsValid()) { ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_INVALID_COMPANY); return { true, estimate_only, networking }; } @@ -311,3 +309,19 @@ bool ScriptObject::DoCommandProcessResult(const CommandCost &res, Script_Suspend NOT_REACHED(); } + + +/* static */ Randomizer ScriptObject::random_states[OWNER_END]; + +Randomizer &ScriptObject::GetRandomizer(Owner owner) +{ + return ScriptObject::random_states[owner]; +} + +void ScriptObject::InitializeRandomizers() +{ + Randomizer random = _random; + for (Owner owner = OWNER_BEGIN; owner < OWNER_END; owner++) { + ScriptObject::GetRandomizer(owner).SetSeed(random.Next()); + } +} diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp index 5fffe783b2fc1..a8d01d5c0db1f 100644 --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.hpp @@ -15,11 +15,14 @@ #include "../../rail_type.h" #include "../../string_func.h" #include "../../command_func.h" +#include "../../core/random_func.hpp" #include "script_types.hpp" #include "../script_suspend.hpp" #include "../squirrel.hpp" +#include + /** * The callback function for Mode-classes. */ @@ -73,6 +76,18 @@ friend class ScriptController; */ static class ScriptInstance *GetActiveInstance(); + /** + * Get a reference of the randomizer that brings this script random values. + * @param owner The owner/script to get the randomizer for. This defaults to ScriptObject::GetRootCompany() + */ + static Randomizer &GetRandomizer(Owner owner = ScriptObject::GetRootCompany()); + + /** + * Initialize/reset the script random states. The state of the scripts are + * based on the current _random seed, but _random does not get changed. + */ + static void InitializeRandomizers(); + protected: template struct ScriptDoCommandHelper; @@ -105,12 +120,12 @@ friend class ScriptController; /** * Store the latest command executed by the script. */ - static void SetLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd); + static void SetLastCommand(const CommandDataBuffer &data, Commands cmd); /** * Check if it's the latest command executed by the script. */ - static bool CheckLastCommand(TileIndex tile, const CommandDataBuffer &data, Commands cmd); + static bool CheckLastCommand(const CommandDataBuffer &data, Commands cmd); /** * Sets the DoCommand costs counter to a value. @@ -273,6 +288,7 @@ friend class ScriptController; static std::tuple DoCommandPrep(); static bool DoCommandProcessResult(const CommandCost &res, Script_SuspendCallbackProc *callback, bool estimate_only); static CommandCallbackData *GetDoCommandCallback(); + static Randomizer random_states[OWNER_END]; ///< Random states for each of the scripts (game script uses OWNER_DEITY) }; namespace ScriptObjectInternal { @@ -333,11 +349,14 @@ bool ScriptObject::ScriptDoCommandHelper tile = std::get<0>(args); } + /* Do not even think about executing out-of-bounds tile-commands. */ + if (tile != 0 && (tile >= Map::Size() || (!IsValidTile(tile) && (GetCommandFlags() & CMD_ALL_TILES) == 0))) return false; + /* Only set ClientID parameters when the command does not come from the network. */ if constexpr ((::GetCommandFlags() & CMD_CLIENT_ID) != 0) ScriptObjectInternal::SetClientIds(args, std::index_sequence_for{}); /* Store the command for command callback validation. */ - if (!estimate_only && networking) ScriptObject::SetLastCommand(tile, EndianBufferWriter::FromValue(args), Tcmd); + if (!estimate_only && networking) ScriptObject::SetLastCommand(EndianBufferWriter::FromValue(args), Tcmd); /* Try to perform the command. */ Tret res = ::Command::Unsafe((StringID)0, networking ? ScriptObject::GetDoCommandCallback() : nullptr, false, estimate_only, tile, args); @@ -350,4 +369,68 @@ bool ScriptObject::ScriptDoCommandHelper } } +/** + * Internally used class to automate the ScriptObject reference counting. + * @api -all + */ +template +class ScriptObjectRef { +private: + T *data; ///< The reference counted object. +public: + /** + * Create the reference counter for the given ScriptObject instance. + * @param data The underlying object. + */ + ScriptObjectRef(T *data) : data(data) + { + this->data->AddRef(); + } + + /* No copy constructor. */ + ScriptObjectRef(const ScriptObjectRef &ref) = delete; + + /* Move constructor. */ + ScriptObjectRef(ScriptObjectRef &&ref) noexcept : data(std::exchange(ref.data, nullptr)) + { + } + + /* No copy assignment. */ + ScriptObjectRef& operator=(const ScriptObjectRef &other) = delete; + + /* Move assignment. */ + ScriptObjectRef& operator=(ScriptObjectRef &&other) noexcept + { + std::swap(this->data, other.data); + return *this; + } + + /** + * Release the reference counted object. + */ + ~ScriptObjectRef() + { + if (this->data != nullptr) this->data->Release(); + } + + /** + * Dereferencing this reference returns a reference to the reference + * counted object + * @return Reference to the underlying object. + */ + T &operator*() + { + return *this->data; + } + + /** + * The arrow operator on this reference returns the reference counted object. + * @return Pointer to the underlying object. + */ + T *operator->() + { + return this->data; + } +}; + #endif /* SCRIPT_OBJECT_HPP */ diff --git a/src/script/api/script_objecttype.cpp b/src/script/api/script_objecttype.cpp index 50af8705cdb1e..7d74d9b8b86cf 100644 --- a/src/script/api/script_objecttype.cpp +++ b/src/script/api/script_objecttype.cpp @@ -30,25 +30,27 @@ return GetString(ObjectSpec::Get(object_type)->name); } -/* static */ uint8 ScriptObjectType::GetViews(ObjectType object_type) +/* static */ SQInteger ScriptObjectType::GetViews(ObjectType object_type) { EnforcePrecondition(0, IsValidObjectType(object_type)); return ObjectSpec::Get(object_type)->views; } -/* static */ bool ScriptObjectType::BuildObject(ObjectType object_type, uint8 view, TileIndex tile) +/* static */ bool ScriptObjectType::BuildObject(ObjectType object_type, SQInteger view, TileIndex tile) { + EnforceDeityOrCompanyModeValid(false); EnforcePrecondition(false, IsValidObjectType(object_type)); + EnforcePrecondition(false, view >= 0 && view < GetViews(object_type)); EnforcePrecondition(false, ScriptMap::IsValidTile(tile)); return ScriptObject::Command::Do(tile, object_type, view); } -/* static */ ObjectType ScriptObjectType::ResolveNewGRFID(uint32 grfid, uint16 grf_local_id) +/* static */ ObjectType ScriptObjectType::ResolveNewGRFID(SQInteger grfid, SQInteger grf_local_id) { EnforcePrecondition(INVALID_OBJECT_TYPE, IsInsideBS(grf_local_id, 0x00, NUM_OBJECTS_PER_GRF)); - grfid = BSWAP32(grfid); // Match people's expectations. + grfid = BSWAP32(GB(grfid, 0, 32)); // Match people's expectations. return _object_mngr.GetID(grf_local_id, grfid); } diff --git a/src/script/api/script_objecttype.hpp b/src/script/api/script_objecttype.hpp index 94da70c4677ec..c4b9949308c1f 100644 --- a/src/script/api/script_objecttype.hpp +++ b/src/script/api/script_objecttype.hpp @@ -41,7 +41,7 @@ class ScriptObjectType : public ScriptObject { * @pre IsValidObjectType(object_type). * @return The number of views for an object. */ - static uint8 GetViews(ObjectType object_type); + static SQInteger GetViews(ObjectType object_type); /** * Build an object of the specified type. @@ -51,16 +51,16 @@ class ScriptObjectType : public ScriptObject { * @pre IsValidObjectType(object_type). * @return True if the object was successfully build. */ - static bool BuildObject(ObjectType object_type, uint8 view, TileIndex tile); + static bool BuildObject(ObjectType object_type, SQInteger view, TileIndex tile); /** * Get a specific object-type from a grf. - * @param grf_id The ID of the NewGRF. + * @param grfid The ID of the NewGRF. * @param grf_local_id The ID of the object, local to the NewGRF. * @pre 0x00 <= grf_local_id < NUM_OBJECTS_PER_GRF. * @return the object-type ID, local to the current game (this diverges from the grf_local_id). */ - static ObjectType ResolveNewGRFID(uint32 grfid, uint16 grf_local_id); + static ObjectType ResolveNewGRFID(SQInteger grfid, SQInteger grf_local_id); }; #endif /* SCRIPT_OBJECTTYPE_HPP */ diff --git a/src/script/api/script_order.cpp b/src/script/api/script_order.cpp index c127d11e3c0d1..307b4b851aa5c 100644 --- a/src/script/api/script_order.cpp +++ b/src/script/api/script_order.cpp @@ -50,7 +50,7 @@ static OrderType GetOrderTypeByTile(TileIndex t) /* static */ bool ScriptOrder::IsValidVehicleOrder(VehicleID vehicle_id, OrderPosition order_position) { - return ScriptVehicle::IsValidVehicle(vehicle_id) && order_position >= 0 && (order_position < ::Vehicle::Get(vehicle_id)->GetNumManualOrders() || order_position == ORDER_CURRENT); + return ScriptVehicle::IsPrimaryVehicle(vehicle_id) && order_position >= 0 && (order_position < ::Vehicle::Get(vehicle_id)->GetNumManualOrders() || order_position == ORDER_CURRENT); } /** @@ -68,6 +68,7 @@ static const Order *ResolveOrder(VehicleID vehicle_id, ScriptOrder::OrderPositio if (order_position == ScriptOrder::ORDER_INVALID) return nullptr; } const Order *order = v->GetFirstOrder(); + assert(order != nullptr); while (order->GetType() == OT_IMPLICIT) order = order->next; while (order_position > 0) { order_position = (ScriptOrder::OrderPosition)(order_position - 1); @@ -92,6 +93,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr int res = (int)order_position; const Order *order = v->orders->GetFirstOrder(); + assert(order != nullptr); for (; order->GetType() == OT_IMPLICIT; order = order->next) res++; while (order_position > 0) { order_position = (ScriptOrder::OrderPosition)(order_position - 1); @@ -132,6 +134,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (!IsValidVehicleOrder(vehicle_id, order_position)) return false; const Order *order = ::Vehicle::Get(vehicle_id)->GetOrder(ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position)); + assert(order != nullptr); return order->GetType() == OT_CONDITIONAL; } @@ -141,6 +144,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (!IsValidVehicleOrder(vehicle_id, order_position)) return false; const Order *order = ::ResolveOrder(vehicle_id, order_position); + assert(order != nullptr); return order->GetType() == OT_DUMMY; } @@ -154,7 +158,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr /* static */ bool ScriptOrder::IsCurrentOrderPartOfOrderList(VehicleID vehicle_id) { - if (!ScriptVehicle::IsValidVehicle(vehicle_id)) return false; + if (!ScriptVehicle::IsPrimaryVehicle(vehicle_id)) return false; if (GetOrderCount(vehicle_id) == 0) return false; const Order *order = &::Vehicle::Get(vehicle_id)->current_order; @@ -164,7 +168,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr /* static */ ScriptOrder::OrderPosition ScriptOrder::ResolveOrderPosition(VehicleID vehicle_id, OrderPosition order_position) { - if (!ScriptVehicle::IsValidVehicle(vehicle_id)) return ORDER_INVALID; + if (!ScriptVehicle::IsPrimaryVehicle(vehicle_id)) return ORDER_INVALID; int num_manual_orders = ::Vehicle::Get(vehicle_id)->GetNumManualOrders(); if (num_manual_orders == 0) return ORDER_INVALID; @@ -172,6 +176,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (order_position == ORDER_CURRENT) { int cur_order_pos = ::Vehicle::Get(vehicle_id)->cur_real_order_index; const Order *order = ::Vehicle::Get(vehicle_id)->GetFirstOrder(); + assert(order != nullptr); int num_implicit_orders = 0; for (int i = 0; i < cur_order_pos; i++) { if (order->GetType() == OT_IMPLICIT) num_implicit_orders++; @@ -229,9 +234,9 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr } } -/* static */ int32 ScriptOrder::GetOrderCount(VehicleID vehicle_id) +/* static */ SQInteger ScriptOrder::GetOrderCount(VehicleID vehicle_id) { - return ScriptVehicle::IsValidVehicle(vehicle_id) ? ::Vehicle::Get(vehicle_id)->GetNumManualOrders() : -1; + return ScriptVehicle::IsPrimaryVehicle(vehicle_id) ? ::Vehicle::Get(vehicle_id)->GetNumManualOrders() : -1; } /* static */ TileIndex ScriptOrder::GetOrderDestination(VehicleID vehicle_id, OrderPosition order_position) @@ -344,13 +349,13 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr return (CompareFunction)order->GetConditionComparator(); } -/* static */ int32 ScriptOrder::GetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position) +/* static */ SQInteger ScriptOrder::GetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position) { if (!IsValidVehicleOrder(vehicle_id, order_position)) return -1; if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return -1; const Order *order = ::ResolveOrder(vehicle_id, order_position); - int32 value = order->GetConditionValue(); + SQInteger value = order->GetConditionValue(); if (order->GetConditionVariable() == OCV_MAX_SPEED) value = value * 16 / 10; return value; } @@ -376,6 +381,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr /* static */ bool ScriptOrder::SetOrderJumpTo(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position)); EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position)); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to) && jump_to != ORDER_CURRENT); @@ -385,6 +391,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr /* static */ bool ScriptOrder::SetOrderCondition(VehicleID vehicle_id, OrderPosition order_position, OrderCondition condition) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position)); EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position)); EnforcePrecondition(false, condition >= OC_LOAD_PERCENTAGE && condition <= OC_REMAINING_LIFETIME); @@ -395,6 +402,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr /* static */ bool ScriptOrder::SetOrderCompareFunction(VehicleID vehicle_id, OrderPosition order_position, CompareFunction compare) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position)); EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position)); EnforcePrecondition(false, compare >= CF_EQUALS && compare <= CF_IS_FALSE); @@ -403,8 +411,9 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr return ScriptObject::Command::Do(0, vehicle_id, order_pos, MOF_COND_COMPARATOR, compare); } -/* static */ bool ScriptOrder::SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, int32 value) +/* static */ bool ScriptOrder::SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, SQInteger value) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position)); EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position)); EnforcePrecondition(false, value >= 0 && value < 2048); @@ -416,6 +425,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr /* static */ bool ScriptOrder::SetStopLocation(VehicleID vehicle_id, OrderPosition order_position, StopLocation stop_location) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position)); EnforcePrecondition(false, ScriptVehicle::GetVehicleType(vehicle_id) == ScriptVehicle::VT_RAIL); EnforcePrecondition(false, IsGotoStationOrder(vehicle_id, order_position)); @@ -429,6 +439,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr /* static */ bool ScriptOrder::SetOrderRefit(VehicleID vehicle_id, OrderPosition order_position, CargoID refit_cargo) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position)); EnforcePrecondition(false, IsGotoStationOrder(vehicle_id, order_position) || (IsGotoDepotOrder(vehicle_id, order_position) && refit_cargo != CT_AUTO_REFIT)); EnforcePrecondition(false, ScriptCargo::IsValidCargo(refit_cargo) || refit_cargo == CT_AUTO_REFIT || refit_cargo == CT_NO_REFIT); @@ -438,7 +449,8 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr /* static */ bool ScriptOrder::AppendOrder(VehicleID vehicle_id, TileIndex destination, ScriptOrderFlags order_flags) { - EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id)); EnforcePrecondition(false, AreOrderFlagsValid(destination, order_flags)); return InsertOrder(vehicle_id, (ScriptOrder::OrderPosition)::Vehicle::Get(vehicle_id)->GetNumManualOrders(), destination, order_flags); @@ -446,7 +458,8 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr /* static */ bool ScriptOrder::AppendConditionalOrder(VehicleID vehicle_id, OrderPosition jump_to) { - EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id)); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to)); return InsertConditionalOrder(vehicle_id, (ScriptOrder::OrderPosition)::Vehicle::Get(vehicle_id)->GetNumManualOrders(), jump_to); @@ -457,7 +470,8 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr /* IsValidVehicleOrder is not good enough because it does not allow appending. */ if (order_position == ORDER_CURRENT) order_position = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position); - EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id)); EnforcePrecondition(false, order_position >= 0 && order_position <= ::Vehicle::Get(vehicle_id)->GetNumManualOrders()); EnforcePrecondition(false, AreOrderFlagsValid(destination, order_flags)); @@ -470,7 +484,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (order_flags & OF_GOTO_NEAREST_DEPOT) odaf |= ODATFB_NEAREST_DEPOT; OrderNonStopFlags onsf = (OrderNonStopFlags)((order_flags & OF_NON_STOP_INTERMEDIATE) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); if (order_flags & OF_GOTO_NEAREST_DEPOT) { - order.MakeGoToDepot(0, odtf, onsf, odaf); + order.MakeGoToDepot(INVALID_DEPOT, odtf, onsf, odaf); } else { /* Check explicitly if the order is to a station (for aircraft) or * to a depot (other vehicle types). */ @@ -511,7 +525,8 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr /* IsValidVehicleOrder is not good enough because it does not allow appending. */ if (order_position == ORDER_CURRENT) order_position = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position); - EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id)); EnforcePrecondition(false, order_position >= 0 && order_position <= ::Vehicle::Get(vehicle_id)->GetNumManualOrders()); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to) && jump_to != ORDER_CURRENT); @@ -526,6 +541,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr { order_position = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position)); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position); @@ -536,6 +552,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr { next_order = ScriptOrder::ResolveOrderPosition(vehicle_id, next_order); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, next_order)); int order_pos = ScriptOrderPositionToRealOrderPosition(vehicle_id, next_order); @@ -572,6 +589,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) order_position = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position)); EnforcePrecondition(false, AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_position), order_flags)); @@ -629,6 +647,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) order_position_move = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position_move); order_position_target = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position_target); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position_move)); EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position_target)); EnforcePrecondition(false, order_position_move != order_position_target); @@ -640,28 +659,31 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) /* static */ bool ScriptOrder::CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id) { - EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); - EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(main_vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id)); + EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(main_vehicle_id)); return ScriptObject::Command::Do(0, CO_COPY, vehicle_id, main_vehicle_id); } /* static */ bool ScriptOrder::ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id) { - EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); - EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(main_vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id)); + EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(main_vehicle_id)); return ScriptObject::Command::Do(0, CO_SHARE, vehicle_id, main_vehicle_id); } /* static */ bool ScriptOrder::UnshareOrders(VehicleID vehicle_id) { - EnforcePrecondition(false, ScriptVehicle::IsValidVehicle(vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, ScriptVehicle::IsPrimaryVehicle(vehicle_id)); return ScriptObject::Command::Do(0, CO_UNSHARE, vehicle_id, 0); } -/* static */ uint ScriptOrder::GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile) +/* static */ SQInteger ScriptOrder::GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile) { if (vehicle_type == ScriptVehicle::VT_AIR) { if (ScriptTile::IsStationTile(origin_tile)) { diff --git a/src/script/api/script_order.hpp b/src/script/api/script_order.hpp index 0086e39ca2bd6..fd0f76496dbe7 100644 --- a/src/script/api/script_order.hpp +++ b/src/script/api/script_order.hpp @@ -142,7 +142,7 @@ class ScriptOrder : public ScriptObject { * Checks whether the given order id is valid for the given vehicle. * @param vehicle_id The vehicle to check the order index for. * @param order_position The order index to check. - * @pre ScriptVehicle::IsValidVehicle(vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id). * @return True if and only if the order_position is valid for the given vehicle. */ static bool IsValidVehicleOrder(VehicleID vehicle_id, OrderPosition order_position); @@ -207,7 +207,7 @@ class ScriptOrder : public ScriptObject { /** * Checks whether the current order is part of the orderlist. * @param vehicle_id The vehicle to check. - * @pre ScriptVehicle::IsValidVehicle(vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id). * @return True if and only if the current order is part of the order list. * @note If the order is a non-'non-stop' order, and the vehicle is currently * (un)loading at a station that is not the final destination, this function @@ -222,7 +222,7 @@ class ScriptOrder : public ScriptObject { * given index does not exist it will return ORDER_INVALID. * @param vehicle_id The vehicle to check the order index for. * @param order_position The order index to resolve. - * @pre ScriptVehicle::IsValidVehicle(vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id). * @return The resolved order index. */ static OrderPosition ResolveOrderPosition(VehicleID vehicle_id, OrderPosition order_position); @@ -246,11 +246,11 @@ class ScriptOrder : public ScriptObject { /** * Returns the number of orders for the given vehicle. * @param vehicle_id The vehicle to get the order count of. - * @pre ScriptVehicle::IsValidVehicle(vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id). * @return The number of orders for the given vehicle or a negative * value when the vehicle does not exist. */ - static int32 GetOrderCount(VehicleID vehicle_id); + static SQInteger GetOrderCount(VehicleID vehicle_id); /** * Gets the destination of the given order for the given vehicle. @@ -320,7 +320,7 @@ class ScriptOrder : public ScriptObject { * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). * @return The value to compare against of the order. */ - static int32 GetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position); + static SQInteger GetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position); /** * Gets the stoplocation of the given order for the given train. @@ -356,6 +356,7 @@ class ScriptOrder : public ScriptObject { * @pre IsValidVehicleOrder(vehicle_id, order_position). * @pre IsValidVehicleOrder(vehicle_id, jump_to). * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). + * @game @pre ScriptCompanyMode::IsValid(). * @return Whether the order has been/can be changed. * @api -game */ @@ -369,6 +370,7 @@ class ScriptOrder : public ScriptObject { * @pre IsValidVehicleOrder(vehicle_id, order_position). * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). * @pre condition >= OC_LOAD_PERCENTAGE && condition <= OC_UNCONDITIONALLY. + * @game @pre ScriptCompanyMode::IsValid(). * @return Whether the order has been/can be changed. * @api -game */ @@ -382,6 +384,7 @@ class ScriptOrder : public ScriptObject { * @pre IsValidVehicleOrder(vehicle_id, order_position). * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). * @pre compare >= CF_EQUALS && compare <= CF_IS_FALSE. + * @game @pre ScriptCompanyMode::IsValid(). * @return Whether the order has been/can be changed. * @api -game */ @@ -395,10 +398,11 @@ class ScriptOrder : public ScriptObject { * @pre IsValidVehicleOrder(vehicle_id, order_position). * @pre order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position). * @pre value >= 0 && value < 2048. + * @game @pre ScriptCompanyMode::IsValid(). * @return Whether the order has been/can be changed. * @api -game */ - static bool SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, int32 value); + static bool SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, SQInteger value); /** * Sets the stoplocation of the given order for the given train. @@ -409,6 +413,7 @@ class ScriptOrder : public ScriptObject { * @pre ScriptVehicle::GetVehicleType(vehicle_id) == ScriptVehicle::VT_RAIL. * @pre IsGotoStationOrder(vehicle_id, order_position). * @pre stop_location >= STOPLOCATION_NEAR && stop_location <= STOPLOCATION_FAR + * @game @pre ScriptCompanyMode::IsValid(). * @return Whether the order has been/can be changed. * @api -game */ @@ -422,6 +427,7 @@ class ScriptOrder : public ScriptObject { * @pre IsValidVehicleOrder(vehicle_id, order_position). * @pre IsGotoStationOrder(vehicle_id, order_position) || (IsGotoDepotOrder(vehicle_id, order_position) && refit_cargo != CT_AUTO_REFIT). * @pre ScriptCargo::IsValidCargo(refit_cargo) || refit_cargo == CT_AUTO_REFIT || refit_cargo == CT_NO_REFIT + * @game @pre ScriptCompanyMode::IsValid(). * @return Whether the order has been/can be changed. * @api -game */ @@ -432,8 +438,9 @@ class ScriptOrder : public ScriptObject { * @param vehicle_id The vehicle to append the order to. * @param destination The destination of the order. * @param order_flags The flags given to the order. - * @pre ScriptVehicle::IsValidVehicle(vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id). * @pre AreOrderFlagsValid(destination, order_flags). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptOrder::ERR_ORDER_TOO_MANY * @exception ScriptOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION @@ -446,8 +453,9 @@ class ScriptOrder : public ScriptObject { * Appends a conditional order to the end of the vehicle's order list. * @param vehicle_id The vehicle to append the order to. * @param jump_to The OrderPosition to jump to if the condition is true. - * @pre ScriptVehicle::IsValidVehicle(vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id). * @pre IsValidVehicleOrder(vehicle_id, jump_to). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptOrder::ERR_ORDER_TOO_MANY * @return True if and only if the order was appended. @@ -461,8 +469,10 @@ class ScriptOrder : public ScriptObject { * @param order_position The order to place the new order before. * @param destination The destination of the order. * @param order_flags The flags given to the order. + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id) * @pre IsValidVehicleOrder(vehicle_id, order_position). * @pre AreOrderFlagsValid(destination, order_flags). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptOrder::ERR_ORDER_TOO_MANY * @exception ScriptOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION @@ -476,8 +486,10 @@ class ScriptOrder : public ScriptObject { * @param vehicle_id The vehicle to add the order to. * @param order_position The order to place the new order before. * @param jump_to The OrderPosition to jump to if the condition is true. + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id). * @pre IsValidVehicleOrder(vehicle_id, order_position). * @pre IsValidVehicleOrder(vehicle_id, jump_to). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptOrder::ERR_ORDER_TOO_MANY * @return True if and only if the order was inserted. @@ -490,6 +502,7 @@ class ScriptOrder : public ScriptObject { * @param vehicle_id The vehicle to remove the order from. * @param order_position The order to remove from the order list. * @pre IsValidVehicleOrder(vehicle_id, order_position). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return True if and only if the order was removed. * @api -game @@ -510,6 +523,7 @@ class ScriptOrder : public ScriptObject { * @pre IsValidVehicleOrder(vehicle_id, order_position). * @pre AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_position), order_flags). * @pre (order_flags & OF_GOTO_NEAREST_DEPOT) == (GetOrderFlags(vehicle_id, order_position) & OF_GOTO_NEAREST_DEPOT). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return True if and only if the order was changed. * @api -game @@ -524,6 +538,7 @@ class ScriptOrder : public ScriptObject { * @pre IsValidVehicleOrder(vehicle_id, order_position_move). * @pre IsValidVehicleOrder(vehicle_id, order_position_target). * @pre order_position_move != order_position_target. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return True if and only if the order was moved. * @note If the order is moved to a lower place (e.g. from 7 to 2) @@ -539,6 +554,7 @@ class ScriptOrder : public ScriptObject { * @param vehicle_id The vehicle that should skip some orders. * @param next_order The order the vehicle should skip to. * @pre IsValidVehicleOrder(vehicle_id, next_order). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return True if and only the current order was changed. * @api -game @@ -550,8 +566,9 @@ class ScriptOrder : public ScriptObject { * are going to be the orders of the changed vehicle. * @param vehicle_id The vehicle to copy the orders to. * @param main_vehicle_id The vehicle to copy the orders from. - * @pre ScriptVehicle::IsValidVehicle(vehicle_id). - * @pre ScriptVehicle::IsValidVehicle(main_vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(main_vehicle_id). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptOrder::ERR_ORDER_TOO_MANY * @exception ScriptOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE @@ -565,8 +582,9 @@ class ScriptOrder : public ScriptObject { * vehicle are going to be the orders of the changed vehicle. * @param vehicle_id The vehicle to add to the shared order list. * @param main_vehicle_id The vehicle to share the orders with. - * @pre ScriptVehicle::IsValidVehicle(vehicle_id). - * @pre ScriptVehicle::IsValidVehicle(main_vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(main_vehicle_id). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptOrder::ERR_ORDER_AIRCRAFT_NOT_ENOUGH_RANGE * @return True if and only if the sharing succeeded. @@ -578,7 +596,8 @@ class ScriptOrder : public ScriptObject { * Removes the given vehicle from a shared orders list. * After unsharing orders, the orders list of the vehicle is empty. * @param vehicle_id The vehicle to remove from the shared order list. - * @pre ScriptVehicle::IsValidVehicle(vehicle_id). + * @pre ScriptVehicle::IsPrimaryVehicle(vehicle_id). + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and only if the unsharing succeeded. * @api -game */ @@ -599,7 +618,7 @@ class ScriptOrder : public ScriptObject { * not be compared with map distances * @see ScriptEngine::GetMaximumOrderDistance and ScriptVehicle::GetMaximumOrderDistance */ - static uint GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile); + static SQInteger GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile); }; DECLARE_ENUM_AS_BIT_SET(ScriptOrder::ScriptOrderFlags) diff --git a/src/script/api/script_priorityqueue.cpp b/src/script/api/script_priorityqueue.cpp index fda452096adc5..c9cdc82862dba 100644 --- a/src/script/api/script_priorityqueue.cpp +++ b/src/script/api/script_priorityqueue.cpp @@ -35,7 +35,7 @@ ScriptPriorityQueue::~ScriptPriorityQueue() SQInteger ScriptPriorityQueue::Insert(HSQUIRRELVM vm) { HSQOBJECT item; - int64 priority; + SQInteger priority; sq_resetobject(&item); sq_getstackobj(vm, 2, &item); sq_getinteger(vm, 3, &priority); @@ -45,7 +45,7 @@ SQInteger ScriptPriorityQueue::Insert(HSQUIRRELVM vm) this->queue.emplace_back(priority, item); std::push_heap(this->queue.begin(), this->queue.end(), this->comp); - return SQConvert::Return(vm, true); + return SQConvert::Return::Set(vm, true); } SQInteger ScriptPriorityQueue::Pop(HSQUIRRELVM vm) @@ -61,7 +61,7 @@ SQInteger ScriptPriorityQueue::Pop(HSQUIRRELVM vm) this->queue.pop_back(); /* Store the object on the Squirrel stack before releasing it to make sure the ref count can't drop to zero. */ - auto ret = SQConvert::Return(vm, item); + auto ret = SQConvert::Return::Set(vm, item); sq_release(vm, &item); return ret; } @@ -74,7 +74,7 @@ SQInteger ScriptPriorityQueue::Peek(HSQUIRRELVM vm) return 1; } - return SQConvert::Return(vm, this->queue.front().second); + return SQConvert::Return::Set(vm, this->queue.front().second); } SQInteger ScriptPriorityQueue::Exists(HSQUIRRELVM vm) @@ -83,7 +83,7 @@ SQInteger ScriptPriorityQueue::Exists(HSQUIRRELVM vm) sq_resetobject(&item); sq_getstackobj(vm, 2, &item); - return SQConvert::Return(vm, std::find(this->queue.cbegin(), this->queue.cend(), item) != this->queue.cend()); + return SQConvert::Return::Set(vm, std::find(this->queue.cbegin(), this->queue.cend(), item) != this->queue.cend()); } SQInteger ScriptPriorityQueue::Clear(HSQUIRRELVM vm) diff --git a/src/script/api/script_priorityqueue.hpp b/src/script/api/script_priorityqueue.hpp index 517f6ab0bd2b7..ac4bbfa6f0129 100644 --- a/src/script/api/script_priorityqueue.hpp +++ b/src/script/api/script_priorityqueue.hpp @@ -21,7 +21,7 @@ */ class ScriptPriorityQueue : public ScriptObject { public: - typedef std::pair PriorityItem; + typedef std::pair PriorityItem; private: struct PriorityComparator { bool operator()(const PriorityItem &lhs, const PriorityItem &rhs) const noexcept @@ -43,7 +43,7 @@ class ScriptPriorityQueue : public ScriptObject { * @param priority The priority to assign the item. * @return True if the item was inserted, false if it was already in the queue. */ - bool Insert(void *item, int64 priority); + bool Insert(void *item, SQInteger priority); /** * Remove and return the item with the lowest priority. @@ -61,6 +61,7 @@ class ScriptPriorityQueue : public ScriptObject { /** * Check if an items is already included in the queue. + * @param item The item to check whether it's already in this queue. * @return true if the items is already in the queue. * @note Performance is O(n), use only when absolutely required. */ diff --git a/src/script/api/script_rail.cpp b/src/script/api/script_rail.cpp index 462dc1311aa18..e9bdbd0658d47 100644 --- a/src/script/api/script_rail.cpp +++ b/src/script/api/script_rail.cpp @@ -69,9 +69,10 @@ /* static */ bool ScriptRail::IsRailTypeAvailable(RailType rail_type) { + EnforceDeityOrCompanyModeValid(false); if ((::RailType)rail_type >= RAILTYPE_END) return false; - return ScriptObject::GetCompany() == OWNER_DEITY || ::HasRailtypeAvail(ScriptObject::GetCompany(), (::RailType)rail_type); + return ScriptCompanyMode::IsDeity() || ::HasRailtypeAvail(ScriptObject::GetCompany(), (::RailType)rail_type); } /* static */ ScriptRail::RailType ScriptRail::GetCurrentRailType() @@ -111,7 +112,7 @@ /* static */ bool ScriptRail::ConvertRailType(TileIndex start_tile, TileIndex end_tile, ScriptRail::RailType convert_to) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(start_tile)); EnforcePrecondition(false, ::IsValidTile(end_tile)); EnforcePrecondition(false, IsRailTypeAvailable(convert_to)); @@ -135,7 +136,7 @@ /* static */ bool ScriptRail::BuildRailDepot(TileIndex tile, TileIndex front) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, tile != front); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(front)); @@ -147,9 +148,9 @@ return ScriptObject::Command::Do(tile, (::RailType)ScriptObject::GetRailType(), entrance_dir); } -/* static */ bool ScriptRail::BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id) +/* static */ bool ScriptRail::BuildRailStation(TileIndex tile, RailTrack direction, SQInteger num_platforms, SQInteger platform_length, StationID station_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW); EnforcePrecondition(false, num_platforms > 0 && num_platforms <= 0xFF); @@ -161,9 +162,9 @@ return ScriptObject::Command::Do(tile, (::RailType)GetCurrentRailType(), direction == RAILTRACK_NW_SE ? AXIS_Y : AXIS_X, num_platforms, platform_length, STAT_CLASS_DFLT, 0, ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION, adjacent); } -/* static */ bool ScriptRail::BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station) +/* static */ bool ScriptRail::BuildNewGRFRailStation(TileIndex tile, RailTrack direction, SQInteger num_platforms, SQInteger platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, SQInteger distance, bool source_station) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW); EnforcePrecondition(false, num_platforms > 0 && num_platforms <= 0xFF); @@ -181,10 +182,10 @@ 0, source_industry, goal_industry, - std::min(255, distance / 2), + std::min(255, distance / 2), AICE_STATION_GET_STATION_ID, source_station ? 0 : 1, - std::min(15u, num_platforms) << 4 | std::min(15u, platform_length), + std::min(15u, num_platforms) << 4 | std::min(15u, platform_length), &file ); @@ -207,7 +208,7 @@ /* static */ bool ScriptRail::BuildRailWaypoint(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsRailTile(tile)); EnforcePrecondition(false, GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE); @@ -218,7 +219,7 @@ /* static */ bool ScriptRail::RemoveRailWaypointTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(tile2)); @@ -227,7 +228,7 @@ /* static */ bool ScriptRail::RemoveRailStationTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(tile2)); @@ -246,7 +247,7 @@ /* static */ bool ScriptRail::BuildRailTrack(TileIndex tile, RailTrack rail_track) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, rail_track != 0); EnforcePrecondition(false, (rail_track & ~::TRACK_BIT_ALL) == 0); @@ -258,7 +259,7 @@ /* static */ bool ScriptRail::RemoveRailTrack(TileIndex tile, RailTrack rail_track) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsPlainRailTile(tile) || ::IsLevelCrossingTile(tile)); EnforcePrecondition(false, GetRailTracks(tile) & rail_track); @@ -276,11 +277,11 @@ if (tile - from == 1) { if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NE_SW) != 0; - if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NE_SE) != 0; - } else if (tile - from == ::MapSizeX()) { + if (to - tile == (int)ScriptMap::GetMapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NE_SE) != 0; + } else if (tile - from == (int)ScriptMap::GetMapSizeX()) { if (tile - to == 1) return (GetRailTracks(tile) & RAILTRACK_NW_NE) != 0; if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NW_SW) != 0; - if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NW_SE) != 0; + if (to - tile == (int)ScriptMap::GetMapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NW_SE) != 0; } else { return (GetRailTracks(tile) & RAILTRACK_SW_SE) != 0; } @@ -301,7 +302,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); } else if (::TileX(from) == ::TileX(*to)) { track = TRACK_Y; - *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); + *to -= ScriptMap::GetMapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); } else if (::TileY(from) < ::TileY(tile)) { if (::TileX(*to) < ::TileX(tile)) { track = TRACK_UPPER; @@ -311,7 +312,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) if (diag_offset != 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); } else { - *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); + *to -= ScriptMap::GetMapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); } } else if (::TileY(from) > ::TileY(tile)) { if (::TileX(*to) < ::TileX(tile)) { @@ -322,7 +323,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) if (diag_offset != 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); } else { - *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); + *to -= ScriptMap::GetMapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); } } else if (::TileX(from) < ::TileX(tile)) { if (::TileY(*to) < ::TileY(tile)) { @@ -333,7 +334,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) if (diag_offset == 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); } else { - *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); + *to -= ScriptMap::GetMapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); } } else if (::TileX(from) > ::TileX(tile)) { if (::TileY(*to) < ::TileY(tile)) { @@ -344,7 +345,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) if (diag_offset == 0) { *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1); } else { - *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); + *to -= ScriptMap::GetMapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1); } } return track; @@ -352,7 +353,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) /* static */ bool ScriptRail::BuildRail(TileIndex from, TileIndex tile, TileIndex to) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(from)); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(to)); @@ -365,12 +366,12 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) (::TileY(from) == ::TileY(tile) && ::TileY(tile) == ::TileY(to))); Track track = SimulateDrag(from, tile, &to); - return ScriptObject::Command::Do(tile, to, (::RailType)ScriptRail::GetCurrentRailType(), track, false, true); + return ScriptObject::Command::Do(to, tile, (::RailType)ScriptRail::GetCurrentRailType(), track, false, true); } /* static */ bool ScriptRail::RemoveRail(TileIndex from, TileIndex tile, TileIndex to) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(from)); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(to)); @@ -382,7 +383,7 @@ static Track SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to) (::TileY(from) == ::TileY(tile) && ::TileY(tile) == ::TileY(to))); Track track = SimulateDrag(from, tile, &to); - return ScriptObject::Command::Do(tile, to, track); + return ScriptObject::Command::Do(to, tile, track); } /** @@ -443,13 +444,13 @@ static bool IsValidSignalType(int signal_type) /* static */ bool ScriptRail::BuildSignal(TileIndex tile, TileIndex front, SignalType signal) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ScriptMap::DistanceManhattan(tile, front) == 1) EnforcePrecondition(false, ::IsPlainRailTile(tile)); EnforcePrecondition(false, ::IsValidSignalType(signal)); Track track = INVALID_TRACK; - uint signal_cycles; + uint signal_cycles = 0; int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile)); for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) { @@ -473,7 +474,7 @@ static bool IsValidSignalType(int signal_type) /* static */ bool ScriptRail::RemoveSignal(TileIndex tile, TileIndex front) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ScriptMap::DistanceManhattan(tile, front) == 1) EnforcePrecondition(false, GetSignalType(tile, front) != SIGNALTYPE_NONE); @@ -504,14 +505,14 @@ static bool IsValidSignalType(int signal_type) } } -/* static */ int32 ScriptRail::GetMaxSpeed(RailType railtype) +/* static */ SQInteger ScriptRail::GetMaxSpeed(RailType railtype) { if (!ScriptRail::IsRailTypeAvailable(railtype)) return -1; return ::GetRailTypeInfo((::RailType)railtype)->max_speed; } -/* static */ uint16 ScriptRail::GetMaintenanceCostFactor(RailType railtype) +/* static */ SQInteger ScriptRail::GetMaintenanceCostFactor(RailType railtype) { if (!ScriptRail::IsRailTypeAvailable(railtype)) return 0; diff --git a/src/script/api/script_rail.hpp b/src/script/api/script_rail.hpp index ec056dacb5257..83a141e554ac5 100644 --- a/src/script/api/script_rail.hpp +++ b/src/script/api/script_rail.hpp @@ -201,7 +201,7 @@ class ScriptRail : public ScriptObject { * @pre ScriptMap::IsValidTile(start_tile). * @pre ScriptMap::IsValidTile(end_tile). * @pre IsRailTypeAvailable(convert_to). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptRail::ERR_UNSUITABLE_TRACK * @return Whether at least some rail has been converted successfully. */ @@ -231,7 +231,7 @@ class ScriptRail : public ScriptObject { * @pre ScriptMap::IsValidTile(front). * @pre 'tile' is not equal to 'front', but in a straight line of it. * @pre IsRailTypeAvailable(GetCurrentRailType()). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_FLAT_LAND_REQUIRED * @exception ScriptError::ERR_AREA_NOT_CLEAR * @return Whether the rail depot has been/can be build or not. @@ -251,7 +251,7 @@ class ScriptRail : public ScriptObject { * @pre num_platforms > 0 && num_platforms <= 255. * @pre platform_length > 0 && platform_length <= 255. * @pre station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_FLAT_LAND_REQUIRED @@ -260,7 +260,7 @@ class ScriptRail : public ScriptObject { * @exception ScriptStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN * @return Whether the station has been/can be build or not. */ - static bool BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id); + static bool BuildRailStation(TileIndex tile, RailTrack direction, SQInteger num_platforms, SQInteger platform_length, StationID station_id); /** * Build a NewGRF rail station. This calls callback 18 to let a NewGRF @@ -288,7 +288,7 @@ class ScriptRail : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo_type) * @pre source_industry == ScriptIndustryType::INDUSTRYTYPE_UNKNOWN || source_industry == ScriptIndustryType::INDUSTRYTYPE_TOWN || ScriptIndustryType::IsValidIndustryType(source_industry). * @pre goal_industry == ScriptIndustryType::INDUSTRYTYPE_UNKNOWN || goal_industry == ScriptIndustryType::INDUSTRYTYPE_TOWN || ScriptIndustryType::IsValidIndustryType(goal_industry). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_FLAT_LAND_REQUIRED @@ -297,7 +297,7 @@ class ScriptRail : public ScriptObject { * @exception ScriptStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN * @return Whether the station has been/can be build or not. */ - static bool BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station); + static bool BuildNewGRFRailStation(TileIndex tile, RailTrack direction, SQInteger num_platforms, SQInteger platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, SQInteger distance, bool source_station); /** * Build a rail waypoint. @@ -306,7 +306,7 @@ class ScriptRail : public ScriptObject { * @pre IsRailTile(tile). * @pre GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE. * @pre IsRailTypeAvailable(GetCurrentRailType()). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_FLAT_LAND_REQUIRED * @return Whether the rail waypoint has been/can be build or not. */ @@ -319,7 +319,7 @@ class ScriptRail : public ScriptObject { * @param keep_rail Whether to keep the rail after removal. * @pre IsValidTile(tile). * @pre IsValidTile(tile2). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptRail::ERR_UNSUITABLE_TRACK * @return Whether at least one tile has been/can be cleared or not. */ @@ -332,7 +332,7 @@ class ScriptRail : public ScriptObject { * @param keep_rail Whether to keep the rail after removal. * @pre IsValidTile(tile). * @pre IsValidTile(tile2). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptRail::ERR_UNSUITABLE_TRACK * @return Whether at least one tile has been/can be cleared or not. */ @@ -353,7 +353,7 @@ class ScriptRail : public ScriptObject { * @param rail_track The RailTrack to build. * @pre ScriptMap::IsValidTile(tile). * @pre IsRailTypeAvailable(GetCurrentRailType()). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_LAND_SLOPED_WRONG * @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS @@ -371,7 +371,7 @@ class ScriptRail : public ScriptObject { * @param rail_track The RailTrack to remove. * @pre ScriptMap::IsValidTile(tile). * @pre (GetRailTracks(tile) & rail_track) != 0. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptRail::ERR_UNSUITABLE_TRACK * @return Whether the rail has been/can be removed or not. * @note You can only remove a single track with this function so do not @@ -404,7 +404,7 @@ class ScriptRail : public ScriptObject { * (ScriptMap::GetTileX(from) == ScriptMap::GetTileX(tile) && ScriptMap::GetTileX(tile) == ScriptMap::GetTileX(to)) || * (ScriptMap::GetTileY(from) == ScriptMap::GetTileY(tile) && ScriptMap::GetTileY(tile) == ScriptMap::GetTileY(to)). * @pre IsRailTypeAvailable(GetCurrentRailType()). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_LAND_SLOPED_WRONG * @exception ScriptRail::ERR_CROSSING_ON_ONEWAY_ROAD @@ -427,7 +427,7 @@ class ScriptRail : public ScriptObject { * abs(ScriptMap::GetTileY(to) - ScriptMap::GetTileY(tile))) <= 1) || * (ScriptMap::GetTileX(from) == ScriptMap::GetTileX(tile) && ScriptMap::GetTileX(tile) == ScriptMap::GetTileX(to)) || * (ScriptMap::GetTileY(from) == ScriptMap::GetTileY(tile) && ScriptMap::GetTileY(tile) == ScriptMap::GetTileY(to)). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptRail::ERR_UNSUITABLE_TRACK * @return Whether the rail has been/can be removed or not. */ @@ -449,7 +449,7 @@ class ScriptRail : public ScriptObject { * @param signal The SignalType to build. * @pre ScriptMap::DistanceManhattan(tile, front) == 1. * @pre IsRailTile(tile) && !IsRailStationTile(tile) && !IsRailWaypointTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptRail::ERR_UNSUITABLE_TRACK * @return Whether the signal has been/can be build or not. */ @@ -461,7 +461,7 @@ class ScriptRail : public ScriptObject { * @param front The tile in front of the signal. * @pre ScriptMap::DistanceManhattan(tile, front) == 1. * @pre GetSignalType(tile, front) != SIGNALTYPE_NONE. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptRail::ERR_UNSUITABLE_TRACK * @return Whether the signal has been/can be removed or not. */ @@ -486,7 +486,7 @@ class ScriptRail : public ScriptObject { * This is mph / 1.6, which is roughly km/h. * To get km/h multiply this number by 1.00584. */ - static int32 GetMaxSpeed(RailType railtype); + static SQInteger GetMaxSpeed(RailType railtype); /** * Get the maintenance cost factor of a railtype. @@ -494,7 +494,7 @@ class ScriptRail : public ScriptObject { * @pre IsRailTypeAvailable(railtype) * @return Maintenance cost factor of the railtype. */ - static uint16 GetMaintenanceCostFactor(RailType railtype); + static SQInteger GetMaintenanceCostFactor(RailType railtype); }; #endif /* SCRIPT_RAIL_HPP */ diff --git a/src/script/api/script_railtypelist.cpp b/src/script/api/script_railtypelist.cpp index ccbbe970955a5..cfc0b3b55073a 100644 --- a/src/script/api/script_railtypelist.cpp +++ b/src/script/api/script_railtypelist.cpp @@ -9,13 +9,15 @@ #include "../../stdafx.h" #include "script_railtypelist.hpp" +#include "script_error.hpp" #include "../../rail.h" #include "../../safeguards.h" ScriptRailTypeList::ScriptRailTypeList() { + EnforceDeityOrCompanyModeValid_Void(); for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - if (ScriptObject::GetCompany() == OWNER_DEITY || ::HasRailtypeAvail(ScriptObject::GetCompany(), rt)) this->AddItem(rt); + if (ScriptCompanyMode::IsDeity() || ::HasRailtypeAvail(ScriptObject::GetCompany(), rt)) this->AddItem(rt); } } diff --git a/src/script/api/script_road.cpp b/src/script/api/script_road.cpp index cae144a871dc8..2326247753972 100644 --- a/src/script/api/script_road.cpp +++ b/src/script/api/script_road.cpp @@ -15,6 +15,7 @@ #include "../../landscape_cmd.h" #include "../../road_cmd.h" #include "../../station_cmd.h" +#include "../../newgrf_roadstop.h" #include "../../script/squirrel_helper_type.hpp" #include "../../safeguards.h" @@ -66,6 +67,7 @@ /* static */ bool ScriptRoad::IsRoadTypeAvailable(RoadType road_type) { + EnforceDeityOrCompanyModeValid(false); return (::RoadType)road_type < ROADTYPE_END && ::HasRoadTypeAvail(ScriptObject::GetCompany(), (::RoadType)road_type); } @@ -98,7 +100,7 @@ { if (!ScriptMap::IsValidTile(tile)) return false; if (!IsRoadTypeAvailable(road_type)) return false; - return ::GetAnyRoadBits(tile, ::GetRoadTramType((::RoadType)road_type), false) != ROAD_NONE; + return ::MayHaveRoad(tile) && HasBit(::GetPresentRoadTypes(tile), (::RoadType)road_type); } /* static */ bool ScriptRoad::AreRoadTilesConnected(TileIndex t1, TileIndex t2) @@ -124,7 +126,7 @@ /* static */ bool ScriptRoad::ConvertRoadType(TileIndex start_tile, TileIndex end_tile, RoadType road_type) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(start_tile)); EnforcePrecondition(false, ::IsValidTile(end_tile)); EnforcePrecondition(false, IsRoadTypeAvailable(road_type)); @@ -148,9 +150,9 @@ * @param end The part that will be build second. * @return True if and only if the road bits can be build. */ -static bool CheckAutoExpandedRoadBits(const Array *existing, int32 start, int32 end) +static bool CheckAutoExpandedRoadBits(const Array<> &existing, int32 start, int32 end) { - return (start + end == 0) && (existing->size == 0 || existing->array[0] == start || existing->array[0] == end); + return (start + end == 0) && (existing.empty() || existing[0] == start || existing[0] == end); } /** @@ -163,7 +165,7 @@ static bool CheckAutoExpandedRoadBits(const Array *existing, int32 start, int32 * they are build or 2 when building the first part automatically * builds the second part. */ -static int32 LookupWithoutBuildOnSlopes(::Slope slope, const Array *existing, int32 start, int32 end) +static int32 LookupWithoutBuildOnSlopes(::Slope slope, const Array<> &existing, int32 start, int32 end) { switch (slope) { /* Flat slopes can always be build. */ @@ -175,9 +177,9 @@ static int32 LookupWithoutBuildOnSlopes(::Slope slope, const Array *existing, in * in the game have been changed. */ case SLOPE_NE: case SLOPE_SW: - return (CheckAutoExpandedRoadBits(existing, start, end) && (start == 1 || end == 1)) ? (existing->size == 0 ? 2 : 1) : 0; + return (CheckAutoExpandedRoadBits(existing, start, end) && (start == 1 || end == 1)) ? (existing.empty() ? 2 : 1) : 0; case SLOPE_SE: case SLOPE_NW: - return (CheckAutoExpandedRoadBits(existing, start, end) && (start != 1 && end != 1)) ? (existing->size == 0 ? 2 : 1) : 0; + return (CheckAutoExpandedRoadBits(existing, start, end) && (start != 1 && end != 1)) ? (existing.empty() ? 2 : 1) : 0; /* Any other tile cannot be built on. */ default: @@ -227,7 +229,7 @@ static RoadBits NeighbourToRoadBits(int32 neighbour) * they are build or 2 when building the first part automatically * builds the second part. */ -static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start, int32 end) +static int32 LookupWithBuildOnSlopes(::Slope slope, const Array<> &existing, int32 start, int32 end) { /* Steep slopes behave the same as slopes with one corner raised. */ if (IsSteepSlope(slope)) { @@ -277,9 +279,6 @@ static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start /* Now perform the actual rotation. */ for (int j = 0; j < base_rotate; j++) { - for (size_t i = 0; i < existing->size; i++) { - existing->array[i] = RotateNeighbour(existing->array[i]); - } start = RotateNeighbour(start); end = RotateNeighbour(end); } @@ -288,8 +287,11 @@ static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start RoadBits start_roadbits = NeighbourToRoadBits(start); RoadBits new_roadbits = start_roadbits | NeighbourToRoadBits(end); RoadBits existing_roadbits = ROAD_NONE; - for (size_t i = 0; i < existing->size; i++) { - existing_roadbits |= NeighbourToRoadBits(existing->array[i]); + for (int32 neighbour : existing) { + for (int j = 0; j < base_rotate; j++) { + neighbour = RotateNeighbour(neighbour); + } + existing_roadbits |= NeighbourToRoadBits(neighbour); } switch (slope) { @@ -377,7 +379,7 @@ static bool NormaliseTileOffset(int32 *tile) return false; } -/* static */ int32 ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::Slope slope_, Array *existing, TileIndex start_, TileIndex end_) +/* static */ SQInteger ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::Slope slope_, Array<> existing, TileIndex start_, TileIndex end_) { ::Slope slope = (::Slope)slope_; int32 start = start_; @@ -386,8 +388,8 @@ static bool NormaliseTileOffset(int32 *tile) /* The start tile and end tile cannot be the same tile either. */ if (start == end) return -1; - for (size_t i = 0; i < existing->size; i++) { - if (!NormaliseTileOffset(&existing->array[i])) return -1; + for (size_t i = 0; i < existing.size(); i++) { + if (!NormaliseTileOffset(&existing[i])) return -1; } if (!NormaliseTileOffset(&start)) return -1; @@ -398,15 +400,13 @@ static bool NormaliseTileOffset(int32 *tile) return _settings_game.construction.build_on_slopes ? LookupWithBuildOnSlopes(slope, existing, start, end) : LookupWithoutBuildOnSlopes(slope, existing, start, end); } -/* static */ int32 ScriptRoad::CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end) +/* static */ SQInteger ScriptRoad::CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end) { if (!::IsValidTile(tile) || !::IsValidTile(start) || !::IsValidTile(end)) return -1; if (::DistanceManhattan(tile, start) != 1 || ::DistanceManhattan(tile, end) != 1) return -1; /* ROAD_NW ROAD_SW ROAD_SE ROAD_NE */ const TileIndexDiff neighbours[] = {::TileDiffXY(0, -1), ::TileDiffXY(1, 0), ::TileDiffXY(0, 1), ::TileDiffXY(-1, 0)}; - Array *existing = (Array*)alloca(sizeof(Array) + lengthof(neighbours) * sizeof(int32)); - existing->size = 0; ::RoadBits rb = ::ROAD_NONE; if (::IsNormalRoadTile(tile)) { @@ -414,8 +414,10 @@ static bool NormaliseTileOffset(int32 *tile) } else { rb = ::GetAnyRoadBits(tile, RTT_ROAD) | ::GetAnyRoadBits(tile, RTT_TRAM); } + + Array<> existing; for (uint i = 0; i < lengthof(neighbours); i++) { - if (HasBit(rb, i)) existing->array[existing->size++] = neighbours[i]; + if (HasBit(rb, i)) existing.emplace_back(neighbours[i]); } return ScriptRoad::CanBuildConnectedRoadParts(ScriptTile::GetSlope(tile), existing, start - tile, end - tile); @@ -449,10 +451,10 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD } } -/* static */ int32 ScriptRoad::GetNeighbourRoadCount(TileIndex tile) +/* static */ SQInteger ScriptRoad::GetNeighbourRoadCount(TileIndex tile) { - if (!::IsValidTile(tile)) return false; - if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false; + if (!::IsValidTile(tile)) return -1; + if (!IsRoadTypeAvailable(GetCurrentRoadType())) return -1; ::RoadType rt = (::RoadType)GetCurrentRoadType(); int32 neighbour = 0; @@ -488,6 +490,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD /* static */ bool ScriptRoad::_BuildRoadInternal(TileIndex start, TileIndex end, bool one_way, bool full) { + EnforceDeityOrCompanyModeValid(false); EnforcePrecondition(false, start != end); EnforcePrecondition(false, ::IsValidTile(start)); EnforcePrecondition(false, ::IsValidTile(end)); @@ -496,7 +499,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); Axis axis = ::TileY(start) != ::TileY(end) ? AXIS_Y : AXIS_X; - return ScriptObject::Command::Do(start, end, ScriptObject::GetRoadType(), axis, one_way ? DRD_NORTHBOUND : DRD_NONE, (start < end) == !full, (start < end) != !full, true); + return ScriptObject::Command::Do(end, start, ScriptObject::GetRoadType(), axis, one_way ? DRD_NORTHBOUND : DRD_NONE, (start < end) == !full, (start < end) != !full, true); } /* static */ bool ScriptRoad::BuildRoad(TileIndex start, TileIndex end) @@ -506,7 +509,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD /* static */ bool ScriptRoad::BuildOneWayRoad(TileIndex start, TileIndex end) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); return _BuildRoadInternal(start, end, true, false); } @@ -517,13 +520,13 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD /* static */ bool ScriptRoad::BuildOneWayRoadFull(TileIndex start, TileIndex end) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); return _BuildRoadInternal(start, end, true, true); } /* static */ bool ScriptRoad::BuildRoadDepot(TileIndex tile, TileIndex front) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, tile != front); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(front)); @@ -537,7 +540,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD /* static */ bool ScriptRoad::_BuildRoadStationInternal(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, bool drive_through, StationID station_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, tile != front); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, ::IsValidTile(front)); @@ -549,7 +552,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD DiagDirection entrance_dir = DiagdirBetweenTiles(tile, front); RoadStopType stop_type = road_veh_type == ROADVEHTYPE_TRUCK ? ROADSTOP_TRUCK : ROADSTOP_BUS; StationID to_join = ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION; - return ScriptObject::Command::Do(tile, 1, 1, stop_type, drive_through, entrance_dir, ScriptObject::GetRoadType(), to_join, station_id != ScriptStation::STATION_JOIN_ADJACENT); + return ScriptObject::Command::Do(tile, 1, 1, stop_type, drive_through, entrance_dir, ScriptObject::GetRoadType(), ROADSTOP_CLASS_DFLT, 0, to_join, station_id != ScriptStation::STATION_JOIN_ADJACENT); } /* static */ bool ScriptRoad::BuildRoadStation(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, StationID station_id) @@ -564,31 +567,31 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD /* static */ bool ScriptRoad::RemoveRoad(TileIndex start, TileIndex end) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, start != end); EnforcePrecondition(false, ::IsValidTile(start)); EnforcePrecondition(false, ::IsValidTile(end)); EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end)); EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); - return ScriptObject::Command::Do(start, end, ScriptObject::GetRoadType(), ::TileY(start) != ::TileY(end) ? AXIS_Y : AXIS_X, start < end, start >= end); + return ScriptObject::Command::Do(end, start, ScriptObject::GetRoadType(), ::TileY(start) != ::TileY(end) ? AXIS_Y : AXIS_X, start < end, start >= end); } /* static */ bool ScriptRoad::RemoveRoadFull(TileIndex start, TileIndex end) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, start != end); EnforcePrecondition(false, ::IsValidTile(start)); EnforcePrecondition(false, ::IsValidTile(end)); EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end)); EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); - return ScriptObject::Command::Do(start, end, ScriptObject::GetRoadType(), ::TileY(start) != ::TileY(end) ? AXIS_Y : AXIS_X, start >= end, start < end); + return ScriptObject::Command::Do(end, start, ScriptObject::GetRoadType(), ::TileY(start) != ::TileY(end) ? AXIS_Y : AXIS_X, start >= end, start < end); } /* static */ bool ScriptRoad::RemoveRoadDepot(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsTileType(tile, MP_ROAD)) EnforcePrecondition(false, GetRoadTileType(tile) == ROAD_TILE_DEPOT); @@ -598,7 +601,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD /* static */ bool ScriptRoad::RemoveRoadStation(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, IsTileType(tile, MP_STATION)); EnforcePrecondition(false, IsRoadStop(tile)); @@ -624,14 +627,14 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD return (RoadTramTypes)(1 << ::GetRoadTramType((::RoadType)roadtype)); } -/* static */ int32 ScriptRoad::GetMaxSpeed(RoadType road_type) +/* static */ SQInteger ScriptRoad::GetMaxSpeed(RoadType road_type) { - if (!ScriptRoad::IsRoadTypeAvailable(road_type)) return 0; + if (!ScriptRoad::IsRoadTypeAvailable(road_type)) return -1; return GetRoadTypeInfo((::RoadType)road_type)->max_speed; } -/* static */ uint16 ScriptRoad::GetMaintenanceCostFactor(RoadType roadtype) +/* static */ SQInteger ScriptRoad::GetMaintenanceCostFactor(RoadType roadtype) { if (!ScriptRoad::IsRoadTypeAvailable(roadtype)) return 0; diff --git a/src/script/api/script_road.hpp b/src/script/api/script_road.hpp index 769c4a7728ff9..78d2f1b77c35b 100644 --- a/src/script/api/script_road.hpp +++ b/src/script/api/script_road.hpp @@ -11,6 +11,7 @@ #define SCRIPT_ROAD_HPP #include "script_tile.hpp" +#include "../squirrel_helper_type.hpp" #include "../../../road.h" /** @@ -140,7 +141,7 @@ class ScriptRoad : public ScriptObject { /** * Check if a given RoadType is available. * @param road_type The RoadType to check for. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if this RoadType can be used. */ static bool IsRoadTypeAvailable(RoadType road_type); @@ -160,7 +161,7 @@ class ScriptRoad : public ScriptObject { /** * Check if a road vehicle built for a road type can run on another road type. * @param engine_road_type The road type the road vehicle is built for. - * @param track_road_type The road type you want to check. + * @param road_road_type The road type you want to check. * @pre ScriptRoad::IsRoadTypeAvailable(engine_road_type). * @pre ScriptRoad::IsRoadTypeAvailable(road_road_type). * @return Whether a road vehicle built for 'engine_road_type' can run on 'road_road_type'. @@ -186,7 +187,7 @@ class ScriptRoad : public ScriptObject { * @pre ScriptMap::IsValidTile(start_tile). * @pre ScriptMap::IsValidTile(end_tile). * @pre IsRoadTypeAvailable(road_type). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptRoad::ERR_UNSUITABLE_ROAD * @return Whether at least some road has been converted successfully. */ @@ -245,7 +246,7 @@ class ScriptRoad : public ScriptObject { * they are build or 2 when building the first part automatically * builds the second part. -1 means the preconditions are not met. */ - static int32 CanBuildConnectedRoadParts(ScriptTile::Slope slope, struct Array *existing, TileIndex start, TileIndex end); + static SQInteger CanBuildConnectedRoadParts(ScriptTile::Slope slope, Array<> existing, TileIndex start, TileIndex end); /** * Lookup function for building road parts independent of whether the @@ -266,7 +267,7 @@ class ScriptRoad : public ScriptObject { * they are build or 2 when building the first part automatically * builds the second part. -1 means the preconditions are not met. */ - static int32 CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end); + static SQInteger CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end); /** * Count how many neighbours are road. @@ -275,7 +276,7 @@ class ScriptRoad : public ScriptObject { * @pre IsRoadTypeAvailable(GetCurrentRoadType()). * @return 0 means no neighbour road; max value is 4. */ - static int32 GetNeighbourRoadCount(TileIndex tile); + static SQInteger GetNeighbourRoadCount(TileIndex tile); /** * Gets the tile in front of a road depot. @@ -321,7 +322,7 @@ class ScriptRoad : public ScriptObject { * @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS * @exception ScriptError::ERR_VEHICLE_IN_THE_WAY * @note Construction will fail if an obstacle is found between the start and end tiles. - * @game @note Building a piece of road (without CompanyMode) results in a piece of road owned by towns. + * @game @note Building a piece of road as deity (ScriptCompanyMode::IsDeity()) results in a piece of road owned by towns. * @return Whether the road has been/can be build or not. */ static bool BuildRoad(TileIndex start, TileIndex end); @@ -342,7 +343,7 @@ class ScriptRoad : public ScriptObject { * ScriptMap::GetTileX(start) == ScriptMap::GetTileX(end) or * ScriptMap::GetTileY(start) == ScriptMap::GetTileY(end). * @pre GetCurrentRoadType() == ROADTYPE_ROAD. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_ALREADY_BUILT * @exception ScriptError::ERR_LAND_SLOPED_WRONG * @exception ScriptError::ERR_AREA_NOT_CLEAR @@ -373,7 +374,7 @@ class ScriptRoad : public ScriptObject { * @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS * @exception ScriptError::ERR_VEHICLE_IN_THE_WAY * @note Construction will fail if an obstacle is found between the start and end tiles. - * @game @note Building a piece of road (without CompanyMode) results in a piece of road owned by towns. + * @game @note Building a piece of road as deity (ScriptCompanyMode::IsDeity()) results in a piece of road owned by towns. * @return Whether the road has been/can be build or not. */ static bool BuildRoadFull(TileIndex start, TileIndex end); @@ -386,7 +387,6 @@ class ScriptRoad : public ScriptObject { * one-way in the other direction, it's made a 'no'-way road (it's * forbidden to enter the tile from any direction). * @param start The start tile of the road. - * @param start The start tile of the road. * @param end The end tile of the road. * @pre 'start' is not equal to 'end'. * @pre ScriptMap::IsValidTile(start). @@ -395,7 +395,7 @@ class ScriptRoad : public ScriptObject { * ScriptMap::GetTileX(start) == ScriptMap::GetTileX(end) or * ScriptMap::GetTileY(start) == ScriptMap::GetTileY(end). * @pre GetCurrentRoadType() == ROADTYPE_ROAD. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_ALREADY_BUILT * @exception ScriptError::ERR_LAND_SLOPED_WRONG * @exception ScriptError::ERR_AREA_NOT_CLEAR @@ -415,7 +415,7 @@ class ScriptRoad : public ScriptObject { * @pre ScriptMap::IsValidTile(front). * @pre 'tile' is not equal to 'front', but in a straight line of it. * @pre IsRoadTypeAvailable(GetCurrentRoadType()). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_FLAT_LAND_REQUIRED * @exception ScriptError::ERR_AREA_NOT_CLEAR * @return Whether the road depot has been/can be build or not. @@ -433,7 +433,7 @@ class ScriptRoad : public ScriptObject { * @pre 'tile' is not equal to 'front', but in a straight line of it. * @pre station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id). * @pre GetCurrentRoadType() == ROADTYPE_ROAD. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_FLAT_LAND_REQUIRED @@ -458,7 +458,7 @@ class ScriptRoad : public ScriptObject { * @pre 'tile' is not equal to 'front', but in a straight line of it. * @pre station_id == ScriptStation::STATION_NEW || station_id == ScriptStation::STATION_JOIN_ADJACENT || ScriptStation::IsValidStation(station_id). * @pre IsRoadTypeAvailable(GetCurrentRoadType()). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_FLAT_LAND_REQUIRED @@ -483,7 +483,7 @@ class ScriptRoad : public ScriptObject { * ScriptMap::GetTileX(start) == ScriptMap::GetTileX(end) or * ScriptMap::GetTileY(start) == ScriptMap::GetTileY(end). * @pre IsRoadTypeAvailable(GetCurrentRoadType()). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptError::ERR_VEHICLE_IN_THE_WAY * @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS @@ -503,7 +503,7 @@ class ScriptRoad : public ScriptObject { * ScriptMap::GetTileX(start) == ScriptMap::GetTileX(end) or * ScriptMap::GetTileY(start) == ScriptMap::GetTileY(end). * @pre IsRoadTypeAvailable(GetCurrentRoadType()). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptError::ERR_VEHICLE_IN_THE_WAY * @exception ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS @@ -516,7 +516,7 @@ class ScriptRoad : public ScriptObject { * @param tile Place to remove the depot from. * @pre ScriptMap::IsValidTile(tile). * @pre Tile is a road depot. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptError::ERR_VEHICLE_IN_THE_WAY * @return Whether the road depot has been/can be removed or not. @@ -528,7 +528,7 @@ class ScriptRoad : public ScriptObject { * @param tile Place to remove the station from. * @pre ScriptMap::IsValidTile(tile). * @pre Tile is a road station. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @exception ScriptError::ERR_VEHICLE_IN_THE_WAY * @return Whether the station has been/can be removed or not. @@ -561,7 +561,7 @@ class ScriptRoad : public ScriptObject { * This is mph / 0.8, which is roughly 0.5 km/h. * To get km/h multiply this number by 2.01168. */ - static int32 GetMaxSpeed(RoadType road_type); + static SQInteger GetMaxSpeed(RoadType road_type); /** * Get the maintenance cost factor of a road type. @@ -569,7 +569,7 @@ class ScriptRoad : public ScriptObject { * @pre IsRoadTypeAvailable(roadtype) * @return Maintenance cost factor of the roadtype. */ - static uint16 GetMaintenanceCostFactor(RoadType roadtype); + static SQInteger GetMaintenanceCostFactor(RoadType roadtype); private: diff --git a/src/script/api/script_roadtypelist.cpp b/src/script/api/script_roadtypelist.cpp index 6ada0cb6b31ca..5d2ad8ae6a1aa 100644 --- a/src/script/api/script_roadtypelist.cpp +++ b/src/script/api/script_roadtypelist.cpp @@ -15,8 +15,9 @@ ScriptRoadTypeList::ScriptRoadTypeList(ScriptRoad::RoadTramTypes rtts) { + EnforceDeityOrCompanyModeValid_Void(); for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { if (!HasBit(rtts, GetRoadTramType(rt))) continue; - if (ScriptObject::GetCompany() == OWNER_DEITY || ::HasRoadTypeAvail(ScriptObject::GetCompany(), rt)) this->AddItem(rt); + if (ScriptCompanyMode::IsDeity() || ::HasRoadTypeAvail(ScriptObject::GetCompany(), rt)) this->AddItem(rt); } } diff --git a/src/script/api/script_sign.cpp b/src/script/api/script_sign.cpp index c95093a791f9b..01488b89537fb 100644 --- a/src/script/api/script_sign.cpp +++ b/src/script/api/script_sign.cpp @@ -21,6 +21,7 @@ /* static */ bool ScriptSign::IsValidSign(SignID sign_id) { + EnforceDeityOrCompanyModeValid(false); const Sign *si = ::Sign::GetIfValid(sign_id); return si != nullptr && (si->owner == ScriptObject::GetCompany() || si->owner == OWNER_DEITY); } @@ -36,9 +37,10 @@ { CCountedPtr counter(name); + EnforceDeityOrCompanyModeValid(false); EnforcePrecondition(false, IsValidSign(sign_id)); EnforcePrecondition(false, name != nullptr); - const char *text = name->GetDecodedText(); + const std::string &text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_SIGN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -63,6 +65,7 @@ /* static */ bool ScriptSign::RemoveSign(SignID sign_id) { + EnforceDeityOrCompanyModeValid(false); EnforcePrecondition(false, IsValidSign(sign_id)); return ScriptObject::Command::Do(sign_id, ""); } @@ -71,9 +74,10 @@ { CCountedPtr counter(name); + EnforceDeityOrCompanyModeValid(INVALID_SIGN); EnforcePrecondition(INVALID_SIGN, ::IsValidTile(location)); EnforcePrecondition(INVALID_SIGN, name != nullptr); - const char *text = name->GetDecodedText(); + const std::string &text = name->GetDecodedText(); EnforcePreconditionEncodedText(INVALID_SIGN, text); EnforcePreconditionCustomError(INVALID_SIGN, ::Utf8StringLength(text) < MAX_LENGTH_SIGN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); diff --git a/src/script/api/script_sign.hpp b/src/script/api/script_sign.hpp index 5913e45a4ff88..06a17da92b4dd 100644 --- a/src/script/api/script_sign.hpp +++ b/src/script/api/script_sign.hpp @@ -43,7 +43,7 @@ class ScriptSign : public ScriptObject { * @param sign_id The sign to set the name for. * @param name The name for the sign (can be either a raw string, or a ScriptText object). * @pre IsValidSign(sign_id). - * @pre name != nullptr && len(name) != 0. + * @pre name != null && len(name) != 0. * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE * @return True if and only if the name was changed. */ @@ -79,7 +79,7 @@ class ScriptSign : public ScriptObject { * @param location The place to build the sign. * @param name The text to place on the sign (can be either a raw string, or a ScriptText object). * @pre ScriptMap::IsValidTile(location). - * @pre name != nullptr && len(name) != 0. + * @pre name != null && len(name) != 0. * @exception ScriptSign::ERR_SIGN_TOO_MANY_SIGNS * @return The SignID of the build sign (use IsValidSign() to check for validity). * In test-mode it returns 0 if successful, or any other value to indicate diff --git a/src/script/api/script_station.cpp b/src/script/api/script_station.cpp index 3b38844df61b6..fd837bb717809 100644 --- a/src/script/api/script_station.cpp +++ b/src/script/api/script_station.cpp @@ -21,8 +21,9 @@ /* static */ bool ScriptStation::IsValidStation(StationID station_id) { + EnforceDeityOrCompanyModeValid(false); const Station *st = ::Station::GetIfValid(station_id); - return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || st->owner == OWNER_NONE); + return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity() || st->owner == OWNER_NONE); } /* static */ ScriptCompany::CompanyID ScriptStation::GetOwner(StationID station_id) @@ -50,7 +51,7 @@ template } template -/* static */ int32 ScriptStation::CountCargoWaiting(StationID station_id, +/* static */ SQInteger ScriptStation::CountCargoWaiting(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id) { if (!ScriptStation::IsCargoRequestValid(station_id, from_station_id, @@ -74,31 +75,31 @@ template return cargo_count; } -/* static */ int32 ScriptStation::GetCargoWaiting(StationID station_id, CargoID cargo_id) +/* static */ SQInteger ScriptStation::GetCargoWaiting(StationID station_id, CargoID cargo_id) { return CountCargoWaiting(station_id, STATION_INVALID, STATION_INVALID, cargo_id); } -/* static */ int32 ScriptStation::GetCargoWaitingFrom(StationID station_id, +/* static */ SQInteger ScriptStation::GetCargoWaitingFrom(StationID station_id, StationID from_station_id, CargoID cargo_id) { return CountCargoWaiting(station_id, from_station_id, STATION_INVALID, cargo_id); } -/* static */ int32 ScriptStation::GetCargoWaitingVia(StationID station_id, +/* static */ SQInteger ScriptStation::GetCargoWaitingVia(StationID station_id, StationID via_station_id, CargoID cargo_id) { return CountCargoWaiting(station_id, STATION_INVALID, via_station_id, cargo_id); } -/* static */ int32 ScriptStation::GetCargoWaitingFromVia(StationID station_id, +/* static */ SQInteger ScriptStation::GetCargoWaitingFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id) { return CountCargoWaiting(station_id, from_station_id, via_station_id, cargo_id); } template -/* static */ int32 ScriptStation::CountCargoPlanned(StationID station_id, +/* static */ SQInteger ScriptStation::CountCargoPlanned(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id) { if (!ScriptStation::IsCargoRequestValid(station_id, from_station_id, @@ -115,24 +116,24 @@ template } } -/* static */ int32 ScriptStation::GetCargoPlanned(StationID station_id, CargoID cargo_id) +/* static */ SQInteger ScriptStation::GetCargoPlanned(StationID station_id, CargoID cargo_id) { return CountCargoPlanned(station_id, STATION_INVALID, STATION_INVALID, cargo_id); } -/* static */ int32 ScriptStation::GetCargoPlannedFrom(StationID station_id, +/* static */ SQInteger ScriptStation::GetCargoPlannedFrom(StationID station_id, StationID from_station_id, CargoID cargo_id) { return CountCargoPlanned(station_id, from_station_id, STATION_INVALID, cargo_id); } -/* static */ int32 ScriptStation::GetCargoPlannedVia(StationID station_id, +/* static */ SQInteger ScriptStation::GetCargoPlannedVia(StationID station_id, StationID via_station_id, CargoID cargo_id) { return CountCargoPlanned(station_id, STATION_INVALID, via_station_id, cargo_id); } -/* static */ int32 ScriptStation::GetCargoPlannedFromVia(StationID station_id, +/* static */ SQInteger ScriptStation::GetCargoPlannedFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id) { return CountCargoPlanned(station_id, from_station_id, via_station_id, cargo_id); @@ -146,14 +147,14 @@ template return ::Station::Get(station_id)->goods[cargo_id].HasRating(); } -/* static */ int32 ScriptStation::GetCargoRating(StationID station_id, CargoID cargo_id) +/* static */ SQInteger ScriptStation::GetCargoRating(StationID station_id, CargoID cargo_id) { if (!ScriptStation::HasCargoRating(station_id, cargo_id)) return -1; return ::ToPercent8(::Station::Get(station_id)->goods[cargo_id].rating); } -/* static */ int32 ScriptStation::GetCoverageRadius(ScriptStation::StationType station_type) +/* static */ SQInteger ScriptStation::GetCoverageRadius(ScriptStation::StationType station_type) { if (station_type == STATION_AIRPORT) return -1; if (!HasExactlyOneBit(station_type)) return -1; @@ -169,21 +170,21 @@ template } } -/* static */ int32 ScriptStation::GetStationCoverageRadius(StationID station_id) +/* static */ SQInteger ScriptStation::GetStationCoverageRadius(StationID station_id) { if (!IsValidStation(station_id)) return -1; return Station::Get(station_id)->GetCatchmentRadius(); } -/* static */ int32 ScriptStation::GetDistanceManhattanToTile(StationID station_id, TileIndex tile) +/* static */ SQInteger ScriptStation::GetDistanceManhattanToTile(StationID station_id, TileIndex tile) { if (!IsValidStation(station_id)) return -1; return ScriptMap::DistanceManhattan(tile, GetLocation(station_id)); } -/* static */ int32 ScriptStation::GetDistanceSquareToTile(StationID station_id, TileIndex tile) +/* static */ SQInteger ScriptStation::GetDistanceSquareToTile(StationID station_id, TileIndex tile) { if (!IsValidStation(station_id)) return -1; @@ -237,6 +238,7 @@ template /* static */ bool ScriptStation::OpenCloseAirport(StationID station_id) { + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidStation(station_id)); EnforcePrecondition(false, HasStationType(station_id, STATION_AIRPORT)); diff --git a/src/script/api/script_station.hpp b/src/script/api/script_station.hpp index 848cc1f27cfd3..4f705a518a99b 100644 --- a/src/script/api/script_station.hpp +++ b/src/script/api/script_station.hpp @@ -82,7 +82,7 @@ class ScriptStation : public ScriptBaseStation { * @pre IsValidCargo(cargo_id). * @return The amount of units waiting at the station. */ - static int32 GetCargoWaiting(StationID station_id, CargoID cargo_id); + static SQInteger GetCargoWaiting(StationID station_id, CargoID cargo_id); /** * See how much cargo with a specific source station there is waiting on a station. @@ -95,7 +95,7 @@ class ScriptStation : public ScriptBaseStation { * @return The amount of units waiting at the station originating from from_station_id. * @note source station means, the station where cargo was first loaded. */ - static int32 GetCargoWaitingFrom(StationID station_id, StationID from_station_id, CargoID cargo_id); + static SQInteger GetCargoWaitingFrom(StationID station_id, StationID from_station_id, CargoID cargo_id); /** * See how much cargo with a specific via-station there is waiting on a station. @@ -108,7 +108,7 @@ class ScriptStation : public ScriptBaseStation { * @return The amount of units waiting at the station with via_station_id as next hop. * @note if ScriptCargo.GetCargoDistributionType(cargo_id) == ScriptCargo.DT_MANUAL, then all waiting cargo will have STATION_INVALID as next hop. */ - static int32 GetCargoWaitingVia(StationID station_id, StationID via_station_id, CargoID cargo_id); + static SQInteger GetCargoWaitingVia(StationID station_id, StationID via_station_id, CargoID cargo_id); /** * See how much cargo with a specific via-station and source station there is waiting on a station. @@ -123,7 +123,7 @@ class ScriptStation : public ScriptBaseStation { * @return The amount of units waiting at the station with from_station_id as source and via_station_id as next hop. * @note if ScriptCargo.GetCargoDistributionType(cargo_id) == ScriptCargo.DT_MANUAL, then all waiting cargo will have STATION_INVALID as next hop. */ - static int32 GetCargoWaitingFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id); + static SQInteger GetCargoWaitingFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id); /** * See how much cargo was planned to pass (including production and consumption) this station per month. @@ -133,7 +133,7 @@ class ScriptStation : public ScriptBaseStation { * @pre IsValidCargo(cargo_id). * @return The amount of cargo units planned to pass the station per month. */ - static int32 GetCargoPlanned(StationID station_id, CargoID cargo_id); + static SQInteger GetCargoPlanned(StationID station_id, CargoID cargo_id); /** * See how much cargo from the specified origin was planned to pass (including production and consumption) this station per month. @@ -145,7 +145,7 @@ class ScriptStation : public ScriptBaseStation { * @pre IsValidCargo(cargo_id). * @return The amount of cargo units from the specified origin planned to pass the station per month. */ - static int32 GetCargoPlannedFrom(StationID station_id, StationID from_station_id, CargoID cargo_id); + static SQInteger GetCargoPlannedFrom(StationID station_id, StationID from_station_id, CargoID cargo_id); /** * See how much cargo was planned to pass (including production and consumption) this station per month, heading for the specified next hop. @@ -158,7 +158,7 @@ class ScriptStation : public ScriptBaseStation { * @return The amount of cargo units planned to pass the station per month, going via the specified next hop. * @note Cargo planned to go "via" the same station that's being queried is actually planned to be consumed there. */ - static int32 GetCargoPlannedVia(StationID station_id, StationID via_station_id, CargoID cargo_id); + static SQInteger GetCargoPlannedVia(StationID station_id, StationID via_station_id, CargoID cargo_id); /** * See how much cargo from the specified origin was planned to pass this station per month, @@ -175,7 +175,7 @@ class ScriptStation : public ScriptBaseStation { * @note Cargo planned to go "via" the same station that's being queried is actually planned to be consumed there. * @note Cargo planned to pass "from" the same station that's being queried is actually produced there. */ - static int32 GetCargoPlannedFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id); + static SQInteger GetCargoPlannedFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id); /** * Check whether the given cargo at the given station a rating. @@ -196,7 +196,7 @@ class ScriptStation : public ScriptBaseStation { * @pre HasCargoRating(station_id, cargo_id). * @return The rating in percent of the cargo on the station. */ - static int32 GetCargoRating(StationID station_id, CargoID cargo_id); + static SQInteger GetCargoRating(StationID station_id, CargoID cargo_id); /** * Get the coverage radius of this type of station. @@ -205,7 +205,7 @@ class ScriptStation : public ScriptBaseStation { * @return The radius in tiles. * @note Coverage radius of airports needs to be requested via ScriptAirport::GetAirportCoverageRadius(), as it requires AirportType. */ - static int32 GetCoverageRadius(ScriptStation::StationType station_type); + static SQInteger GetCoverageRadius(ScriptStation::StationType station_type); /** * Get the coverage radius of this station. @@ -213,7 +213,7 @@ class ScriptStation : public ScriptBaseStation { * @pre IsValidStation(station_id). * @return The radius in tiles. */ - static int32 GetStationCoverageRadius(StationID station_id); + static SQInteger GetStationCoverageRadius(StationID station_id); /** * Get the manhattan distance from the tile to the ScriptStation::GetLocation() @@ -223,7 +223,7 @@ class ScriptStation : public ScriptBaseStation { * @pre IsValidStation(station_id). * @return The distance between station and tile. */ - static int32 GetDistanceManhattanToTile(StationID station_id, TileIndex tile); + static SQInteger GetDistanceManhattanToTile(StationID station_id, TileIndex tile); /** * Get the square distance from the tile to the ScriptStation::GetLocation() @@ -233,7 +233,7 @@ class ScriptStation : public ScriptBaseStation { * @pre IsValidStation(station_id). * @return The distance between station and tile. */ - static int32 GetDistanceSquareToTile(StationID station_id, TileIndex tile); + static SQInteger GetDistanceSquareToTile(StationID station_id, TileIndex tile); /** * Find out if this station is within the rating influence of a town. @@ -287,6 +287,7 @@ class ScriptStation : public ScriptBaseStation { /** * Toggle the open/closed state of an airport. * @param station_id The airport to modify. + * @game @pre ScriptCompanyMode::IsValid(). * @pre IsValidStation(station_id). * @pre HasStationType(station_id, STATION_AIRPORT). * @return True if the state was toggled successfully. @@ -299,11 +300,11 @@ class ScriptStation : public ScriptBaseStation { StationID via_station_id, CargoID cargo_id); template - static int32 CountCargoWaiting(StationID station_id, StationID from_station_id, + static SQInteger CountCargoWaiting(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id); template - static int32 CountCargoPlanned(StationID station_id, StationID from_station_id, + static SQInteger CountCargoPlanned(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id); }; diff --git a/src/script/api/script_stationlist.cpp b/src/script/api/script_stationlist.cpp index 9b9e67e7a6e35..5ccb6a0609ac8 100644 --- a/src/script/api/script_stationlist.cpp +++ b/src/script/api/script_stationlist.cpp @@ -18,14 +18,15 @@ ScriptStationList::ScriptStationList(ScriptStation::StationType station_type) { + EnforceDeityOrCompanyModeValid_Void(); for (Station *st : Station::Iterate()) { - if ((st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && (st->facilities & station_type) != 0) this->AddItem(st->index); + if ((st->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity()) && (st->facilities & station_type) != 0) this->AddItem(st->index); } } ScriptStationList_Vehicle::ScriptStationList_Vehicle(VehicleID vehicle_id) { - if (!ScriptVehicle::IsValidVehicle(vehicle_id)) return; + if (!ScriptVehicle::IsPrimaryVehicle(vehicle_id)) return; Vehicle *v = ::Vehicle::Get(vehicle_id); diff --git a/src/script/api/script_story_page.cpp b/src/script/api/script_story_page.cpp index f767472e02e72..c86896f30ebc3 100644 --- a/src/script/api/script_story_page.cpp +++ b/src/script/api/script_story_page.cpp @@ -42,29 +42,34 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) { CCountedPtr counter(title); - EnforcePrecondition(STORY_PAGE_INVALID, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(STORY_PAGE_INVALID); EnforcePrecondition(STORY_PAGE_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID); uint8 c = company; if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY; if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnStoryPageID, - (::CompanyID)c, title != nullptr ? std::string{ title->GetEncodedText() } : std::string{})) return STORY_PAGE_INVALID; + (::CompanyID)c, title != nullptr ? title->GetEncodedText() : std::string{})) return STORY_PAGE_INVALID; /* In case of test-mode, we return StoryPageID 0 */ return (ScriptStoryPage::StoryPageID)0; } -/* static */ ScriptStoryPage::StoryPageElementID ScriptStoryPage::NewElement(StoryPageID story_page_id, StoryPageElementType type, uint32 reference, Text *text) +/* static */ ScriptStoryPage::StoryPageElementID ScriptStoryPage::NewElement(StoryPageID story_page_id, StoryPageElementType type, SQInteger reference, Text *text) { CCountedPtr counter(text); ::StoryPageElementType btype = static_cast<::StoryPageElementType>(type); - EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(STORY_PAGE_ELEMENT_INVALID); EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, IsValidStoryPage(story_page_id)); - EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, !StoryPageElementTypeRequiresText(btype) || (text != nullptr && !StrEmpty(text->GetEncodedText()))); - EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, type != SPET_LOCATION || ::IsValidTile(reference)); + std::string encoded_text; + if (StoryPageElementTypeRequiresText(btype)) { + EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, text != nullptr); + encoded_text = text->GetEncodedText(); + EnforcePreconditionEncodedText(STORY_PAGE_ELEMENT_INVALID, encoded_text); + } + EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, type != SPET_LOCATION || ::IsValidTile((::TileIndex)reference)); EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, type != SPET_GOAL || ScriptGoal::IsValidGoal((ScriptGoal::GoalID)reference)); EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, type != SPET_GOAL || !(StoryPage::Get(story_page_id)->company == INVALID_COMPANY && Goal::Get(reference)->company != INVALID_COMPANY)); @@ -90,25 +95,30 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) reftile, (::StoryPageID)story_page_id, (::StoryPageElementType)type, refid, - StoryPageElementTypeRequiresText(btype) ? std::string{ text->GetEncodedText() } : std::string{})) return STORY_PAGE_ELEMENT_INVALID; + encoded_text)) return STORY_PAGE_ELEMENT_INVALID; /* In case of test-mode, we return StoryPageElementID 0 */ return (ScriptStoryPage::StoryPageElementID)0; } -/* static */ bool ScriptStoryPage::UpdateElement(StoryPageElementID story_page_element_id, uint32 reference, Text *text) +/* static */ bool ScriptStoryPage::UpdateElement(StoryPageElementID story_page_element_id, SQInteger reference, Text *text) { CCountedPtr counter(text); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, IsValidStoryPageElement(story_page_element_id)); StoryPageElement *pe = StoryPageElement::Get(story_page_element_id); StoryPage *p = StoryPage::Get(pe->page); ::StoryPageElementType type = pe->type; - EnforcePrecondition(false, !StoryPageElementTypeRequiresText(type) || (text != nullptr && !StrEmpty(text->GetEncodedText()))); - EnforcePrecondition(false, type != ::SPET_LOCATION || ::IsValidTile(reference)); + std::string encoded_text; + if (StoryPageElementTypeRequiresText(type)) { + EnforcePrecondition(false, text != nullptr); + encoded_text = text->GetEncodedText(); + EnforcePreconditionEncodedText(false, encoded_text); + } + EnforcePrecondition(false, type != ::SPET_LOCATION || ::IsValidTile((::TileIndex)reference)); EnforcePrecondition(false, type != ::SPET_GOAL || ScriptGoal::IsValidGoal((ScriptGoal::GoalID)reference)); EnforcePrecondition(false, type != ::SPET_GOAL || !(p->company == INVALID_COMPANY && Goal::Get(reference)->company != INVALID_COMPANY)); @@ -130,20 +140,17 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) NOT_REACHED(); } - return ScriptObject::Command::Do(reftile, - story_page_element_id, - refid, - StoryPageElementTypeRequiresText(type) ? std::string{ text->GetEncodedText() } : std::string{}); + return ScriptObject::Command::Do(reftile, story_page_element_id, refid, encoded_text); } -/* static */ uint32 ScriptStoryPage::GetPageSortValue(StoryPageID story_page_id) +/* static */ SQInteger ScriptStoryPage::GetPageSortValue(StoryPageID story_page_id) { EnforcePrecondition(false, IsValidStoryPage(story_page_id)); return StoryPage::Get(story_page_id)->sort_value; } -/* static */ uint32 ScriptStoryPage::GetPageElementSortValue(StoryPageElementID story_page_element_id) +/* static */ SQInteger ScriptStoryPage::GetPageElementSortValue(StoryPageElementID story_page_element_id) { EnforcePrecondition(false, IsValidStoryPageElement(story_page_element_id)); @@ -155,9 +162,9 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) CCountedPtr counter(title); EnforcePrecondition(false, IsValidStoryPage(story_page_id)); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); - return ScriptObject::Command::Do(story_page_id, title != nullptr ? std::string{ title->GetEncodedText() } : std::string{}); + return ScriptObject::Command::Do(story_page_id, title != nullptr ? title->GetEncodedText() : std::string{}); } /* static */ ScriptCompany::CompanyID ScriptStoryPage::GetCompany(StoryPageID story_page_id) @@ -173,7 +180,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) /* static */ ScriptDate::Date ScriptStoryPage::GetDate(StoryPageID story_page_id) { EnforcePrecondition(ScriptDate::DATE_INVALID, IsValidStoryPage(story_page_id)); - EnforcePrecondition(ScriptDate::DATE_INVALID, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(ScriptDate::DATE_INVALID); return (ScriptDate::Date)StoryPage::Get(story_page_id)->date; } @@ -181,7 +188,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) /* static */ bool ScriptStoryPage::SetDate(StoryPageID story_page_id, ScriptDate::Date date) { EnforcePrecondition(false, IsValidStoryPage(story_page_id)); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); return ScriptObject::Command::Do(story_page_id, date); } @@ -190,14 +197,14 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) /* static */ bool ScriptStoryPage::Show(StoryPageID story_page_id) { EnforcePrecondition(false, IsValidStoryPage(story_page_id)); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); return ScriptObject::Command::Do(story_page_id); } /* static */ bool ScriptStoryPage::Remove(StoryPageID story_page_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, IsValidStoryPage(story_page_id)); return ScriptObject::Command::Do(story_page_id); @@ -205,7 +212,7 @@ static inline bool StoryPageElementTypeRequiresText(StoryPageElementType type) /* static */ bool ScriptStoryPage::RemoveElement(StoryPageElementID story_page_element_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, IsValidStoryPageElement(story_page_element_id)); return ScriptObject::Command::Do(story_page_element_id); diff --git a/src/script/api/script_story_page.hpp b/src/script/api/script_story_page.hpp index c87ef7cb37810..2e878ede5e386 100644 --- a/src/script/api/script_story_page.hpp +++ b/src/script/api/script_story_page.hpp @@ -184,7 +184,7 @@ class ScriptStoryPage : public ScriptObject { * @param company The company to create the story page for, or ScriptCompany::COMPANY_INVALID for all. * @param title Page title (can be either a raw string, a ScriptText object, or null). * @return The new StoryPageID, or STORY_PAGE_INVALID if it failed. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID. */ static StoryPageID New(ScriptCompany::CompanyID company, Text *title); @@ -200,14 +200,14 @@ class ScriptStoryPage : public ScriptObject { * use the #BuildPushButtonReference, #BuildTileButtonReference, or #BuildVehicleButtonReference functions to make the values. * @param text The body text of page elements that allow custom text. (SPET_TEXT and SPET_LOCATION) * @return The new StoryPageElementID, or STORY_PAGE_ELEMENT_INVALID if it failed. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidStoryPage(story_page). - * @pre (type != SPET_TEXT && type != SPET_LOCATION) || (text != nullptr && len(text) != 0). + * @pre (type != SPET_TEXT && type != SPET_LOCATION) || (text != null && len(text) != 0). * @pre type != SPET_LOCATION || ScriptMap::IsValidTile(reference). * @pre type != SPET_GOAL || ScriptGoal::IsValidGoal(reference). * @pre if type is SPET_GOAL and story_page is a global page, then referenced goal must be global. */ - static StoryPageElementID NewElement(StoryPageID story_page_id, StoryPageElementType type, uint32 reference, Text *text); + static StoryPageElementID NewElement(StoryPageID story_page_id, StoryPageElementType type, SQInteger reference, Text *text); /** * Update the content of a page element @@ -215,14 +215,14 @@ class ScriptStoryPage : public ScriptObject { * @param reference A reference value to the object that is referred to by some page element types. See also NewElement. * @param text The body text of page elements that allow custom text. See also NewElement. * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidStoryPage(story_page). - * @pre (type != SPET_TEXT && type != SPET_LOCATION) || (text != nullptr && len(text) != 0). + * @pre (type != SPET_TEXT && type != SPET_LOCATION) || (text != null && len(text) != 0). * @pre type != SPET_LOCATION || ScriptMap::IsValidTile(reference). * @pre type != SPET_GOAL || ScriptGoal::IsValidGoal(reference). * @pre if type is SPET_GOAL and story_page is a global page, then referenced goal must be global. */ - static bool UpdateElement(StoryPageElementID story_page_element_id, uint32 reference, Text *text); + static bool UpdateElement(StoryPageElementID story_page_element_id, SQInteger reference, Text *text); /** * Get story page sort value. Each page has a sort value that is internally assigned and used @@ -232,7 +232,7 @@ class ScriptStoryPage : public ScriptObject { * @param story_page_id The story page to get the sort value of. * @return Page sort value. */ - static uint32 GetPageSortValue(StoryPageID story_page_id); + static SQInteger GetPageSortValue(StoryPageID story_page_id); /** * Get story page element sort value. Each page element has a sort value that is internally @@ -243,7 +243,7 @@ class ScriptStoryPage : public ScriptObject { * @param story_page_element_id The story page element to get the sort value of. * @return Page element sort value. */ - static uint32 GetPageElementSortValue(StoryPageElementID story_page_element_id); + static SQInteger GetPageElementSortValue(StoryPageElementID story_page_element_id); /** * Get the company which the page belongs to. If the page is global, @@ -267,7 +267,7 @@ class ScriptStoryPage : public ScriptObject { * @param story_page_id The story page to set the date for. * @param date Date to display at the top of story page or ScriptDate::DATE_INVALID to disable showing date on this page. (also, @see ScriptDate) * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidStoryPage(story_page_id). */ static bool SetDate(StoryPageID story_page_id, ScriptDate::Date date); @@ -277,7 +277,7 @@ class ScriptStoryPage : public ScriptObject { * @param story_page_id The story page to update. * @param title Page title (can be either a raw string, a ScriptText object, or null). * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidStoryPage(story_page_id). */ static bool SetTitle(StoryPageID story_page_id, Text *title); @@ -288,7 +288,7 @@ class ScriptStoryPage : public ScriptObject { * companies are affecetd. Otherwise only the clients of the company which the page belongs * to are affected. * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidStoryPage(story_page_id). */ static bool Show(StoryPageID story_page_id); @@ -298,7 +298,7 @@ class ScriptStoryPage : public ScriptObject { * associated with it. * @param story_page_id The story page to remove. * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidStoryPage(story_page_id). */ static bool Remove(StoryPageID story_page_id); @@ -307,7 +307,7 @@ class ScriptStoryPage : public ScriptObject { * Removes a story page element. * @param story_page_element_id The story page element to remove. * @return True if the action succeeded. - * @pre No ScriptCompanyMode may be in scope. + * @pre ScriptCompanyMode::IsDeity(). * @pre IsValidStoryPageElement(story_page_element_id). */ static bool RemoveElement(StoryPageElementID story_page_element_id); @@ -315,6 +315,7 @@ class ScriptStoryPage : public ScriptObject { /** * Create a reference value for SPET_BUTTON_PUSH element parameters. * @param colour The colour for the face of the button. + * @param flags The formatting and layout flags for the button. * @return A reference value usable with the #NewElement and #UpdateElement functions. */ static StoryPageButtonFormatting MakePushButtonReference(StoryPageButtonColour colour, StoryPageButtonFlags flags); @@ -322,6 +323,7 @@ class ScriptStoryPage : public ScriptObject { /** * Create a reference value for SPET_BUTTON_TILE element parameters. * @param colour The colour for the face of the button. + * @param flags The formatting and layout flags for the button. * @param cursor The mouse cursor to use when the player clicks the button and the game is ready for the player to select a tile. * @return A reference value usable with the #NewElement and #UpdateElement functions. */ @@ -330,6 +332,7 @@ class ScriptStoryPage : public ScriptObject { /** * Create a reference value for SPET_BUTTON_VEHICLE element parameters. * @param colour The colour for the face of the button. + * @param flags The formatting and layout flags for the button. * @param cursor The mouse cursor to use when the player clicks the button and the game is ready for the player to select a vehicle. * @param vehtype The type of vehicle that will be selectable, or \c VT_INVALID to allow all types. * @return A reference value usable with the #NewElement and #UpdateElement functions. diff --git a/src/script/api/script_subsidy.cpp b/src/script/api/script_subsidy.cpp index 5e1180d1bb951..afc6eef14bd5e 100644 --- a/src/script/api/script_subsidy.cpp +++ b/src/script/api/script_subsidy.cpp @@ -31,8 +31,9 @@ return ::Subsidy::Get(subsidy_id)->IsAwarded(); } -/* static */ bool ScriptSubsidy::Create(CargoID cargo_type, SubsidyParticipantType from_type, uint16 from_id, SubsidyParticipantType to_type, uint16 to_id) +/* static */ bool ScriptSubsidy::Create(CargoID cargo_type, SubsidyParticipantType from_type, SQInteger from_id, SubsidyParticipantType to_type, SQInteger to_id) { + EnforceDeityMode(false); EnforcePrecondition(false, ScriptCargo::IsValidCargo(cargo_type)); EnforcePrecondition(false, from_type == SPT_INDUSTRY || from_type == SPT_TOWN); EnforcePrecondition(false, to_type == SPT_INDUSTRY || to_type == SPT_TOWN); @@ -78,9 +79,9 @@ return (SubsidyParticipantType)(uint)::Subsidy::Get(subsidy_id)->src_type; } -/* static */ int32 ScriptSubsidy::GetSourceIndex(SubsidyID subsidy_id) +/* static */ SQInteger ScriptSubsidy::GetSourceIndex(SubsidyID subsidy_id) { - if (!IsValidSubsidy(subsidy_id)) return INVALID_STATION; + if (!IsValidSubsidy(subsidy_id)) return INVALID_SOURCE; return ::Subsidy::Get(subsidy_id)->src; } @@ -92,9 +93,9 @@ return (SubsidyParticipantType)(uint)::Subsidy::Get(subsidy_id)->dst_type; } -/* static */ int32 ScriptSubsidy::GetDestinationIndex(SubsidyID subsidy_id) +/* static */ SQInteger ScriptSubsidy::GetDestinationIndex(SubsidyID subsidy_id) { - if (!IsValidSubsidy(subsidy_id)) return INVALID_STATION; + if (!IsValidSubsidy(subsidy_id)) return INVALID_SOURCE; return ::Subsidy::Get(subsidy_id)->dst; } diff --git a/src/script/api/script_subsidy.hpp b/src/script/api/script_subsidy.hpp index a4f9fa68670cf..dd71ab036b0a0 100644 --- a/src/script/api/script_subsidy.hpp +++ b/src/script/api/script_subsidy.hpp @@ -55,6 +55,7 @@ class ScriptSubsidy : public ScriptObject { * @param to_type The type of the subsidy on the 'to' side. * @param to_id The ID of the 'to' side. * @return True if the action succeeded. + * @pre ScriptCompanyMode::IsDeity(). * @pre ScriptCargo::IsValidCargo(cargo_type) * @pre from_type == SPT_INDUSTRY || from_type == SPT_TOWN. * @pre to_type == SPT_INDUSTRY || to_type == SPT_TOWN. @@ -62,7 +63,7 @@ class ScriptSubsidy : public ScriptObject { * @pre (to_type == SPT_INDUSTRY && ScriptIndustry::IsValidIndustry(to_id)) || (to_type == SPT_TOWN && ScriptTown::IsValidTown(to_id)) * @api -ai */ - static bool Create(CargoID cargo_type, SubsidyParticipantType from_type, uint16 from_id, SubsidyParticipantType to_type, uint16 to_id); + static bool Create(CargoID cargo_type, SubsidyParticipantType from_type, SQInteger from_id, SubsidyParticipantType to_type, SQInteger to_id); /** * Get the company index of the company this subsidy is awarded to. @@ -109,7 +110,7 @@ class ScriptSubsidy : public ScriptObject { * @pre IsValidSubsidy(subsidy_id). * @return One of TownID/IndustryID. */ - static int32 GetSourceIndex(SubsidyID subsidy_id); + static SQInteger GetSourceIndex(SubsidyID subsidy_id); /** * Returns the type of destination of subsidy. @@ -127,7 +128,7 @@ class ScriptSubsidy : public ScriptObject { * @pre IsValidSubsidy(subsidy_id). * @return One of TownID/IndustryID. */ - static int32 GetDestinationIndex(SubsidyID subsidy_id); + static SQInteger GetDestinationIndex(SubsidyID subsidy_id); }; #endif /* SCRIPT_SUBSIDY_HPP */ diff --git a/src/script/api/script_text.cpp b/src/script/api/script_text.cpp index 62980326ce4ff..79166ee3949ca 100644 --- a/src/script/api/script_text.cpp +++ b/src/script/api/script_text.cpp @@ -10,22 +10,19 @@ #include "../../stdafx.h" #include "../../string_func.h" #include "../../strings_func.h" +#include "../../game/game_text.hpp" #include "script_text.hpp" +#include "../script_fatalerror.hpp" #include "../../table/control_codes.h" #include "table/strings.h" #include "../../safeguards.h" -RawText::RawText(const char *text) : text(stredup(text)) +RawText::RawText(const char *text) : text(text) { } -RawText::~RawText() -{ - free(this->text); -} - ScriptText::ScriptText(HSQUIRRELVM vm) : ZeroedMemoryAllocator() @@ -57,32 +54,16 @@ ScriptText::ScriptText(HSQUIRRELVM vm) : } } -ScriptText::~ScriptText() -{ - for (int i = 0; i < SCRIPT_TEXT_MAX_PARAMETERS; i++) { - free(this->params[i]); - if (this->paramt[i] != nullptr) this->paramt[i]->Release(); - } -} - SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm) { if (parameter >= SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR; - free(this->params[parameter]); - if (this->paramt[parameter] != nullptr) this->paramt[parameter]->Release(); - - this->parami[parameter] = 0; - this->params[parameter] = nullptr; - this->paramt[parameter] = nullptr; - switch (sq_gettype(vm, -1)) { case OT_STRING: { const SQChar *value; sq_getstring(vm, -1, &value); - this->params[parameter] = stredup(value); - StrMakeValidInPlace(this->params[parameter]); + this->param[parameter] = StrMakeValid(value); break; } @@ -90,7 +71,7 @@ SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm) SQInteger value; sq_getinteger(vm, -1, &value); - this->parami[parameter] = value; + this->param[parameter] = value; break; } @@ -113,8 +94,7 @@ SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm) if (real_instance == nullptr) return SQ_ERROR; ScriptText *value = static_cast(real_instance); - value->AddRef(); - this->paramt[parameter] = value; + this->param[parameter] = ScriptTextRef(value); break; } @@ -176,40 +156,67 @@ SQInteger ScriptText::_set(HSQUIRRELVM vm) return this->_SetParam(k, vm); } -const char *ScriptText::GetEncodedText() +const std::string ScriptText::GetEncodedText() { static char buf[1024]; + static StringIDList seen_ids; int param_count = 0; - this->_GetEncodedText(buf, lastof(buf), param_count); - return (param_count > SCRIPT_TEXT_MAX_PARAMETERS) ? nullptr : buf; + seen_ids.clear(); + this->_GetEncodedText(buf, lastof(buf), param_count, seen_ids); + if (param_count > SCRIPT_TEXT_MAX_PARAMETERS) throw Script_FatalError(fmt::format("{}: Too many parameters", GetGameStringName(this->string))); + return buf; } -char *ScriptText::_GetEncodedText(char *p, char *lastofp, int ¶m_count) +char *ScriptText::_GetEncodedText(char *p, char *lastofp, int ¶m_count, StringIDList &seen_ids) { + const std::string &name = GetGameStringName(this->string); + + if (std::find(seen_ids.begin(), seen_ids.end(), this->string) != seen_ids.end()) throw Script_FatalError(fmt::format("{}: Circular reference detected", name)); + seen_ids.push_back(this->string); + p += Utf8Encode(p, SCC_ENCODED); p += seprintf(p, lastofp, "%X", this->string); - for (int i = 0; i < this->paramc; i++) { - if (this->params[i] != nullptr) { - p += seprintf(p, lastofp, ":\"%s\"", this->params[i]); - param_count++; - continue; - } - if (this->paramt[i] != nullptr) { - p += seprintf(p, lastofp, ":"); - p = this->paramt[i]->_GetEncodedText(p, lastofp, param_count); - continue; + + const StringParams ¶ms = GetGameStringParams(this->string); + int cur_idx = 0; + + for (const StringParam &cur_param : params) { + if (cur_idx >= this->paramc) throw Script_FatalError(fmt::format("{}: Not enough parameters", name)); + + switch (cur_param.type) { + case StringParam::RAW_STRING: + if (!std::holds_alternative(this->param[cur_idx])) throw Script_FatalError(fmt::format("{}: Parameter {} expects a raw string", name, cur_idx)); + p += seprintf(p, lastofp, ":\"%s\"", std::get(this->param[cur_idx++]).c_str()); + break; + + case StringParam::STRING: { + if (!std::holds_alternative(this->param[cur_idx])) throw Script_FatalError(fmt::format("{}: Parameter {} expects a substring", name, cur_idx)); + int count = 1; // 1 because the string id is included in consumed parameters + p += seprintf(p, lastofp, ":"); + p = std::get(this->param[cur_idx++])->_GetEncodedText(p, lastofp, count, seen_ids); + if (count != cur_param.consumes) throw Script_FatalError(fmt::format("{}: Parameter {} substring consumes {}, but expected {} to be consumed", name, cur_idx, count - 1, cur_param.consumes - 1)); + break; + } + + default: + if (cur_idx + cur_param.consumes > this->paramc) throw Script_FatalError(fmt::format("{}: Not enough parameters", name)); + for (int i = 0; i < cur_param.consumes; i++) { + if (!std::holds_alternative(this->param[cur_idx])) throw Script_FatalError(fmt::format("{}: Parameter {} expects an integer", name, cur_idx)); + p += seprintf(p, lastofp,":" OTTD_PRINTFHEX64, std::get(this->param[cur_idx++])); + } } - p += seprintf(p, lastofp,":" OTTD_PRINTFHEX64, this->parami[i]); - param_count++; + + param_count += cur_param.consumes; } + seen_ids.pop_back(); + return p; } -const char *Text::GetDecodedText() +const std::string Text::GetDecodedText() { - const char *encoded_text = this->GetEncodedText(); - if (encoded_text == nullptr) return nullptr; + const std::string &encoded_text = this->GetEncodedText(); static char buf[1024]; ::SetDParamStr(0, encoded_text); diff --git a/src/script/api/script_text.hpp b/src/script/api/script_text.hpp index 64cf2e7993566..597f2bdd74be8 100644 --- a/src/script/api/script_text.hpp +++ b/src/script/api/script_text.hpp @@ -13,6 +13,8 @@ #include "script_object.hpp" #include "../../core/alloc_type.hpp" +#include + /** * Internal parent object of all Text-like objects. * @api -all @@ -21,17 +23,17 @@ class Text : public ScriptObject { public: /** * Convert a ScriptText to a normal string. - * @return A string (in a static buffer), or nullptr. + * @return A string. * @api -all */ - virtual const char *GetEncodedText() = 0; + virtual const std::string GetEncodedText() = 0; /** * Convert a #ScriptText into a decoded normal string. - * @return A string (in a static buffer), or nullptr. + * @return A string. * @api -all */ - const char *GetDecodedText(); + const std::string GetDecodedText(); }; /** @@ -41,11 +43,10 @@ class Text : public ScriptObject { class RawText : public Text { public: RawText(const char *text); - ~RawText(); - const char *GetEncodedText() override { return this->text; } + const std::string GetEncodedText() override { return this->text; } private: - const char *text; + const std::string text; }; /** @@ -89,7 +90,6 @@ class ScriptText : public Text , public ZeroedMemoryAllocator { */ ScriptText(StringID string, ...); #endif /* DOXYGEN_API */ - ~ScriptText(); #ifndef DOXYGEN_API /** @@ -125,13 +125,14 @@ class ScriptText : public Text , public ZeroedMemoryAllocator { /** * @api -all */ - virtual const char *GetEncodedText(); + virtual const std::string GetEncodedText(); private: + using ScriptTextRef = ScriptObjectRef; + using StringIDList = std::vector; + StringID string; - char *params[SCRIPT_TEXT_MAX_PARAMETERS]; - int64 parami[SCRIPT_TEXT_MAX_PARAMETERS]; - ScriptText *paramt[SCRIPT_TEXT_MAX_PARAMETERS]; + std::variant param[SCRIPT_TEXT_MAX_PARAMETERS]; int paramc; /** @@ -140,9 +141,10 @@ class ScriptText : public Text , public ZeroedMemoryAllocator { * @param p The current position in the buffer. * @param lastofp The last position valid in the buffer. * @param param_count The number of parameters that are in the string. + * @param seen_ids The list of seen StringID. * @return The new current position in the buffer. */ - char *_GetEncodedText(char *p, char *lastofp, int ¶m_count); + char *_GetEncodedText(char *p, char *lastofp, int ¶m_count, StringIDList &seen_ids); /** * Set a parameter, where the value is the first item on the stack. diff --git a/src/script/api/script_tile.cpp b/src/script/api/script_tile.cpp index d8bcc399fa83c..f292bfd64735b 100644 --- a/src/script/api/script_tile.cpp +++ b/src/script/api/script_tile.cpp @@ -25,6 +25,7 @@ /* static */ bool ScriptTile::IsBuildable(TileIndex tile) { + EnforceDeityOrCompanyModeValid(false); if (!::IsValidTile(tile)) return false; switch (::GetTileType(tile)) { @@ -44,10 +45,10 @@ } } -/* static */ bool ScriptTile::IsBuildableRectangle(TileIndex tile, uint width, uint height) +/* static */ bool ScriptTile::IsBuildableRectangle(TileIndex tile, SQInteger width, SQInteger height) { /* Check whether we can extract valid X and Y */ - if (!::IsValidTile(tile)) return false; + if (!::IsValidTile(tile) || width < 0 || height < 0) return false; uint tx = ScriptMap::GetTileX(tile); uint ty = ScriptMap::GetTileY(tile); @@ -180,21 +181,21 @@ return (Slope)::ComplementSlope((::Slope)slope); } -/* static */ int32 ScriptTile::GetMinHeight(TileIndex tile) +/* static */ SQInteger ScriptTile::GetMinHeight(TileIndex tile) { if (!::IsValidTile(tile)) return -1; return ::GetTileZ(tile); } -/* static */ int32 ScriptTile::GetMaxHeight(TileIndex tile) +/* static */ SQInteger ScriptTile::GetMaxHeight(TileIndex tile) { if (!::IsValidTile(tile)) return -1; return ::GetTileMaxZ(tile); } -/* static */ int32 ScriptTile::GetCornerHeight(TileIndex tile, Corner corner) +/* static */ SQInteger ScriptTile::GetCornerHeight(TileIndex tile, Corner corner) { if (!::IsValidTile(tile) || !::IsValidCorner((::Corner)corner)) return -1; @@ -224,7 +225,7 @@ } } -/* static */ int32 ScriptTile::GetCargoAcceptance(TileIndex tile, CargoID cargo_type, int width, int height, int radius) +/* static */ SQInteger ScriptTile::GetCargoAcceptance(TileIndex tile, CargoID cargo_type, SQInteger width, SQInteger height, SQInteger radius) { if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius < 0 || !ScriptCargo::IsValidCargo(cargo_type)) return -1; @@ -232,7 +233,7 @@ return acceptance[cargo_type]; } -/* static */ int32 ScriptTile::GetCargoProduction(TileIndex tile, CargoID cargo_type, int width, int height, int radius) +/* static */ SQInteger ScriptTile::GetCargoProduction(TileIndex tile, CargoID cargo_type, SQInteger width, SQInteger height, SQInteger radius) { if (!::IsValidTile(tile) || width <= 0 || height <= 0 || radius < 0 || !ScriptCargo::IsValidCargo(cargo_type)) return -1; @@ -240,43 +241,44 @@ return produced[cargo_type]; } -/* static */ int32 ScriptTile::GetDistanceManhattanToTile(TileIndex tile_from, TileIndex tile_to) +/* static */ SQInteger ScriptTile::GetDistanceManhattanToTile(TileIndex tile_from, TileIndex tile_to) { return ScriptMap::DistanceManhattan(tile_from, tile_to); } -/* static */ int32 ScriptTile::GetDistanceSquareToTile(TileIndex tile_from, TileIndex tile_to) +/* static */ SQInteger ScriptTile::GetDistanceSquareToTile(TileIndex tile_from, TileIndex tile_to) { return ScriptMap::DistanceSquare(tile_from, tile_to); } -/* static */ bool ScriptTile::RaiseTile(TileIndex tile, int32 slope) +/* static */ bool ScriptTile::RaiseTile(TileIndex tile, Slope slope) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); - EnforcePrecondition(false, tile < ::MapSize()); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, tile < ScriptMap::GetMapSize()); return ScriptObject::Command::Do(tile, (::Slope)slope, true); } -/* static */ bool ScriptTile::LowerTile(TileIndex tile, int32 slope) +/* static */ bool ScriptTile::LowerTile(TileIndex tile, Slope slope) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); - EnforcePrecondition(false, tile < ::MapSize()); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, tile < ScriptMap::GetMapSize()); return ScriptObject::Command::Do(tile, (::Slope)slope, false); } /* static */ bool ScriptTile::LevelTiles(TileIndex start_tile, TileIndex end_tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); - EnforcePrecondition(false, start_tile < ::MapSize()); - EnforcePrecondition(false, end_tile < ::MapSize()); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, start_tile < ScriptMap::GetMapSize()); + EnforcePrecondition(false, end_tile < ScriptMap::GetMapSize()); return ScriptObject::Command::Do(end_tile, start_tile, false, LM_LEVEL); } /* static */ bool ScriptTile::DemolishTile(TileIndex tile) { + EnforceDeityOrCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); return ScriptObject::Command::Do(tile); @@ -284,21 +286,21 @@ /* static */ bool ScriptTile::PlantTree(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); - return ScriptObject::Command::Do(tile, tile, TREE_INVALID); + return ScriptObject::Command::Do(tile, tile, TREE_INVALID, false); } -/* static */ bool ScriptTile::PlantTreeRectangle(TileIndex tile, uint width, uint height) +/* static */ bool ScriptTile::PlantTreeRectangle(TileIndex tile, SQInteger width, SQInteger height) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, width >= 1 && width <= 20); EnforcePrecondition(false, height >= 1 && height <= 20); TileIndex end_tile = tile + ::TileDiffXY(width - 1, height - 1); - return ScriptObject::Command::Do(tile, end_tile, TREE_INVALID); + return ScriptObject::Command::Do(tile, end_tile, TREE_INVALID, false); } /* static */ bool ScriptTile::IsWithinTownInfluence(TileIndex tile, TownID town_id) diff --git a/src/script/api/script_tile.hpp b/src/script/api/script_tile.hpp index 4ee12c6912b7f..de476ffb6976c 100644 --- a/src/script/api/script_tile.hpp +++ b/src/script/api/script_tile.hpp @@ -155,9 +155,11 @@ class ScriptTile : public ScriptObject { * @param width The width of the rectangle. * @param height The height of the rectangle. * @pre ScriptMap::IsValidTile(tile). + * @pre width >= 0. + * @pre height >= 0. * @return True if it is buildable, false if not. */ - static bool IsBuildableRectangle(TileIndex tile, uint width, uint height); + static bool IsBuildableRectangle(TileIndex tile, SQInteger width, SQInteger height); /** * Checks whether the given tile is actually a sea tile. @@ -308,7 +310,7 @@ class ScriptTile : public ScriptObject { * @pre ScriptMap::IsValidTile(tile). * @return The height of the lowest corner of the tile, ranging from 0 to 15. */ - static int32 GetMinHeight(TileIndex tile); + static SQInteger GetMinHeight(TileIndex tile); /** * Get the maximal height on a tile. @@ -317,7 +319,7 @@ class ScriptTile : public ScriptObject { * @pre ScriptMap::IsValidTile(tile). * @return The height of the highest corner of the tile, ranging from 0 to 15. */ - static int32 GetMaxHeight(TileIndex tile); + static SQInteger GetMaxHeight(TileIndex tile); /** * Get the height of a certain corner of a tile. @@ -327,7 +329,7 @@ class ScriptTile : public ScriptObject { * @pre ScriptMap::IsValidTile(tile). * @return The height of the lowest corner of the tile, ranging from 0 to 15. */ - static int32 GetCornerHeight(TileIndex tile, Corner corner); + static SQInteger GetCornerHeight(TileIndex tile, Corner corner); /** * Get the owner of the tile. @@ -372,7 +374,7 @@ class ScriptTile : public ScriptObject { * @pre radius >= 0. * @return Values below 8 mean no acceptance; the more the better. */ - static int32 GetCargoAcceptance(TileIndex tile, CargoID cargo_type, int width, int height, int radius); + static SQInteger GetCargoAcceptance(TileIndex tile, CargoID cargo_type, SQInteger width, SQInteger height, SQInteger radius); /** * Checks how many producers in the radius produces this cargo. @@ -389,7 +391,7 @@ class ScriptTile : public ScriptObject { * @pre radius >= 0. * @return The number of producers that produce this cargo within radius of the tile. */ - static int32 GetCargoProduction(TileIndex tile, CargoID cargo_type, int width, int height, int radius); + static SQInteger GetCargoProduction(TileIndex tile, CargoID cargo_type, SQInteger width, SQInteger height, SQInteger radius); /** * Get the manhattan distance from the tile to the tile. @@ -397,7 +399,7 @@ class ScriptTile : public ScriptObject { * @param tile_to The tile to get the distance to. * @return The distance between the two tiles. */ - static int32 GetDistanceManhattanToTile(TileIndex tile_from, TileIndex tile_to); + static SQInteger GetDistanceManhattanToTile(TileIndex tile_from, TileIndex tile_to); /** * Get the square distance from the tile to the tile. @@ -405,7 +407,7 @@ class ScriptTile : public ScriptObject { * @param tile_to The tile to get the distance to. * @return The distance between the two tiles. */ - static int32 GetDistanceSquareToTile(TileIndex tile_from, TileIndex tile_to); + static SQInteger GetDistanceSquareToTile(TileIndex tile_from, TileIndex tile_to); /** * Raise the given corners of the tile. The corners can be combined, @@ -416,13 +418,13 @@ class ScriptTile : public ScriptObject { * @param tile The tile to raise. * @param slope Corners to raise (SLOPE_xxx). * @pre tile < ScriptMap::GetMapSize(). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_TOO_CLOSE_TO_EDGE * @exception ScriptTile::ERR_TILE_TOO_HIGH * @return 0 means failed, 1 means success. */ - static bool RaiseTile(TileIndex tile, int32 slope); + static bool RaiseTile(TileIndex tile, Slope slope); /** * Lower the given corners of the tile. The corners can be combined, @@ -433,13 +435,13 @@ class ScriptTile : public ScriptObject { * @param tile The tile to lower. * @param slope Corners to lower (SLOPE_xxx). * @pre tile < ScriptMap::GetMapSize(). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_TOO_CLOSE_TO_EDGE * @exception ScriptTile::ERR_TILE_TOO_LOW * @return 0 means failed, 1 means success. */ - static bool LowerTile(TileIndex tile, int32 slope); + static bool LowerTile(TileIndex tile, Slope slope); /** * Level all tiles in the rectangle between start_tile and end_tile so they @@ -449,7 +451,7 @@ class ScriptTile : public ScriptObject { * @param end_tile The opposite corner of the rectangle. * @pre start_tile < ScriptMap::GetMapSize(). * @pre end_tile < ScriptMap::GetMapSize(). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptError::ERR_TOO_CLOSE_TO_EDGE * @return True if one or more tiles were leveled. @@ -473,7 +475,7 @@ class ScriptTile : public ScriptObject { * Create a random tree on a tile. * @param tile The tile to build a tree on. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and only if a tree was added on the tile. */ static bool PlantTree(TileIndex tile); @@ -486,10 +488,10 @@ class ScriptTile : public ScriptObject { * @pre ScriptMap::IsValidTile(tile). * @pre width >= 1 && width <= 20. * @pre height >= 1 && height <= 20. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and only if a tree was added on any of the tiles in the rectangle. */ - static bool PlantTreeRectangle(TileIndex tile, uint width, uint height); + static bool PlantTreeRectangle(TileIndex tile, SQInteger width, SQInteger height); /** * Find out if this tile is within the rating influence of a town. diff --git a/src/script/api/script_tilelist.cpp b/src/script/api/script_tilelist.cpp index 8266f46ff9650..ac6afdde1b9f4 100644 --- a/src/script/api/script_tilelist.cpp +++ b/src/script/api/script_tilelist.cpp @@ -53,7 +53,7 @@ void ScriptTileList::RemoveTile(TileIndex tile) * @param radius Catchment radius to test * @param bta BitmapTileArea to fill */ -static void FillIndustryCatchment(const Industry *i, int radius, BitmapTileArea &bta) +static void FillIndustryCatchment(const Industry *i, SQInteger radius, BitmapTileArea &bta) { for (TileIndex cur_tile : i->location) { if (!::IsTileType(cur_tile, MP_INDUSTRY) || ::GetIndustryIndex(cur_tile) != i->index) continue; @@ -61,9 +61,9 @@ static void FillIndustryCatchment(const Industry *i, int radius, BitmapTileArea int tx = TileX(cur_tile); int ty = TileY(cur_tile); for (int y = -radius; y <= radius; y++) { - if (ty + y < 0 || ty + y > (int)MapMaxY()) continue; + if (ty + y < 0 || ty + y > (int)Map::MaxY()) continue; for (int x = -radius; x <= radius; x++) { - if (tx + x < 0 || tx + x > (int)MapMaxX()) continue; + if (tx + x < 0 || tx + x > (int)Map::MaxX()) continue; TileIndex tile = TileXY(tx + x, ty + y); if (!IsValidTile(tile)) continue; if (::IsTileType(tile, MP_INDUSTRY) && ::GetIndustryIndex(tile) == i->index) continue; @@ -73,7 +73,7 @@ static void FillIndustryCatchment(const Industry *i, int radius, BitmapTileArea } } -ScriptTileList_IndustryAccepting::ScriptTileList_IndustryAccepting(IndustryID industry_id, int radius) +ScriptTileList_IndustryAccepting::ScriptTileList_IndustryAccepting(IndustryID industry_id, SQInteger radius) { if (!ScriptIndustry::IsValidIndustry(industry_id) || radius <= 0) return; @@ -113,7 +113,7 @@ ScriptTileList_IndustryAccepting::ScriptTileList_IndustryAccepting(IndustryID in } } -ScriptTileList_IndustryProducing::ScriptTileList_IndustryProducing(IndustryID industry_id, int radius) +ScriptTileList_IndustryProducing::ScriptTileList_IndustryProducing(IndustryID industry_id, SQInteger radius) { if (!ScriptIndustry::IsValidIndustry(industry_id) || radius <= 0) return; @@ -155,7 +155,7 @@ ScriptTileList_StationType::ScriptTileList_StationType(StationID station_id, Scr if ((station_type & ScriptStation::STATION_AIRPORT) != 0) station_type_value |= (1 << ::STATION_AIRPORT) | (1 << ::STATION_OILRIG); if ((station_type & ScriptStation::STATION_DOCK) != 0) station_type_value |= (1 << ::STATION_DOCK) | (1 << ::STATION_OILRIG); - TileArea ta(::TileXY(rect->left, rect->top), rect->right - rect->left + 1, rect->bottom - rect->top + 1); + TileArea ta(::TileXY(rect->left, rect->top), rect->Width(), rect->Height()); for (TileIndex cur_tile : ta) { if (!::IsTileType(cur_tile, MP_STATION)) continue; if (::GetStationIndex(cur_tile) != station_id) continue; diff --git a/src/script/api/script_tilelist.hpp b/src/script/api/script_tilelist.hpp index 38f08d62a89b0..5d2c9d189826d 100644 --- a/src/script/api/script_tilelist.hpp +++ b/src/script/api/script_tilelist.hpp @@ -68,7 +68,7 @@ class ScriptTileList_IndustryAccepting : public ScriptTileList { * @pre radius > 0. * @note A station part built on any of the returned tiles will give you coverage. */ - ScriptTileList_IndustryAccepting(IndustryID industry_id, int radius); + ScriptTileList_IndustryAccepting(IndustryID industry_id, SQInteger radius); }; /** @@ -86,7 +86,7 @@ class ScriptTileList_IndustryProducing : public ScriptTileList { * @pre radius > 0. * @note A station part built on any of the returned tiles will give you acceptance. */ - ScriptTileList_IndustryProducing(IndustryID industry_id, int radius); + ScriptTileList_IndustryProducing(IndustryID industry_id, SQInteger radius); }; /** diff --git a/src/script/api/script_town.cpp b/src/script/api/script_town.cpp index 78a17344412b5..c39b9e11857f6 100644 --- a/src/script/api/script_town.cpp +++ b/src/script/api/script_town.cpp @@ -22,9 +22,9 @@ #include "../../safeguards.h" -/* static */ int32 ScriptTown::GetTownCount() +/* static */ SQInteger ScriptTown::GetTownCount() { - return (int32)::Town::GetNumItems(); + return ::Town::GetNumItems(); } /* static */ bool ScriptTown::IsValidTown(TownID town_id) @@ -44,39 +44,35 @@ { CCountedPtr counter(name); - const char *text = nullptr; + EnforceDeityMode(false); + EnforcePrecondition(false, IsValidTown(town_id)); + std::string text; if (name != nullptr) { text = name->GetDecodedText(); - EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_TOWN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); } - EnforcePrecondition(false, IsValidTown(town_id)); - return ScriptObject::Command::Do(town_id, text != nullptr ? std::string{ text } : std::string{}); + return ScriptObject::Command::Do(town_id, text); } /* static */ bool ScriptTown::SetText(TownID town_id, Text *text) { CCountedPtr counter(text); - const char *encoded_text = nullptr; - if (text != nullptr) { - encoded_text = text->GetEncodedText(); - EnforcePreconditionEncodedText(false, encoded_text); - } + EnforceDeityMode(false); EnforcePrecondition(false, IsValidTown(town_id)); - return ScriptObject::Command::Do(town_id, encoded_text != nullptr ? std::string{ encoded_text } : std::string{}); + return ScriptObject::Command::Do(town_id, text != nullptr ? text->GetEncodedText() : std::string{}); } -/* static */ int32 ScriptTown::GetPopulation(TownID town_id) +/* static */ SQInteger ScriptTown::GetPopulation(TownID town_id) { if (!IsValidTown(town_id)) return -1; const Town *t = ::Town::Get(town_id); return t->cache.population; } -/* static */ int32 ScriptTown::GetHouseCount(TownID town_id) +/* static */ SQInteger ScriptTown::GetHouseCount(TownID town_id) { if (!IsValidTown(town_id)) return -1; const Town *t = ::Town::Get(town_id); @@ -90,7 +86,7 @@ return t->xy; } -/* static */ int32 ScriptTown::GetLastMonthProduction(TownID town_id, CargoID cargo_id) +/* static */ SQInteger ScriptTown::GetLastMonthProduction(TownID town_id, CargoID cargo_id) { if (!IsValidTown(town_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo_id)) return -1; @@ -100,7 +96,7 @@ return t->supplied[cargo_id].old_max; } -/* static */ int32 ScriptTown::GetLastMonthSupplied(TownID town_id, CargoID cargo_id) +/* static */ SQInteger ScriptTown::GetLastMonthSupplied(TownID town_id, CargoID cargo_id) { if (!IsValidTown(town_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo_id)) return -1; @@ -110,7 +106,7 @@ return t->supplied[cargo_id].old_act; } -/* static */ int32 ScriptTown::GetLastMonthTransportedPercentage(TownID town_id, CargoID cargo_id) +/* static */ SQInteger ScriptTown::GetLastMonthTransportedPercentage(TownID town_id, CargoID cargo_id) { if (!IsValidTown(town_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo_id)) return -1; @@ -119,7 +115,7 @@ return ::ToPercent8(t->GetPercentTransported(cargo_id)); } -/* static */ int32 ScriptTown::GetLastMonthReceived(TownID town_id, ScriptCargo::TownEffect towneffect_id) +/* static */ SQInteger ScriptTown::GetLastMonthReceived(TownID town_id, ScriptCargo::TownEffect towneffect_id) { if (!IsValidTown(town_id)) return -1; if (!ScriptCargo::IsValidTownEffect(towneffect_id)) return -1; @@ -129,18 +125,21 @@ return t->received[towneffect_id].old_act; } -/* static */ bool ScriptTown::SetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id, uint32 goal) +/* static */ bool ScriptTown::SetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id, SQInteger goal) { + EnforceDeityMode(false); EnforcePrecondition(false, IsValidTown(town_id)); EnforcePrecondition(false, ScriptCargo::IsValidTownEffect(towneffect_id)); + goal = Clamp(goal, 0, UINT32_MAX); + return ScriptObject::Command::Do(town_id, (::TownEffect)towneffect_id, goal); } -/* static */ uint32 ScriptTown::GetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id) +/* static */ SQInteger ScriptTown::GetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id) { - if (!IsValidTown(town_id)) return UINT32_MAX; - if (!ScriptCargo::IsValidTownEffect(towneffect_id)) return UINT32_MAX; + if (!IsValidTown(town_id)) return -1; + if (!ScriptCargo::IsValidTownEffect(towneffect_id)) return -1; const Town *t = ::Town::Get(town_id); @@ -157,8 +156,9 @@ } } -/* static */ bool ScriptTown::SetGrowthRate(TownID town_id, uint32 days_between_town_growth) +/* static */ bool ScriptTown::SetGrowthRate(TownID town_id, SQInteger days_between_town_growth) { + EnforceDeityMode(false); EnforcePrecondition(false, IsValidTown(town_id)); uint16 growth_rate; switch (days_between_town_growth) { @@ -173,14 +173,14 @@ default: EnforcePrecondition(false, (days_between_town_growth * DAY_TICKS / TOWN_GROWTH_TICKS) <= MAX_TOWN_GROWTH_TICKS); /* Don't use growth_rate 0 as it means GROWTH_NORMAL */ - growth_rate = std::max(days_between_town_growth * DAY_TICKS, 2u) - 1; + growth_rate = std::max(days_between_town_growth * DAY_TICKS, 2u) - 1; break; } return ScriptObject::Command::Do(town_id, growth_rate); } -/* static */ int32 ScriptTown::GetGrowthRate(TownID town_id) +/* static */ SQInteger ScriptTown::GetGrowthRate(TownID town_id) { if (!IsValidTown(town_id)) return -1; @@ -191,12 +191,12 @@ return RoundDivSU(t->growth_rate + 1, DAY_TICKS); } -/* static */ int32 ScriptTown::GetDistanceManhattanToTile(TownID town_id, TileIndex tile) +/* static */ SQInteger ScriptTown::GetDistanceManhattanToTile(TownID town_id, TileIndex tile) { return ScriptMap::DistanceManhattan(tile, GetLocation(town_id)); } -/* static */ int32 ScriptTown::GetDistanceSquareToTile(TownID town_id, TileIndex tile) +/* static */ SQInteger ScriptTown::GetDistanceSquareToTile(TownID town_id, TileIndex tile) { return ScriptMap::DistanceSquare(tile, GetLocation(town_id)); } @@ -211,7 +211,7 @@ /* static */ bool ScriptTown::HasStatue(TownID town_id) { - if (ScriptObject::GetCompany() == OWNER_DEITY) return false; + EnforceCompanyModeValid(false); if (!IsValidTown(town_id)) return false; return ::HasBit(::Town::Get(town_id)->statues, ScriptObject::GetCompany()); @@ -224,14 +224,14 @@ return ::Town::Get(town_id)->larger_town; } -/* static */ int ScriptTown::GetRoadReworkDuration(TownID town_id) +/* static */ SQInteger ScriptTown::GetRoadReworkDuration(TownID town_id) { if (!IsValidTown(town_id)) return -1; return ::Town::Get(town_id)->road_build_months; } -/* static */ int ScriptTown::GetFundBuildingsDuration(TownID town_id) +/* static */ SQInteger ScriptTown::GetFundBuildingsDuration(TownID town_id) { if (!IsValidTown(town_id)) return -1; @@ -240,13 +240,13 @@ /* static */ ScriptCompany::CompanyID ScriptTown::GetExclusiveRightsCompany(TownID town_id) { - if (ScriptObject::GetCompany() == OWNER_DEITY) return ScriptCompany::COMPANY_INVALID; + EnforceCompanyModeValid(ScriptCompany::COMPANY_INVALID); if (!IsValidTown(town_id)) return ScriptCompany::COMPANY_INVALID; return (ScriptCompany::CompanyID)(int8)::Town::Get(town_id)->exclusivity; } -/* static */ int32 ScriptTown::GetExclusiveRightsDuration(TownID town_id) +/* static */ SQInteger ScriptTown::GetExclusiveRightsDuration(TownID town_id) { if (!IsValidTown(town_id)) return -1; @@ -255,27 +255,29 @@ /* static */ bool ScriptTown::IsActionAvailable(TownID town_id, TownAction town_action) { - if (ScriptObject::GetCompany() == OWNER_DEITY) return false; + EnforceCompanyModeValid(false); if (!IsValidTown(town_id)) return false; - return HasBit(::GetMaskOfTownActions(nullptr, ScriptObject::GetCompany(), ::Town::Get(town_id)), town_action); + return HasBit(::GetMaskOfTownActions(ScriptObject::GetCompany(), ::Town::Get(town_id)), town_action); } /* static */ bool ScriptTown::PerformTownAction(TownID town_id, TownAction town_action) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidTown(town_id)); EnforcePrecondition(false, IsActionAvailable(town_id, town_action)); return ScriptObject::Command::Do(town_id, town_action); } -/* static */ bool ScriptTown::ExpandTown(TownID town_id, int houses) +/* static */ bool ScriptTown::ExpandTown(TownID town_id, SQInteger houses) { - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, IsValidTown(town_id)); EnforcePrecondition(false, houses > 0); + houses = std::min(houses, UINT32_MAX); + return ScriptObject::Command::Do(town_id, houses); } @@ -283,30 +285,30 @@ { CCountedPtr counter(name); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY || _settings_game.economy.found_town != TF_FORBIDDEN); + EnforceDeityOrCompanyModeValid(false); + EnforcePrecondition(false, ScriptCompanyMode::IsDeity() || _settings_game.economy.found_town != TF_FORBIDDEN); EnforcePrecondition(false, ::IsValidTile(tile)); EnforcePrecondition(false, size == TOWN_SIZE_SMALL || size == TOWN_SIZE_MEDIUM || size == TOWN_SIZE_LARGE) - EnforcePrecondition(false, size != TOWN_SIZE_LARGE || ScriptObject::GetCompany() == OWNER_DEITY); - if (ScriptObject::GetCompany() == OWNER_DEITY || _settings_game.economy.found_town == TF_CUSTOM_LAYOUT) { - EnforcePrecondition(false, layout == ROAD_LAYOUT_ORIGINAL || layout == ROAD_LAYOUT_BETTER_ROADS || layout == ROAD_LAYOUT_2x2 || layout == ROAD_LAYOUT_3x3); + EnforcePrecondition(false, ScriptCompanyMode::IsDeity() || size != TOWN_SIZE_LARGE); + if (ScriptCompanyMode::IsDeity() || _settings_game.economy.found_town == TF_CUSTOM_LAYOUT) { + EnforcePrecondition(false, layout >= ROAD_LAYOUT_ORIGINAL && layout <= ROAD_LAYOUT_RANDOM); } else { /* The layout parameter is ignored for AIs when custom layouts is disabled. */ layout = (RoadLayout) (byte)_settings_game.economy.town_layout; } - const char *text = nullptr; + std::string text; if (name != nullptr) { text = name->GetDecodedText(); - EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_TOWN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); } uint32 townnameparts; - if (!GenerateTownName(&townnameparts)) { + if (!GenerateTownName(ScriptObject::GetRandomizer(), &townnameparts)) { ScriptObject::SetLastError(ScriptError::ERR_NAME_IS_NOT_UNIQUE); return false; } - return ScriptObject::Command::Do(tile, (::TownSize)size, city, (::TownLayout)layout, false, townnameparts, text != nullptr ? std::string{ text } : std::string{}); + return ScriptObject::Command::Do(tile, (::TownSize)size, city, (::TownLayout)layout, false, townnameparts, text); } /* static */ ScriptTown::TownRating ScriptTown::GetRating(TownID town_id, ScriptCompany::CompanyID company_id) @@ -337,7 +339,7 @@ } } -/* static */ int ScriptTown::GetDetailedRating(TownID town_id, ScriptCompany::CompanyID company_id) +/* static */ SQInteger ScriptTown::GetDetailedRating(TownID town_id, ScriptCompany::CompanyID company_id) { if (!IsValidTown(town_id)) return TOWN_RATING_INVALID; ScriptCompany::CompanyID company = ScriptCompany::ResolveCompanyID(company_id); @@ -347,9 +349,9 @@ return t->ratings[company]; } -/* static */ bool ScriptTown::ChangeRating(TownID town_id, ScriptCompany::CompanyID company_id, int delta) +/* static */ bool ScriptTown::ChangeRating(TownID town_id, ScriptCompany::CompanyID company_id, SQInteger delta) { - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, IsValidTown(town_id)); ScriptCompany::CompanyID company = ScriptCompany::ResolveCompanyID(company_id); EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); @@ -358,13 +360,10 @@ int16 new_rating = Clamp(t->ratings[company] + delta, RATING_MINIMUM, RATING_MAXIMUM); if (new_rating == t->ratings[company]) return false; - uint16 p2 = 0; - memcpy(&p2, &new_rating, sizeof(p2)); - - return ScriptObject::Command::Do(town_id, (::CompanyID)company_id, p2); + return ScriptObject::Command::Do(town_id, (::CompanyID)company_id, new_rating); } -/* static */ int ScriptTown::GetAllowedNoise(TownID town_id) +/* static */ SQInteger ScriptTown::GetAllowedNoise(TownID town_id) { if (!IsValidTown(town_id)) return -1; diff --git a/src/script/api/script_town.hpp b/src/script/api/script_town.hpp index 6ae7ee33f566b..bd2167f0f705a 100644 --- a/src/script/api/script_town.hpp +++ b/src/script/api/script_town.hpp @@ -98,6 +98,7 @@ class ScriptTown : public ScriptObject { ROAD_LAYOUT_BETTER_ROADS = ::TL_BETTER_ROADS, ///< Extended original algorithm (min. 2 distance between roads). ROAD_LAYOUT_2x2 = ::TL_2X2_GRID, ///< Geometric 2x2 grid algorithm ROAD_LAYOUT_3x3 = ::TL_3X3_GRID, ///< Geometric 3x3 grid algorithm + ROAD_LAYOUT_RANDOM = ::TL_RANDOM, ///< Random road layout /* Custom added value, only valid for this API */ ROAD_LAYOUT_INVALID = -1, ///< The layout for invalid towns. @@ -126,7 +127,7 @@ class ScriptTown : public ScriptObject { * Gets the number of towns. * @return The number of towns. */ - static int32 GetTownCount(); + static SQInteger GetTownCount(); /** * Checks whether the given town index is valid. @@ -146,8 +147,9 @@ class ScriptTown : public ScriptObject { /** * Rename a town. * @param town_id The town to rename - * @param name The new name of the town. If null is passed, the town name will be reset to the default name. + * @param name The new name of the town. If null, or an empty string, is passed, the town name will be reset to the default name. * @pre IsValidTown(town_id). + * @pre ScriptCompanyMode::IsDeity(). * @return True if the action succeeded. * @api -ai */ @@ -156,8 +158,9 @@ class ScriptTown : public ScriptObject { /** * Set the custom text of a town, shown in the GUI. * @param town_id The town to set the custom text of. - * @param text The text to set it to (can be either a raw string, or a ScriptText object). If null is passed, the text will be removed. + * @param text The text to set it to (can be either a raw string, or a ScriptText object). If null, or an empty string, is passed, the text will be removed. * @pre IsValidTown(town_id). + * @pre ScriptCompanyMode::IsDeity(). * @return True if the action succeeded. * @api -ai */ @@ -169,7 +172,7 @@ class ScriptTown : public ScriptObject { * @pre IsValidTown(town_id). * @return The number of inhabitants. */ - static int32 GetPopulation(TownID town_id); + static SQInteger GetPopulation(TownID town_id); /** * Gets the number of houses in the town. @@ -177,7 +180,7 @@ class ScriptTown : public ScriptObject { * @pre IsValidTown(town_id). * @return The number of houses. */ - static int32 GetHouseCount(TownID town_id); + static SQInteger GetHouseCount(TownID town_id); /** * Gets the location of the town. @@ -195,7 +198,7 @@ class ScriptTown : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo_id). * @return The last month's production of the given cargo for this town. */ - static int32 GetLastMonthProduction(TownID town_id, CargoID cargo_id); + static SQInteger GetLastMonthProduction(TownID town_id, CargoID cargo_id); /** * Get the total amount of cargo supplied from a town last month. @@ -205,7 +208,7 @@ class ScriptTown : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo_id). * @return The amount of cargo supplied for transport from this town last month. */ - static int32 GetLastMonthSupplied(TownID town_id, CargoID cargo_id); + static SQInteger GetLastMonthSupplied(TownID town_id, CargoID cargo_id); /** * Get the percentage of transported production of the given cargo at a town. @@ -215,7 +218,7 @@ class ScriptTown : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo_id). * @return The percentage of given cargo transported from this town last month. */ - static int32 GetLastMonthTransportedPercentage(TownID town_id, CargoID cargo_id); + static SQInteger GetLastMonthTransportedPercentage(TownID town_id, CargoID cargo_id); /** * Get the total amount of cargo effects received by a town last month. @@ -225,19 +228,21 @@ class ScriptTown : public ScriptObject { * @pre ScriptCargo::IsValidTownEffect(cargo_id). * @return The amount of cargo received by this town last month for this cargo effect. */ - static int32 GetLastMonthReceived(TownID town_id, ScriptCargo::TownEffect towneffect_id); + static SQInteger GetLastMonthReceived(TownID town_id, ScriptCargo::TownEffect towneffect_id); /** * Set the goal of a cargo for this town. * @param town_id The index of the town. * @param towneffect_id The index of the towneffect. * @param goal The new goal. + * The value will be clamped to 0 .. MAX(uint32). * @pre IsValidTown(town_id). * @pre ScriptCargo::IsValidTownEffect(towneffect_id). + * @pre ScriptCompanyMode::IsDeity(). * @return True if the action succeeded. * @api -ai */ - static bool SetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id, uint32 goal); + static bool SetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id, SQInteger goal); /** * Get the amount of cargo that needs to be delivered (per TownEffect) for a @@ -250,7 +255,7 @@ class ScriptTown : public ScriptObject { * @note Goals can change over time. For example with a changing snowline, or * with a growing town. */ - static uint32 GetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id); + static SQInteger GetCargoGoal(TownID town_id, ScriptCargo::TownEffect towneffect_id); /** * Set the amount of days between town growth. @@ -264,7 +269,7 @@ class ScriptTown : public ScriptObject { * @note When changing the growth rate, the relative progress is preserved and scaled to the new rate. * @api -ai */ - static bool SetGrowthRate(TownID town_id, uint32 days_between_town_growth); + static bool SetGrowthRate(TownID town_id, SQInteger days_between_town_growth); /** * Get the amount of days between town growth. @@ -273,7 +278,7 @@ class ScriptTown : public ScriptObject { * @return Amount of days between town growth, or TOWN_GROWTH_NONE. * @note This function does not indicate when it will grow next. It only tells you the time between growths. */ - static int32 GetGrowthRate(TownID town_id); + static SQInteger GetGrowthRate(TownID town_id); /** * Get the manhattan distance from the tile to the ScriptTown::GetLocation() @@ -283,7 +288,7 @@ class ScriptTown : public ScriptObject { * @pre IsValidTown(town_id). * @return The distance between town and tile. */ - static int32 GetDistanceManhattanToTile(TownID town_id, TileIndex tile); + static SQInteger GetDistanceManhattanToTile(TownID town_id, TileIndex tile); /** * Get the square distance from the tile to the ScriptTown::GetLocation() @@ -293,7 +298,7 @@ class ScriptTown : public ScriptObject { * @pre IsValidTown(town_id). * @return The distance between town and tile. */ - static int32 GetDistanceSquareToTile(TownID town_id, TileIndex tile); + static SQInteger GetDistanceSquareToTile(TownID town_id, TileIndex tile); /** * Find out if this tile is within the rating influence of a town. @@ -310,7 +315,7 @@ class ScriptTown : public ScriptObject { * Find out if this town has a statue for the current company. * @param town_id The town to check. * @pre IsValidTown(town_id). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if the town has a statue. */ static bool HasStatue(TownID town_id); @@ -330,7 +335,7 @@ class ScriptTown : public ScriptObject { * @return The number of months the road reworks are still going to take. * The value 0 means that there are currently no road reworks. */ - static int GetRoadReworkDuration(TownID town_id); + static SQInteger GetRoadReworkDuration(TownID town_id); /** * Find out how long new buildings are still being funded in a town. @@ -339,13 +344,13 @@ class ScriptTown : public ScriptObject { * @return The number of months building construction is still funded. * The value 0 means that there is currently no funding. */ - static int GetFundBuildingsDuration(TownID town_id); + static SQInteger GetFundBuildingsDuration(TownID town_id); /** * Find out which company currently has the exclusive rights of this town. * @param town_id The town to check. * @pre IsValidTown(town_id). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return The company that has the exclusive rights. The value * ScriptCompany::COMPANY_INVALID means that there are currently no * exclusive rights given out to anyone. @@ -360,14 +365,14 @@ class ScriptTown : public ScriptObject { * The value 0 means that there are currently no exclusive rights * given out to anyone. */ - static int32 GetExclusiveRightsDuration(TownID town_id); + static SQInteger GetExclusiveRightsDuration(TownID town_id); /** * Find out if an action can currently be performed on the town. * @param town_id The town to perform the action on. * @param town_action The action to perform on the town. * @pre IsValidTown(town_id). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and only if the action can performed. */ static bool IsActionAvailable(TownID town_id, TownAction town_action); @@ -378,7 +383,7 @@ class ScriptTown : public ScriptObject { * @param town_action The action to perform on the town. * @pre IsValidTown(town_id). * @pre IsActionAvailable(town_id, town_action). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if the action succeeded. */ static bool PerformTownAction(TownID town_id, TownAction town_action); @@ -387,12 +392,14 @@ class ScriptTown : public ScriptObject { * Expand the town. * @param town_id The town to expand. * @param houses The amount of houses to grow the town with. + * The value will be clamped to 0 .. MAX(uint32). * @pre IsValidTown(town_id). * @pre houses > 0. + * @pre ScriptCompanyMode::IsDeity(). * @return True if the action succeeded. * @api -ai */ - static bool ExpandTown(TownID town_id, int houses); + static bool ExpandTown(TownID town_id, SQInteger houses); /** * Found a new town. @@ -400,15 +407,15 @@ class ScriptTown : public ScriptObject { * @param size The town size of the new town. * @param city True if the new town should be a city. * @param layout The town layout of the new town. - * @param name The name of the new town. Pass nullptr to use a random town name. - * @game @pre no company mode in scope || ScriptSettings.GetValue("economy.found_town") != 0. + * @param name The name of the new town. Pass null, or an empty string, to use a random town name. + * @game @pre ScriptCompanyMode::IsDeity() || ScriptSettings.GetValue("economy.found_town") != 0. * @ai @pre ScriptSettings.GetValue("economy.found_town") != 0. - * @game @pre no company mode in scope || size != TOWN_SIZE_LARGE. + * @game @pre ScriptCompanyMode::IsDeity() || size != TOWN_SIZE_LARGE. * @ai @pre size != TOWN_SIZE_LARGE. * @pre size != TOWN_SIZE_INVALID. * @pre layout != ROAD_LAYOUT_INVALID. * @return True if the action succeeded. - * @game @note Companies are restricted by the advanced setting that controls if funding towns is allowed or not. If custom road layout is forbidden and there is a company mode in scope, the layout parameter will be ignored. + * @game @note Companies are restricted by the advanced setting that controls if funding towns is allowed or not. If custom road layout is forbidden and there is a company mode in scope (ScriptCompanyMode::IsValid()), the layout parameter will be ignored. * @ai @note AIs are restricted by the advanced setting that controls if funding towns is allowed or not. If custom road layout is forbidden, the layout parameter will be ignored. */ static bool FoundTown(TileIndex tile, TownSize size, bool city, RoadLayout layout, Text *name); @@ -432,7 +439,7 @@ class ScriptTown : public ScriptObject { * @return The rating as a number between -1000 (worst) and 1000 (best). * @api -ai */ - static int GetDetailedRating(TownID town_id, ScriptCompany::CompanyID company_id); + static SQInteger GetDetailedRating(TownID town_id, ScriptCompany::CompanyID company_id); /** * Change the rating of a company within a town. @@ -442,10 +449,10 @@ class ScriptTown : public ScriptObject { * @return True if the rating was changed. * @pre IsValidTown(town_id). * @pre ScriptCompany.ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID. - * @pre no company mode in scope + * @pre ScriptCompanyMode::IsDeity(). * @api -ai */ - static bool ChangeRating(TownID town_id, ScriptCompany::CompanyID company_id, int delta); + static bool ChangeRating(TownID town_id, ScriptCompany::CompanyID company_id, SQInteger delta); /** * Get the maximum level of noise that still can be added by airports @@ -453,7 +460,7 @@ class ScriptTown : public ScriptObject { * @param town_id The town to get the allowed noise from. * @return The noise that still can be added. */ - static int GetAllowedNoise(TownID town_id); + static SQInteger GetAllowedNoise(TownID town_id); /** * Get the road layout for a town. diff --git a/src/script/api/script_tunnel.cpp b/src/script/api/script_tunnel.cpp index 04c182c1fb0da..0e1286c334af7 100644 --- a/src/script/api/script_tunnel.cpp +++ b/src/script/api/script_tunnel.cpp @@ -82,11 +82,12 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) /* static */ bool ScriptTunnel::BuildTunnel(ScriptVehicle::VehicleType vehicle_type, TileIndex start) { + EnforceDeityOrCompanyModeValid(false); EnforcePrecondition(false, ::IsValidTile(start)); EnforcePrecondition(false, vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_ROAD); EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_RAIL || ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType())); EnforcePrecondition(false, vehicle_type != ScriptVehicle::VT_ROAD || ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType())); - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY || vehicle_type == ScriptVehicle::VT_ROAD); + EnforcePrecondition(false, ScriptCompanyMode::IsValid() || vehicle_type == ScriptVehicle::VT_ROAD); if (vehicle_type == ScriptVehicle::VT_RAIL) { /* For rail we do nothing special */ @@ -99,6 +100,8 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) /* static */ bool ScriptTunnel::_BuildTunnelRoad1() { + EnforceDeityOrCompanyModeValid(false); + /* Build the piece of road on the 'start' side of the tunnel */ TileIndex end = ScriptObject::GetCallbackVariable(0); TileIndex start = ScriptTunnel::GetOtherTunnelEnd(end); @@ -111,6 +114,8 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) /* static */ bool ScriptTunnel::_BuildTunnelRoad2() { + EnforceDeityOrCompanyModeValid(false); + /* Build the piece of road on the 'end' side of the tunnel */ TileIndex end = ScriptObject::GetCallbackVariable(0); TileIndex start = ScriptTunnel::GetOtherTunnelEnd(end); @@ -123,7 +128,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) /* static */ bool ScriptTunnel::RemoveTunnel(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsTunnelTile(tile)); return ScriptObject::Command::Do(tile); diff --git a/src/script/api/script_tunnel.hpp b/src/script/api/script_tunnel.hpp index b096dbcd06c20..5f226370b461d 100644 --- a/src/script/api/script_tunnel.hpp +++ b/src/script/api/script_tunnel.hpp @@ -85,7 +85,7 @@ class ScriptTunnel : public ScriptObject { * @pre ScriptMap::IsValidTile(start). * @pre (vehicle_type == ScriptVehicle::VT_ROAD && ScriptRoad::IsRoadTypeAvailable(ScriptRoad::GetCurrentRoadType())) || * (vehicle_type == ScriptVehicle::VT_RAIL && ScriptRail::IsRailTypeAvailable(ScriptRail::GetCurrentRailType())). - * @game @pre Outside CompanyMode: vehicle_type == ScriptVehicle::VT_ROAD. + * @game @pre ScriptCompanyMode::IsValid() || vehicle_type == ScriptVehicle::VT_ROAD. * @exception ScriptError::ERR_AREA_NOT_CLEAR * @exception ScriptTunnel::ERR_TUNNEL_CANNOT_BUILD_ON_WATER * @exception ScriptTunnel::ERR_TUNNEL_START_SITE_UNSUITABLE @@ -95,7 +95,7 @@ class ScriptTunnel : public ScriptObject { * @note The slope of a tile can be determined by ScriptTile::GetSlope(TileIndex). * @note No matter if the road pieces were build or not, if building the * tunnel succeeded, this function returns true. - * @game @note Building a bridge (without CompanyMode) results in a bridge owned by towns. + * @game @note Building a tunnel as deity (ScriptCompanyMode::IsDeity()) results in a tunnel owned by towns. */ static bool BuildTunnel(ScriptVehicle::VehicleType vehicle_type, TileIndex start); @@ -103,7 +103,7 @@ class ScriptTunnel : public ScriptObject { * Remove the tunnel whose entrance is located at tile. * @param tile The tile that is an entrance to a tunnel. * @pre ScriptMap::IsValidTile(tile) && IsTunnelTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_OWNED_BY_ANOTHER_COMPANY * @return Whether the tunnel has been/can be removed or not. */ diff --git a/src/script/api/script_vehicle.cpp b/src/script/api/script_vehicle.cpp index 82db2dfce8db6..144e5e3e29ae7 100644 --- a/src/script/api/script_vehicle.cpp +++ b/src/script/api/script_vehicle.cpp @@ -12,6 +12,7 @@ #include "script_cargo.hpp" #include "script_gamesettings.hpp" #include "script_group.hpp" +#include "script_map.hpp" #include "../script_instance.hpp" #include "../../string_func.h" #include "../../strings_func.h" @@ -29,8 +30,16 @@ /* static */ bool ScriptVehicle::IsValidVehicle(VehicleID vehicle_id) { + EnforceDeityOrCompanyModeValid(false); const Vehicle *v = ::Vehicle::GetIfValid(vehicle_id); - return v != nullptr && (v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && ::Train::From(v)->IsFreeWagon())); + return v != nullptr && (v->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity()) && (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && ::Train::From(v)->IsFreeWagon())); +} + +/* static */ bool ScriptVehicle::IsPrimaryVehicle(VehicleID vehicle_id) +{ + if (!IsValidVehicle(vehicle_id)) return false; + + return ::Vehicle::Get(vehicle_id)->IsPrimaryVehicle(); } /* static */ ScriptCompany::CompanyID ScriptVehicle::GetOwner(VehicleID vehicle_id) @@ -40,7 +49,7 @@ return static_cast((int)::Vehicle::Get(vehicle_id)->owner); } -/* static */ int32 ScriptVehicle::GetNumWagons(VehicleID vehicle_id) +/* static */ SQInteger ScriptVehicle::GetNumWagons(VehicleID vehicle_id) { if (!IsValidVehicle(vehicle_id)) return -1; @@ -54,7 +63,7 @@ return num; } -/* static */ int ScriptVehicle::GetLength(VehicleID vehicle_id) +/* static */ SQInteger ScriptVehicle::GetLength(VehicleID vehicle_id) { if (!IsValidVehicle(vehicle_id)) return -1; @@ -64,7 +73,7 @@ /* static */ VehicleID ScriptVehicle::_BuildVehicleInternal(TileIndex depot, EngineID engine_id, CargoID cargo) { - EnforcePrecondition(VEHICLE_INVALID, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(VEHICLE_INVALID); EnforcePrecondition(VEHICLE_INVALID, ScriptEngine::IsBuildable(engine_id)); EnforcePrecondition(VEHICLE_INVALID, cargo == CT_INVALID || ScriptCargo::IsValidCargo(cargo)); @@ -89,19 +98,19 @@ return _BuildVehicleInternal(depot, engine_id, cargo); } -/* static */ int ScriptVehicle::GetBuildWithRefitCapacity(TileIndex depot, EngineID engine_id, CargoID cargo) +/* static */ SQInteger ScriptVehicle::GetBuildWithRefitCapacity(TileIndex depot, EngineID engine_id, CargoID cargo) { if (!ScriptEngine::IsBuildable(engine_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; - auto [res, veh_id, refit_capacity, refit_mail] = ::Command::Do(DC_QUERY_COST, depot, engine_id, true, cargo, INVALID_CLIENT_ID); + auto [res, veh_id, refit_capacity, refit_mail, cargo_capacities] = ::Command::Do(DC_QUERY_COST, depot, engine_id, true, cargo, INVALID_CLIENT_ID); return res.Succeeded() ? refit_capacity : -1; } /* static */ VehicleID ScriptVehicle::CloneVehicle(TileIndex depot, VehicleID vehicle_id, bool share_orders) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); - EnforcePrecondition(false, IsValidVehicle(vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, IsPrimaryVehicle(vehicle_id)); if (!ScriptObject::Command::Do(&ScriptInstance::DoCommandReturnVehicleID, depot, vehicle_id, share_orders)) return VEHICLE_INVALID; @@ -109,9 +118,9 @@ return 0; } -/* static */ bool ScriptVehicle::_MoveWagonInternal(VehicleID source_vehicle_id, int source_wagon, bool move_attached_wagons, int dest_vehicle_id, int dest_wagon) +/* static */ bool ScriptVehicle::_MoveWagonInternal(VehicleID source_vehicle_id, SQInteger source_wagon, bool move_attached_wagons, SQInteger dest_vehicle_id, SQInteger dest_wagon) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicle(source_vehicle_id) && source_wagon < GetNumWagons(source_vehicle_id)); EnforcePrecondition(false, dest_vehicle_id == -1 || (IsValidVehicle(dest_vehicle_id) && dest_wagon < GetNumWagons(dest_vehicle_id))); EnforcePrecondition(false, ::Vehicle::Get(source_vehicle_id)->type == VEH_TRAIN); @@ -128,28 +137,28 @@ return ScriptObject::Command::Do(v->index, w == nullptr ? ::INVALID_VEHICLE : w->index, move_attached_wagons); } -/* static */ bool ScriptVehicle::MoveWagon(VehicleID source_vehicle_id, int source_wagon, int dest_vehicle_id, int dest_wagon) +/* static */ bool ScriptVehicle::MoveWagon(VehicleID source_vehicle_id, SQInteger source_wagon, SQInteger dest_vehicle_id, SQInteger dest_wagon) { return _MoveWagonInternal(source_vehicle_id, source_wagon, false, dest_vehicle_id, dest_wagon); } -/* static */ bool ScriptVehicle::MoveWagonChain(VehicleID source_vehicle_id, int source_wagon, int dest_vehicle_id, int dest_wagon) +/* static */ bool ScriptVehicle::MoveWagonChain(VehicleID source_vehicle_id, SQInteger source_wagon, SQInteger dest_vehicle_id, SQInteger dest_wagon) { return _MoveWagonInternal(source_vehicle_id, source_wagon, true, dest_vehicle_id, dest_wagon); } -/* static */ int ScriptVehicle::GetRefitCapacity(VehicleID vehicle_id, CargoID cargo) +/* static */ SQInteger ScriptVehicle::GetRefitCapacity(VehicleID vehicle_id, CargoID cargo) { if (!IsValidVehicle(vehicle_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; - auto [res, refit_capacity, refit_mail] = ::Command::Do(DC_QUERY_COST, vehicle_id, cargo, 0, false, false, 0); + auto [res, refit_capacity, refit_mail, cargo_capacities] = ::Command::Do(DC_QUERY_COST, vehicle_id, cargo, 0, false, false, 0); return res.Succeeded() ? refit_capacity : -1; } /* static */ bool ScriptVehicle::RefitVehicle(VehicleID vehicle_id, CargoID cargo) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicle(vehicle_id) && ScriptCargo::IsValidCargo(cargo)); return ScriptObject::Command::Do(vehicle_id, cargo, 0, false, false, 0); @@ -158,16 +167,16 @@ /* static */ bool ScriptVehicle::SellVehicle(VehicleID vehicle_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); const Vehicle *v = ::Vehicle::Get(vehicle_id); return ScriptObject::Command::Do(vehicle_id, v->type == VEH_TRAIN, false, INVALID_CLIENT_ID); } -/* static */ bool ScriptVehicle::_SellWagonInternal(VehicleID vehicle_id, int wagon, bool sell_attached_wagons) +/* static */ bool ScriptVehicle::_SellWagonInternal(VehicleID vehicle_id, SQInteger wagon, bool sell_attached_wagons) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforceCompanyModeValid(false); EnforcePrecondition(false, IsValidVehicle(vehicle_id) && wagon < GetNumWagons(vehicle_id)); EnforcePrecondition(false, ::Vehicle::Get(vehicle_id)->type == VEH_TRAIN); @@ -177,28 +186,28 @@ return ScriptObject::Command::Do(v->index, sell_attached_wagons, false, INVALID_CLIENT_ID); } -/* static */ bool ScriptVehicle::SellWagon(VehicleID vehicle_id, int wagon) +/* static */ bool ScriptVehicle::SellWagon(VehicleID vehicle_id, SQInteger wagon) { return _SellWagonInternal(vehicle_id, wagon, false); } -/* static */ bool ScriptVehicle::SellWagonChain(VehicleID vehicle_id, int wagon) +/* static */ bool ScriptVehicle::SellWagonChain(VehicleID vehicle_id, SQInteger wagon) { return _SellWagonInternal(vehicle_id, wagon, true); } /* static */ bool ScriptVehicle::SendVehicleToDepot(VehicleID vehicle_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); - EnforcePrecondition(false, IsValidVehicle(vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, IsPrimaryVehicle(vehicle_id)); return ScriptObject::Command::Do(vehicle_id, DepotCommand::None, {}); } /* static */ bool ScriptVehicle::SendVehicleToDepotForServicing(VehicleID vehicle_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); - EnforcePrecondition(false, IsValidVehicle(vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, IsPrimaryVehicle(vehicle_id)); return ScriptObject::Command::Do(vehicle_id, DepotCommand::Service, {}); } @@ -217,16 +226,16 @@ /* static */ bool ScriptVehicle::StartStopVehicle(VehicleID vehicle_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); - EnforcePrecondition(false, IsValidVehicle(vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, IsPrimaryVehicle(vehicle_id)); return ScriptObject::Command::Do(vehicle_id, false); } /* static */ bool ScriptVehicle::ReverseVehicle(VehicleID vehicle_id) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); - EnforcePrecondition(false, IsValidVehicle(vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, IsPrimaryVehicle(vehicle_id)); EnforcePrecondition(false, ::Vehicle::Get(vehicle_id)->type == VEH_ROAD || ::Vehicle::Get(vehicle_id)->type == VEH_TRAIN); switch (::Vehicle::Get(vehicle_id)->type) { @@ -240,10 +249,10 @@ { CCountedPtr counter(name); - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); - EnforcePrecondition(false, IsValidVehicle(vehicle_id)); + EnforceCompanyModeValid(false); + EnforcePrecondition(false, IsPrimaryVehicle(vehicle_id)); EnforcePrecondition(false, name != nullptr); - const char *text = name->GetDecodedText(); + const std::string &text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_VEHICLE_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -256,8 +265,8 @@ const Vehicle *v = ::Vehicle::Get(vehicle_id); if (v->type == VEH_AIRCRAFT) { - uint x = Clamp(v->x_pos / TILE_SIZE, 0, ::MapSizeX() - 2); - uint y = Clamp(v->y_pos / TILE_SIZE, 0, ::MapSizeY() - 2); + uint x = Clamp(v->x_pos / TILE_SIZE, 0, ScriptMap::GetMapSizeX() - 2); + uint y = Clamp(v->y_pos / TILE_SIZE, 0, ScriptMap::GetMapSizeY() - 2); return ::TileXY(x, y); } @@ -271,7 +280,7 @@ return ::Vehicle::Get(vehicle_id)->engine_type; } -/* static */ EngineID ScriptVehicle::GetWagonEngineType(VehicleID vehicle_id, int wagon) +/* static */ EngineID ScriptVehicle::GetWagonEngineType(VehicleID vehicle_id, SQInteger wagon) { if (!IsValidVehicle(vehicle_id)) return INVALID_ENGINE; if (wagon >= GetNumWagons(vehicle_id)) return INVALID_ENGINE; @@ -283,29 +292,29 @@ return v->engine_type; } -/* static */ int32 ScriptVehicle::GetUnitNumber(VehicleID vehicle_id) +/* static */ SQInteger ScriptVehicle::GetUnitNumber(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return -1; + if (!IsPrimaryVehicle(vehicle_id)) return -1; return ::Vehicle::Get(vehicle_id)->unitnumber; } /* static */ char *ScriptVehicle::GetName(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return nullptr; + if (!IsPrimaryVehicle(vehicle_id)) return nullptr; ::SetDParam(0, vehicle_id); return GetString(STR_VEHICLE_NAME); } -/* static */ int32 ScriptVehicle::GetAge(VehicleID vehicle_id) +/* static */ SQInteger ScriptVehicle::GetAge(VehicleID vehicle_id) { if (!IsValidVehicle(vehicle_id)) return -1; return ::Vehicle::Get(vehicle_id)->age; } -/* static */ int32 ScriptVehicle::GetWagonAge(VehicleID vehicle_id, int wagon) +/* static */ SQInteger ScriptVehicle::GetWagonAge(VehicleID vehicle_id, SQInteger wagon) { if (!IsValidVehicle(vehicle_id)) return -1; if (wagon >= GetNumWagons(vehicle_id)) return -1; @@ -317,23 +326,23 @@ return v->age; } -/* static */ int32 ScriptVehicle::GetMaxAge(VehicleID vehicle_id) +/* static */ SQInteger ScriptVehicle::GetMaxAge(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return -1; + if (!IsPrimaryVehicle(vehicle_id)) return -1; return ::Vehicle::Get(vehicle_id)->max_age; } -/* static */ int32 ScriptVehicle::GetAgeLeft(VehicleID vehicle_id) +/* static */ SQInteger ScriptVehicle::GetAgeLeft(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return -1; + if (!IsPrimaryVehicle(vehicle_id)) return -1; return ::Vehicle::Get(vehicle_id)->max_age - ::Vehicle::Get(vehicle_id)->age; } -/* static */ int32 ScriptVehicle::GetCurrentSpeed(VehicleID vehicle_id) +/* static */ SQInteger ScriptVehicle::GetCurrentSpeed(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return -1; + if (!IsPrimaryVehicle(vehicle_id)) return -1; const ::Vehicle *v = ::Vehicle::Get(vehicle_id); return (v->vehstatus & (::VS_STOPPED | ::VS_CRASHED)) == 0 ? v->GetDisplaySpeed() : 0; // km-ish/h @@ -356,21 +365,21 @@ /* static */ Money ScriptVehicle::GetRunningCost(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return -1; + if (!IsPrimaryVehicle(vehicle_id)) return -1; return ::Vehicle::Get(vehicle_id)->GetRunningCost() >> 8; } /* static */ Money ScriptVehicle::GetProfitThisYear(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return -1; + if (!IsPrimaryVehicle(vehicle_id)) return -1; return ::Vehicle::Get(vehicle_id)->GetDisplayProfitThisYear(); } /* static */ Money ScriptVehicle::GetProfitLastYear(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return -1; + if (!IsPrimaryVehicle(vehicle_id)) return -1; return ::Vehicle::Get(vehicle_id)->GetDisplayProfitLastYear(); } @@ -403,7 +412,7 @@ return (ScriptRoad::RoadType)(int)(::RoadVehicle::Get(vehicle_id))->roadtype; } -/* static */ int32 ScriptVehicle::GetCapacity(VehicleID vehicle_id, CargoID cargo) +/* static */ SQInteger ScriptVehicle::GetCapacity(VehicleID vehicle_id, CargoID cargo) { if (!IsValidVehicle(vehicle_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; @@ -416,7 +425,7 @@ return amount; } -/* static */ int32 ScriptVehicle::GetCargoLoad(VehicleID vehicle_id, CargoID cargo) +/* static */ SQInteger ScriptVehicle::GetCargoLoad(VehicleID vehicle_id, CargoID cargo) { if (!IsValidVehicle(vehicle_id)) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; @@ -431,7 +440,7 @@ /* static */ GroupID ScriptVehicle::GetGroupID(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return ScriptGroup::GROUP_INVALID; + if (!IsPrimaryVehicle(vehicle_id)) return ScriptGroup::GROUP_INVALID; return ::Vehicle::Get(vehicle_id)->group_id; } @@ -451,30 +460,25 @@ /* static */ bool ScriptVehicle::HasSharedOrders(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return false; + if (!IsPrimaryVehicle(vehicle_id)) return false; Vehicle *v = ::Vehicle::Get(vehicle_id); return v->orders != nullptr && v->orders->GetNumVehicles() > 1; } -/* static */ int ScriptVehicle::GetReliability(VehicleID vehicle_id) +/* static */ SQInteger ScriptVehicle::GetReliability(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return -1; + if (!IsPrimaryVehicle(vehicle_id)) return -1; const Vehicle *v = ::Vehicle::Get(vehicle_id); return ::ToPercent16(v->reliability); } -/* static */ uint ScriptVehicle::GetMaximumOrderDistance(VehicleID vehicle_id) +/* static */ SQInteger ScriptVehicle::GetMaximumOrderDistance(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return 0; + if (!IsPrimaryVehicle(vehicle_id)) return 0; const ::Vehicle *v = ::Vehicle::Get(vehicle_id); - switch (v->type) { - case VEH_AIRCRAFT: - return ::Aircraft::From(v)->acache.cached_max_range_sqr; - - default: - return 0; - } + if (v->type != VEH_AIRCRAFT) return 0; + return ::Aircraft::From(v)->acache.cached_max_range_sqr; } diff --git a/src/script/api/script_vehicle.hpp b/src/script/api/script_vehicle.hpp index 3c242d56fe6de..e76ffccec51fc 100644 --- a/src/script/api/script_vehicle.hpp +++ b/src/script/api/script_vehicle.hpp @@ -97,24 +97,35 @@ class ScriptVehicle : public ScriptObject { * Checks whether the given vehicle is valid and owned by you. * @param vehicle_id The vehicle to check. * @return True if and only if the vehicle is valid. + * @note Also returns true when the leading part of the vehicle is a wagon. + * Use IsPrimaryVehicle() to check for a valid vehicle with a leading engine. */ static bool IsValidVehicle(VehicleID vehicle_id); + /** + * Checks whether this is a primary vehicle. + * @param vehicle_id The vehicle to check. + * @pre IsValidVehicle(vehicle_id). + * @return True if the vehicle is a primary vehicle. + * @note Returns false when the leading part of the vehicle is a wagon. + */ + static bool IsPrimaryVehicle(VehicleID vehicle_id); + /** * Get the number of wagons a vehicle has. * @param vehicle_id The vehicle to get the number of wagons from. * @pre IsValidVehicle(vehicle_id). * @return The number of wagons the vehicle has. */ - static int32 GetNumWagons(VehicleID vehicle_id); + static SQInteger GetNumWagons(VehicleID vehicle_id); /** * Set the name of a vehicle. * @param vehicle_id The vehicle to set the name for. * @param name The name for the vehicle (can be either a raw string, or a ScriptText object). - * @pre IsValidVehicle(vehicle_id). - * @pre name != nullptr && len(name) != 0. - * @game @pre Valid ScriptCompanyMode active in scope. + * @pre IsPrimaryVehicle(vehicle_id). + * @pre name != null && len(name) != 0. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE * @return True if and only if the name was changed. */ @@ -123,7 +134,7 @@ class ScriptVehicle : public ScriptObject { /** * Get the name of a vehicle. * @param vehicle_id The vehicle to get the name of. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @return The name the vehicle has. */ static char *GetName(VehicleID vehicle_id); @@ -161,15 +172,15 @@ class ScriptVehicle : public ScriptObject { * @pre wagon < GetNumWagons(vehicle_id). * @return The engine type the vehicle has. */ - static EngineID GetWagonEngineType(VehicleID vehicle_id, int wagon); + static EngineID GetWagonEngineType(VehicleID vehicle_id, SQInteger wagon); /** * Get the unitnumber of a vehicle. * @param vehicle_id The vehicle to get the unitnumber of. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @return The unitnumber the vehicle has. */ - static int32 GetUnitNumber(VehicleID vehicle_id); + static SQInteger GetUnitNumber(VehicleID vehicle_id); /** * Get the current age of a vehicle. @@ -178,7 +189,7 @@ class ScriptVehicle : public ScriptObject { * @return The current age the vehicle has. * @note The age is in days. */ - static int32 GetAge(VehicleID vehicle_id); + static SQInteger GetAge(VehicleID vehicle_id); /** * Get the current age of a second (or third, etc.) engine in a train vehicle. @@ -189,36 +200,36 @@ class ScriptVehicle : public ScriptObject { * @return The current age the vehicle has. * @note The age is in days. */ - static int32 GetWagonAge(VehicleID vehicle_id, int wagon); + static SQInteger GetWagonAge(VehicleID vehicle_id, SQInteger wagon); /** * Get the maximum age of a vehicle. * @param vehicle_id The vehicle to get the age of. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @return The maximum age the vehicle has. * @note The age is in days. */ - static int32 GetMaxAge(VehicleID vehicle_id); + static SQInteger GetMaxAge(VehicleID vehicle_id); /** * Get the age a vehicle has left (maximum - current). * @param vehicle_id The vehicle to get the age of. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @return The age the vehicle has left. * @note The age is in days. */ - static int32 GetAgeLeft(VehicleID vehicle_id); + static SQInteger GetAgeLeft(VehicleID vehicle_id); /** * Get the current speed of a vehicle. * @param vehicle_id The vehicle to get the speed of. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @return The current speed of the vehicle. * @note The speed is in OpenTTD's internal speed unit. * This is mph / 1.6, which is roughly km/h. * To get km/h multiply this number by 1.00584. */ - static int32 GetCurrentSpeed(VehicleID vehicle_id); + static SQInteger GetCurrentSpeed(VehicleID vehicle_id); /** * Get the current state of a vehicle. @@ -231,7 +242,7 @@ class ScriptVehicle : public ScriptObject { /** * Get the running cost of this vehicle. * @param vehicle_id The vehicle to get the running cost of. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @return The running cost of the vehicle per year. * @note Cost is per year; divide by 365 to get per day. * @note This is not equal to ScriptEngine::GetRunningCost for Trains, because @@ -242,7 +253,7 @@ class ScriptVehicle : public ScriptObject { /** * Get the current profit of a vehicle. * @param vehicle_id The vehicle to get the profit of. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @return The current profit the vehicle has. */ static Money GetProfitThisYear(VehicleID vehicle_id); @@ -250,7 +261,7 @@ class ScriptVehicle : public ScriptObject { /** * Get the profit of last year of a vehicle. * @param vehicle_id The vehicle to get the profit of. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @return The profit the vehicle had last year. */ static Money GetProfitLastYear(VehicleID vehicle_id); @@ -305,7 +316,7 @@ class ScriptVehicle : public ScriptObject { * @pre The tile at depot has a depot that can build the engine and * is owned by you. * @pre ScriptEngine::IsBuildable(engine_id). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptVehicle::ERR_VEHICLE_TOO_MANY * @exception ScriptVehicle::ERR_VEHICLE_BUILD_DISABLED * @exception ScriptVehicle::ERR_VEHICLE_WRONG_DEPOT @@ -331,7 +342,7 @@ class ScriptVehicle : public ScriptObject { * is owned by you. * @pre ScriptEngine::IsBuildable(engine_id). * @pre ScriptCargo::IsValidCargo(cargo). - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptVehicle::ERR_VEHICLE_TOO_MANY * @exception ScriptVehicle::ERR_VEHICLE_BUILD_DISABLED * @exception ScriptVehicle::ERR_VEHICLE_WRONG_DEPOT @@ -355,7 +366,7 @@ class ScriptVehicle : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo). * @return The capacity the vehicle will have when refited. */ - static int GetBuildWithRefitCapacity(TileIndex depot, EngineID engine_id, CargoID cargo); + static SQInteger GetBuildWithRefitCapacity(TileIndex depot, EngineID engine_id, CargoID cargo); /** * Clones a vehicle at the given depot, copying or cloning its orders. @@ -363,8 +374,8 @@ class ScriptVehicle : public ScriptObject { * @param vehicle_id The vehicle to use as example for the new vehicle. * @param share_orders Should the orders be copied or shared? * @pre The tile 'depot' has a depot on it, allowing 'vehicle_id'-type vehicles. - * @pre IsValidVehicle(vehicle_id). - * @game @pre Valid ScriptCompanyMode active in scope. + * @pre IsPrimaryVehicle(vehicle_id). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptVehicle::ERR_VEHICLE_TOO_MANY * @exception ScriptVehicle::ERR_VEHICLE_BUILD_DISABLED * @exception ScriptVehicle::ERR_VEHICLE_WRONG_DEPOT @@ -385,10 +396,10 @@ class ScriptVehicle : public ScriptObject { * @pre dest_vehicle_id == -1 || (IsValidVehicle(dest_vehicle_id) && dest_wagon < GetNumWagons(dest_vehicle_id)). * @pre GetVehicleType(source_vehicle_id) == VT_RAIL. * @pre dest_vehicle_id == -1 || GetVehicleType(dest_vehicle_id) == VT_RAIL. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return Whether or not moving the wagon succeeded. */ - static bool MoveWagon(VehicleID source_vehicle_id, int source_wagon, int dest_vehicle_id, int dest_wagon); + static bool MoveWagon(VehicleID source_vehicle_id, SQInteger source_wagon, SQInteger dest_vehicle_id, SQInteger dest_wagon); /** * Move a chain of wagons after another wagon. @@ -401,10 +412,10 @@ class ScriptVehicle : public ScriptObject { * @pre dest_vehicle_id == -1 || (IsValidVehicle(dest_vehicle_id) && dest_wagon < GetNumWagons(dest_vehicle_id)). * @pre GetVehicleType(source_vehicle_id) == VT_RAIL. * @pre dest_vehicle_id == -1 || GetVehicleType(dest_vehicle_id) == VT_RAIL. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return Whether or not moving the wagons succeeded. */ - static bool MoveWagonChain(VehicleID source_vehicle_id, int source_wagon, int dest_vehicle_id, int dest_wagon); + static bool MoveWagonChain(VehicleID source_vehicle_id, SQInteger source_wagon, SQInteger dest_vehicle_id, SQInteger dest_wagon); /** * Gets the capacity of the given vehicle when refitted to the given cargo type. @@ -416,7 +427,7 @@ class ScriptVehicle : public ScriptObject { * @pre The vehicle must be stopped in the depot. * @return The capacity the vehicle will have when refited. */ - static int GetRefitCapacity(VehicleID vehicle_id, CargoID cargo); + static SQInteger GetRefitCapacity(VehicleID vehicle_id, CargoID cargo); /** * Refits a vehicle to the given cargo type. @@ -426,7 +437,7 @@ class ScriptVehicle : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo). * @pre You must own the vehicle. * @pre The vehicle must be stopped in the depot. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptVehicle::ERR_VEHICLE_CANNOT_REFIT * @exception ScriptVehicle::ERR_VEHICLE_IS_DESTROYED * @exception ScriptVehicle::ERR_VEHICLE_NOT_IN_DEPOT @@ -440,7 +451,7 @@ class ScriptVehicle : public ScriptObject { * @pre IsValidVehicle(vehicle_id). * @pre You must own the vehicle. * @pre The vehicle must be stopped in the depot. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptVehicle::ERR_VEHICLE_IS_DESTROYED * @exception ScriptVehicle::ERR_VEHICLE_NOT_IN_DEPOT * @return True if and only if the vehicle has been sold. @@ -455,12 +466,12 @@ class ScriptVehicle : public ScriptObject { * @pre wagon < GetNumWagons(vehicle_id). * @pre You must own the vehicle. * @pre The vehicle must be stopped in the depot. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptVehicle::ERR_VEHICLE_IS_DESTROYED * @exception ScriptVehicle::ERR_VEHICLE_NOT_IN_DEPOT * @return True if and only if the wagon has been sold. */ - static bool SellWagon(VehicleID vehicle_id, int wagon); + static bool SellWagon(VehicleID vehicle_id, SQInteger wagon); /** * Sells all wagons from the vehicle starting from a given position. @@ -470,19 +481,19 @@ class ScriptVehicle : public ScriptObject { * @pre wagon < GetNumWagons(vehicle_id). * @pre You must own the vehicle. * @pre The vehicle must be stopped in the depot. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptVehicle::ERR_VEHICLE_IS_DESTROYED * @exception ScriptVehicle::ERR_VEHICLE_NOT_IN_DEPOT * @return True if and only if the wagons have been sold. */ - static bool SellWagonChain(VehicleID vehicle_id, int wagon); + static bool SellWagonChain(VehicleID vehicle_id, SQInteger wagon); /** * Sends the given vehicle to a depot. If the vehicle has already been * sent to a depot it continues with its normal orders instead. * @param vehicle_id The vehicle to send to a depot. - * @pre IsValidVehicle(vehicle_id). - * @game @pre Valid ScriptCompanyMode active in scope. + * @pre IsPrimaryVehicle(vehicle_id). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptVehicle::ERR_VEHICLE_CANNOT_SEND_TO_DEPOT * @return True if the current order was changed. */ @@ -492,8 +503,8 @@ class ScriptVehicle : public ScriptObject { * Sends the given vehicle to a depot for servicing. If the vehicle has * already been sent to a depot it continues with its normal orders instead. * @param vehicle_id The vehicle to send to a depot for servicing. - * @pre IsValidVehicle(vehicle_id). - * @game @pre Valid ScriptCompanyMode active in scope. + * @pre IsPrimaryVehicle(vehicle_id). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptVehicle::ERR_VEHICLE_CANNOT_SEND_TO_DEPOT * @return True if the current order was changed. */ @@ -502,8 +513,8 @@ class ScriptVehicle : public ScriptObject { /** * Starts or stops the given vehicle depending on the current state. * @param vehicle_id The vehicle to start/stop. - * @pre IsValidVehicle(vehicle_id). - * @game @pre Valid ScriptCompanyMode active in scope. + * @pre IsPrimaryVehicle(vehicle_id). + * @game @pre ScriptCompanyMode::IsValid(). * @exception ScriptVehicle::ERR_VEHICLE_CANNOT_START_STOP * @exception (For aircraft only): ScriptVehicle::ERR_VEHICLE_IN_FLIGHT * @exception (For trains only): ScriptVehicle::ERR_VEHICLE_NO_POWER @@ -514,9 +525,9 @@ class ScriptVehicle : public ScriptObject { /** * Turn the given vehicle so it'll drive the other way. * @param vehicle_id The vehicle to turn. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @pre GetVehicleType(vehicle_id) == VT_ROAD || GetVehicleType(vehicle_id) == VT_RAIL. - * @game @pre Valid ScriptCompanyMode active in scope. + * @game @pre ScriptCompanyMode::IsValid(). * @return True if and only if the vehicle has started to turn. * @note Vehicles cannot always be reversed. For example busses and trucks need to be running * and not be inside a depot. @@ -531,7 +542,7 @@ class ScriptVehicle : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo). * @return The maximum amount of the given cargo the vehicle can transport. */ - static int32 GetCapacity(VehicleID vehicle_id, CargoID cargo); + static SQInteger GetCapacity(VehicleID vehicle_id, CargoID cargo); /** * Get the length of a the total vehicle in 1/16's of a tile. @@ -540,7 +551,7 @@ class ScriptVehicle : public ScriptObject { * @pre GetVehicleType(vehicle_id) == VT_ROAD || GetVehicleType(vehicle_id) == VT_RAIL. * @return The length of the engine. */ - static int GetLength(VehicleID vehicle_id); + static SQInteger GetLength(VehicleID vehicle_id); /** * Get the amount of a specific cargo the given vehicle is transporting. @@ -550,11 +561,12 @@ class ScriptVehicle : public ScriptObject { * @pre ScriptCargo::IsValidCargo(cargo). * @return The amount of the given cargo the vehicle is currently transporting. */ - static int32 GetCargoLoad(VehicleID vehicle_id, CargoID cargo); + static SQInteger GetCargoLoad(VehicleID vehicle_id, CargoID cargo); /** * Get the group of a given vehicle. * @param vehicle_id The vehicle to get the group from. + * @pre IsPrimaryVehicle(vehicle_id). * @return The group of the given vehicle. */ static GroupID GetGroupID(VehicleID vehicle_id); @@ -571,7 +583,7 @@ class ScriptVehicle : public ScriptObject { /** * Check if the vehicle has shared orders. * @param vehicle_id The vehicle to check. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @return True if the vehicle has shared orders. */ static bool HasSharedOrders(VehicleID vehicle_id); @@ -579,10 +591,10 @@ class ScriptVehicle : public ScriptObject { /** * Get the current reliability of a vehicle. * @param vehicle_id The vehicle to check. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @return The current reliability (0-100%). */ - static int GetReliability(VehicleID vehicle_id); + static SQInteger GetReliability(VehicleID vehicle_id); /** * Get the maximum allowed distance between two orders for a vehicle. @@ -590,14 +602,14 @@ class ScriptVehicle : public ScriptObject { * map distances, you may use the result of this function to compare it * with the result of ScriptOrder::GetOrderDistance. * @param vehicle_id The vehicle to get the distance for. - * @pre IsValidVehicle(vehicle_id). + * @pre IsPrimaryVehicle(vehicle_id). * @return The maximum distance between two orders for this vehicle * or 0 if the distance is unlimited. * @note The unit of the order distances is unspecified and should * not be compared with map distances * @see ScriptOrder::GetOrderDistance */ - static uint GetMaximumOrderDistance(VehicleID vehicle_id); + static SQInteger GetMaximumOrderDistance(VehicleID vehicle_id); private: /** @@ -608,12 +620,12 @@ class ScriptVehicle : public ScriptObject { /** * Internal function used by SellWagon(Chain). */ - static bool _SellWagonInternal(VehicleID vehicle_id, int wagon, bool sell_attached_wagons); + static bool _SellWagonInternal(VehicleID vehicle_id, SQInteger wagon, bool sell_attached_wagons); /** * Internal function used by MoveWagon(Chain). */ - static bool _MoveWagonInternal(VehicleID source_vehicle_id, int source_wagon, bool move_attached_wagons, int dest_vehicle_id, int dest_wagon); + static bool _MoveWagonInternal(VehicleID source_vehicle_id, SQInteger source_wagon, bool move_attached_wagons, SQInteger dest_vehicle_id, SQInteger dest_wagon); }; #endif /* SCRIPT_VEHICLE_HPP */ diff --git a/src/script/api/script_vehiclelist.cpp b/src/script/api/script_vehiclelist.cpp index 3a4d2d135b863..0687ac366c267 100644 --- a/src/script/api/script_vehiclelist.cpp +++ b/src/script/api/script_vehiclelist.cpp @@ -20,17 +20,19 @@ ScriptVehicleList::ScriptVehicleList() { + EnforceDeityOrCompanyModeValid_Void(); for (const Vehicle *v : Vehicle::Iterate()) { - if ((v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && ::Train::From(v)->IsFreeWagon()))) this->AddItem(v->index); + if ((v->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity()) && (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && ::Train::From(v)->IsFreeWagon()))) this->AddItem(v->index); } } ScriptVehicleList_Station::ScriptVehicleList_Station(StationID station_id) { + EnforceDeityOrCompanyModeValid_Void(); if (!ScriptBaseStation::IsValidBaseStation(station_id)) return; for (const Vehicle *v : Vehicle::Iterate()) { - if ((v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && v->IsPrimaryVehicle()) { + if ((v->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity()) && v->IsPrimaryVehicle()) { for (const Order *order : v->Orders()) { if ((order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT)) && order->GetDestination() == station_id) { this->AddItem(v->index); @@ -43,6 +45,7 @@ ScriptVehicleList_Station::ScriptVehicleList_Station(StationID station_id) ScriptVehicleList_Depot::ScriptVehicleList_Depot(TileIndex tile) { + EnforceDeityOrCompanyModeValid_Void(); if (!ScriptMap::IsValidTile(tile)) return; DestinationID dest; @@ -78,7 +81,7 @@ ScriptVehicleList_Depot::ScriptVehicleList_Depot(TileIndex tile) } for (const Vehicle *v : Vehicle::Iterate()) { - if ((v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && v->IsPrimaryVehicle() && v->type == type) { + if ((v->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity()) && v->IsPrimaryVehicle() && v->type == type) { for (const Order *order : v->Orders()) { if (order->IsType(OT_GOTO_DEPOT) && order->GetDestination() == dest) { this->AddItem(v->index); @@ -91,7 +94,7 @@ ScriptVehicleList_Depot::ScriptVehicleList_Depot(TileIndex tile) ScriptVehicleList_SharedOrders::ScriptVehicleList_SharedOrders(VehicleID vehicle_id) { - if (!ScriptVehicle::IsValidVehicle(vehicle_id)) return; + if (!ScriptVehicle::IsPrimaryVehicle(vehicle_id)) return; for (const Vehicle *v = Vehicle::Get(vehicle_id)->FirstShared(); v != nullptr; v = v->NextShared()) { this->AddItem(v->index); @@ -100,6 +103,7 @@ ScriptVehicleList_SharedOrders::ScriptVehicleList_SharedOrders(VehicleID vehicle ScriptVehicleList_Group::ScriptVehicleList_Group(GroupID group_id) { + EnforceDeityOrCompanyModeValid_Void(); if (!ScriptGroup::IsValidGroup((ScriptGroup::GroupID)group_id)) return; for (const Vehicle *v : Vehicle::Iterate()) { @@ -111,6 +115,7 @@ ScriptVehicleList_Group::ScriptVehicleList_Group(GroupID group_id) ScriptVehicleList_DefaultGroup::ScriptVehicleList_DefaultGroup(ScriptVehicle::VehicleType vehicle_type) { + EnforceDeityOrCompanyModeValid_Void(); if (vehicle_type < ScriptVehicle::VT_RAIL || vehicle_type > ScriptVehicle::VT_AIR) return; for (const Vehicle *v : Vehicle::Iterate()) { diff --git a/src/script/api/script_viewport.cpp b/src/script/api/script_viewport.cpp index 86a4c12dbdaef..b5f85850974aa 100644 --- a/src/script/api/script_viewport.cpp +++ b/src/script/api/script_viewport.cpp @@ -28,7 +28,7 @@ /* static */ bool ScriptViewport::ScrollEveryoneTo(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, ScriptMap::IsValidTile(tile)); return ScriptObject::Command::Do(tile, VST_EVERYONE, 0); @@ -36,7 +36,7 @@ /* static */ bool ScriptViewport::ScrollCompanyClientsTo(ScriptCompany::CompanyID company, TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, ScriptMap::IsValidTile(tile)); company = ScriptCompany::ResolveCompanyID(company); @@ -48,7 +48,7 @@ /* static */ bool ScriptViewport::ScrollClientTo(ScriptClient::ClientID client, TileIndex tile) { EnforcePrecondition(false, ScriptGame::IsMultiplayer()); - EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforceDeityMode(false); EnforcePrecondition(false, ScriptMap::IsValidTile(tile)); client = ScriptClient::ResolveClientID(client); diff --git a/src/script/api/script_viewport.hpp b/src/script/api/script_viewport.hpp index 81612031dc6f7..49a8bca333aaa 100644 --- a/src/script/api/script_viewport.hpp +++ b/src/script/api/script_viewport.hpp @@ -33,8 +33,9 @@ class ScriptViewport : public ScriptObject { * Scroll the viewport of all players to the given tile, * where the tile will be in the center of the screen. * @param tile The tile to put in the center of the screen. - * @pre ScriptObject::GetCompany() == OWNER_DEITY + * @pre ScriptCompanyMode::IsDeity(). * @pre ScriptMap::IsValidTile(tile) + * @return True iff the command was executed successfully. */ static bool ScrollEveryoneTo(TileIndex tile); @@ -43,9 +44,10 @@ class ScriptViewport : public ScriptObject { * where the tile will be in the center of the screen. * @param company The company which players to scroll the viewport of. * @param tile The tile to put in the center of the screen. - * @pre ScriptObject::GetCompany() == OWNER_DEITY + * @pre ScriptCompanyMode::IsDeity(). * @pre ScriptMap::IsValidTile(tile) * @pre ResolveCompanyID(company) != COMPANY_INVALID + * @return True iff the command was executed successfully. */ static bool ScrollCompanyClientsTo(ScriptCompany::CompanyID company, TileIndex tile); @@ -55,9 +57,10 @@ class ScriptViewport : public ScriptObject { * @param client The client to scroll the viewport of. * @param tile The tile to put in the center of the screen. * @pre ScriptGame::IsMultiplayer() - * @pre ScriptObject::GetCompany() == OWNER_DEITY + * @pre ScriptCompanyMode::IsDeity(). * @pre ScriptMap::IsValidTile(tile) * @pre ResolveClientID(client) != CLIENT_INVALID + * @return True iff the command was executed successfully. */ static bool ScrollClientTo(ScriptClient::ClientID client, TileIndex tile); }; diff --git a/src/script/api/script_waypoint.cpp b/src/script/api/script_waypoint.cpp index 8bc36950412b9..5f7bceaa61108 100644 --- a/src/script/api/script_waypoint.cpp +++ b/src/script/api/script_waypoint.cpp @@ -17,8 +17,9 @@ /* static */ bool ScriptWaypoint::IsValidWaypoint(StationID waypoint_id) { + EnforceDeityOrCompanyModeValid(false); const Waypoint *wp = ::Waypoint::GetIfValid(waypoint_id); - return wp != nullptr && (wp->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || wp->owner == OWNER_NONE); + return wp != nullptr && (wp->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity() || wp->owner == OWNER_NONE); } /* static */ StationID ScriptWaypoint::GetWaypointID(TileIndex tile) diff --git a/src/script/api/script_waypointlist.cpp b/src/script/api/script_waypointlist.cpp index 1c0a804d1cdeb..5e1e1ca07954a 100644 --- a/src/script/api/script_waypointlist.cpp +++ b/src/script/api/script_waypointlist.cpp @@ -17,15 +17,16 @@ ScriptWaypointList::ScriptWaypointList(ScriptWaypoint::WaypointType waypoint_type) { + EnforceDeityOrCompanyModeValid_Void(); for (const Waypoint *wp : Waypoint::Iterate()) { if ((wp->facilities & waypoint_type) && - (wp->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || wp->owner == OWNER_NONE)) this->AddItem(wp->index); + (wp->owner == ScriptObject::GetCompany() || ScriptCompanyMode::IsDeity() || wp->owner == OWNER_NONE)) this->AddItem(wp->index); } } ScriptWaypointList_Vehicle::ScriptWaypointList_Vehicle(VehicleID vehicle_id) { - if (!ScriptVehicle::IsValidVehicle(vehicle_id)) return; + if (!ScriptVehicle::IsPrimaryVehicle(vehicle_id)) return; const Vehicle *v = ::Vehicle::Get(vehicle_id); diff --git a/src/script/api/script_window.cpp b/src/script/api/script_window.cpp index 7969380cb367f..42b5614c03842 100644 --- a/src/script/api/script_window.cpp +++ b/src/script/api/script_window.cpp @@ -15,7 +15,7 @@ #include "../../safeguards.h" -/* static */ void ScriptWindow::Close(WindowClass window, uint32 number) +/* static */ void ScriptWindow::Close(WindowClass window, SQInteger number) { if (ScriptGame::IsMultiplayer()) return; @@ -24,10 +24,12 @@ return; } + number = Clamp(number, 0, INT32_MAX); + CloseWindowById((::WindowClass)window, number); } -/* static */ bool ScriptWindow::IsOpen(WindowClass window, uint32 number) +/* static */ bool ScriptWindow::IsOpen(WindowClass window, SQInteger number) { if (ScriptGame::IsMultiplayer()) return false; @@ -35,17 +37,22 @@ return (FindWindowByClass((::WindowClass)window) != nullptr); } + number = Clamp(number, 0, INT32_MAX); + return FindWindowById((::WindowClass)window, number) != nullptr; } -/* static */ void ScriptWindow::Highlight(WindowClass window, uint32 number, uint8 widget, TextColour colour) +/* static */ void ScriptWindow::Highlight(WindowClass window, SQInteger number, SQInteger widget, TextColour colour) { if (ScriptGame::IsMultiplayer()) return; if (number == NUMBER_ALL) return; if (!IsOpen(window, number)) return; if (colour != TC_INVALID && (::TextColour)colour >= ::TC_END) return; + number = Clamp(number, 0, INT32_MAX); + Window *w = FindWindowById((::WindowClass)window, number); + assert(w != nullptr); if (widget == WIDGET_ALL) { if (colour != TC_INVALID) return; @@ -53,6 +60,8 @@ return; } + widget = Clamp(widget, 0, UINT8_MAX); + const NWidgetBase *wid = w->GetWidget(widget); if (wid == nullptr) return; w->SetWidgetHighlight(widget, (::TextColour)colour); diff --git a/src/script/api/script_window.hpp.in b/src/script/api/script_window.hpp.in index 9d443a88a74e0..65356b48eb207 100644 --- a/src/script/api/script_window.hpp.in +++ b/src/script/api/script_window.hpp.in @@ -11,69 +11,11 @@ #define SCRIPT_WINDOW_HPP #include "script_object.hpp" -#include "../../window_type.h" -#include "../../gfx_type.h" -#include "../../widgets/ai_widget.h" -#include "../../widgets/airport_widget.h" -#include "../../widgets/autoreplace_widget.h" -#include "../../widgets/bootstrap_widget.h" -#include "../../widgets/bridge_widget.h" -#include "../../widgets/build_vehicle_widget.h" -#include "../../widgets/cheat_widget.h" -#include "../../widgets/company_widget.h" -#include "../../widgets/console_widget.h" -#include "../../widgets/date_widget.h" -#include "../../widgets/depot_widget.h" -#include "../../widgets/dock_widget.h" -#include "../../widgets/dropdown_widget.h" -#include "../../widgets/engine_widget.h" -#include "../../widgets/error_widget.h" -#include "../../widgets/fios_widget.h" -#include "../../widgets/framerate_widget.h" -#include "../../widgets/genworld_widget.h" -#include "../../widgets/goal_widget.h" -#include "../../widgets/graph_widget.h" -#include "../../widgets/group_widget.h" -#include "../../widgets/highscore_widget.h" -#include "../../widgets/industry_widget.h" -#include "../../widgets/intro_widget.h" -#include "../../widgets/main_widget.h" -#include "../../widgets/misc_widget.h" -#include "../../widgets/music_widget.h" -#include "../../widgets/network_chat_widget.h" -#include "../../widgets/network_content_widget.h" -#include "../../widgets/network_widget.h" -#include "../../widgets/newgrf_debug_widget.h" -#include "../../widgets/newgrf_widget.h" -#include "../../widgets/news_widget.h" -#include "../../widgets/object_widget.h" -#include "../../widgets/order_widget.h" -#include "../../widgets/osk_widget.h" -#include "../../widgets/pace_factor_widget.h" -#include "../../widgets/rail_widget.h" -#include "../../widgets/road_widget.h" -#include "../../widgets/screenshot_widget.h" -#include "../../widgets/settings_widget.h" -#include "../../widgets/sign_widget.h" -#include "../../widgets/smallmap_widget.h" -#include "../../widgets/station_widget.h" -#include "../../widgets/statusbar_widget.h" -#include "../../widgets/subsidy_widget.h" -#include "../../widgets/terraform_widget.h" -#include "../../widgets/timetable_widget.h" -#include "../../widgets/toolbar_widget.h" -#include "../../widgets/town_widget.h" -#include "../../widgets/transparency_widget.h" -#include "../../widgets/tree_widget.h" -#include "../../widgets/vehicle_widget.h" -#include "../../widgets/viewport_widget.h" -#include "../../widgets/waypoint_widget.h" -#include "../../widgets/link_graph_legend_widget.h" -#include "../../widgets/story_widget.h" +${INCLUDES} /** - * Class that handles window interaction. A Window in OpenTTD has two imporant + * Class that handles window interaction. A Window in OpenTTD has two important * values. The WindowClass, and a Window number. The first indicates roughly * which window it is. WC_TOWN_VIEW for example, is the view of a town. * The Window number is a bit more complex, as it depends mostly on the @@ -125,45 +67,49 @@ public: * Special number values. */ enum NumberType { - NUMBER_ALL = 0xFFFFFFFF, ///< Value to select all windows of a class. + NUMBER_ALL = -1, ///< Value to select all windows of a class. }; /** * Special widget values. */ enum WidgetType { - WIDGET_ALL = 0xFF, ///< Value to select all widgets of a window. + WIDGET_ALL = -1, ///< Value to select all widgets of a window. }; /** * Close a window. * @param window The class of the window to close. * @param number The number of the window to close, or NUMBER_ALL to close all of this class. + * The value will be clamped to 0 .. MAX(int32) when value is not NUMBER_ALL. * @pre !ScriptGame::IsMultiplayer(). */ - static void Close(WindowClass window, uint32 number); + static void Close(WindowClass window, SQInteger number); /** * Check if a window is open. * @param window The class of the window to check for. * @param number The number of the window to check for, or NUMBER_ALL to check for any in the class. + * The value will be clamped to 0 .. MAX(int32) when value is not NUMBER_ALL. * @pre !ScriptGame::IsMultiplayer(). * @return True if the window is open. */ - static bool IsOpen(WindowClass window, uint32 number); + static bool IsOpen(WindowClass window, SQInteger number); /** * Highlight a widget in a window. * @param window The class of the window to highlight a widget in. * @param number The number of the window to highlight a widget in. + * The value will be clamped to 0 .. MAX(int32) when value is not NUMBER_ALL. * @param widget The widget in the window to highlight, or WIDGET_ALL (in combination with TC_INVALID) to disable all widget highlighting on this window. + * The value will be clamped to 0 .. MAX(uint8) when value is not WIDGET_ALL. * @param colour The colour of the highlight, or TC_INVALID for disabling. * @pre !ScriptGame::IsMultiplayer(). * @pre number != NUMBER_ALL. * @pre colour < TC_END || (widget == WIDGET_ALL && colour == TC_INVALID). * @pre IsOpen(window, number). */ - static void Highlight(WindowClass window, uint32 number, uint8 widget, TextColour colour); + static void Highlight(WindowClass window, SQInteger number, SQInteger widget, TextColour colour); // @enum .*Widgets ../../widgets/*_widget.h@ENUM_WIDGETS@ // @endenum diff --git a/src/script/script_config.cpp b/src/script/script_config.cpp index 340b3b3f13028..7f4cfebb6d1dc 100644 --- a/src/script/script_config.cpp +++ b/src/script/script_config.cpp @@ -11,6 +11,7 @@ #include "../settings_type.h" #include "../core/random_func.hpp" #include "script_info.hpp" +#include "api/script_object.hpp" #include "../textfile_gui.h" #include "../string_func.h" @@ -26,6 +27,7 @@ void ScriptConfig::Change(const char *name, int version, bool force_exact_match, if (this->config_list != nullptr) delete this->config_list; this->config_list = (info == nullptr) ? nullptr : new ScriptConfigItemList(); if (this->config_list != nullptr) this->PushExtraConfigList(); + this->to_load_data.reset(); this->ClearConfigList(); @@ -34,7 +36,7 @@ void ScriptConfig::Change(const char *name, int version, bool force_exact_match, * for the Script that have the random flag to a random value. */ for (const auto &item : *this->info->GetConfigList()) { if (item.flags & SCRIPTCONFIG_RANDOM) { - this->SetSetting(item.name, InteractiveRandomRange(item.max_value + 1 - item.min_value) + item.min_value); + this->SetSetting(item.name, ScriptObject::GetRandomizer(OWNER_NONE).Next(item.max_value + 1 - item.min_value) + item.min_value); } } @@ -49,6 +51,7 @@ ScriptConfig::ScriptConfig(const ScriptConfig *config) this->version = config->version; this->config_list = nullptr; this->is_random = config->is_random; + this->to_load_data.reset(); for (const auto &item : config->settings) { this->settings[stredup(item.first)] = item.second; @@ -63,6 +66,7 @@ ScriptConfig::~ScriptConfig() free(this->name); this->ResetSettings(); if (this->config_list != nullptr) delete this->config_list; + this->to_load_data.reset(); } ScriptInfo *ScriptConfig::GetInfo() const @@ -154,7 +158,7 @@ void ScriptConfig::AddRandomDeviation() { for (const auto &item : *this->GetConfigList()) { if (item.random_deviation != 0) { - this->SetSetting(item.name, InteractiveRandomRange(item.random_deviation * 2 + 1) - item.random_deviation + this->GetSetting(item.name)); + this->SetSetting(item.name, ScriptObject::GetRandomizer(OWNER_NONE).Next(item.random_deviation * 2 + 1) - item.random_deviation + this->GetSetting(item.name)); } } } @@ -212,7 +216,7 @@ std::string ScriptConfig::SettingsToString() const char *s = string; *s = '\0'; for (const auto &item : this->settings) { - char no[10]; + char no[INT32_DIGITS_WITH_SIGN_AND_TERMINATION]; seprintf(no, lastof(no), "%d", item.second); /* Check if the string would fit in the destination */ @@ -238,3 +242,14 @@ const char *ScriptConfig::GetTextfile(TextfileType type, CompanyID slot) const return ::GetTextfile(type, (slot == OWNER_DEITY) ? GAME_DIR : AI_DIR, this->GetInfo()->GetMainScript()); } + +void ScriptConfig::SetToLoadData(ScriptInstance::ScriptData *data) +{ + this->to_load_data.reset(data); +} + +ScriptInstance::ScriptData *ScriptConfig::GetToLoadData() +{ + return this->to_load_data.get(); +} + diff --git a/src/script/script_config.hpp b/src/script/script_config.hpp index 13a136cbbf461..b243f3061f109 100644 --- a/src/script/script_config.hpp +++ b/src/script/script_config.hpp @@ -16,6 +16,10 @@ #include "../core/string_compare_type.hpp" #include "../company_type.h" #include "../textfile_gui.h" +#include "script_instance.hpp" + +/** Maximum of 10 digits for MIN / MAX_INT32, 1 for the sign and 1 for '\0'. */ +static const int INT32_DIGITS_WITH_SIGN_AND_TERMINATION = 10 + 1 + 1; /** Bitmask of flags for Script settings. */ enum ScriptConfigFlags { @@ -63,7 +67,8 @@ class ScriptConfig { version(-1), info(nullptr), config_list(nullptr), - is_random(false) + is_random(false), + to_load_data(nullptr) {} /** @@ -185,13 +190,17 @@ class ScriptConfig { */ const char *GetTextfile(TextfileType type, CompanyID slot) const; + void SetToLoadData(ScriptInstance::ScriptData *data); + ScriptInstance::ScriptData *GetToLoadData(); + protected: - const char *name; ///< Name of the Script - int version; ///< Version of the Script - class ScriptInfo *info; ///< ScriptInfo object for related to this Script version - SettingValueList settings; ///< List with all setting=>value pairs that are configure for this Script - ScriptConfigItemList *config_list; ///< List with all settings defined by this Script - bool is_random; ///< True if the AI in this slot was randomly chosen. + const char *name; ///< Name of the Script + int version; ///< Version of the Script + class ScriptInfo *info; ///< ScriptInfo object for related to this Script version + SettingValueList settings; ///< List with all setting=>value pairs that are configure for this Script + ScriptConfigItemList *config_list; ///< List with all settings defined by this Script + bool is_random; ///< True if the AI in this slot was randomly chosen. + std::unique_ptr to_load_data; ///< Data to load after the Script start. /** * In case you have mandatory non-Script-definable config entries in your diff --git a/src/script/script_gui.cpp b/src/script/script_gui.cpp new file mode 100644 index 0000000000000..1a1bca282230b --- /dev/null +++ b/src/script/script_gui.cpp @@ -0,0 +1,1255 @@ +/* + * 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 script_gui.cpp %Window for configuring the Scripts */ + +#include "../stdafx.h" +#include "../table/sprites.h" +#include "../error.h" +#include "../settings_gui.h" +#include "../querystring_gui.h" +#include "../stringfilter_type.h" +#include "../company_base.h" +#include "../company_gui.h" +#include "../window_func.h" +#include "../network/network.h" +#include "../widgets/dropdown_func.h" +#include "../hotkeys.h" +#include "../company_cmd.h" +#include "../misc_cmd.h" + +#include "script_gui.h" +#include "script_log.hpp" +#include "script_scanner.hpp" +#include "script_config.hpp" +#include "../ai/ai.hpp" +#include "../ai/ai_config.hpp" +#include "../ai/ai_info.hpp" +#include "../ai/ai_instance.hpp" +#include "../game/game.hpp" +#include "../game/game_config.hpp" +#include "../game/game_info.hpp" +#include "../game/game_instance.hpp" +#include "table/strings.h" + +#include "../safeguards.h" + + +static ScriptConfig *GetConfig(CompanyID slot) +{ + if (slot == OWNER_DEITY) return GameConfig::GetConfig(); + return AIConfig::GetConfig(slot); +} + +/** + * Window that let you choose an available Script. + */ +struct ScriptListWindow : public Window { + const ScriptInfoList *info_list; ///< The list of Scripts. + int selected; ///< The currently selected Script. + CompanyID slot; ///< The company we're selecting a new Script for. + int line_height; ///< Height of a row in the matrix widget. + Scrollbar *vscroll; ///< Cache of the vertical scrollbar. + + /** + * Constructor for the window. + * @param desc The description of the window. + * @param slot The company we're changing the Script for. + */ + ScriptListWindow(WindowDesc *desc, CompanyID slot) : Window(desc), + slot(slot) + { + if (slot == OWNER_DEITY) { + this->info_list = Game::GetUniqueInfoList(); + } else { + this->info_list = AI::GetUniqueInfoList(); + } + + this->CreateNestedTree(); + this->vscroll = this->GetScrollbar(WID_SCRL_SCROLLBAR); + this->FinishInitNested(); // Initializes 'this->line_height' as side effect. + + this->vscroll->SetCount((int)this->info_list->size() + 1); + + /* Try if we can find the currently selected AI */ + this->selected = -1; + if (GetConfig(slot)->HasScript()) { + ScriptInfo *info = GetConfig(slot)->GetInfo(); + int i = 0; + for (const auto &item : *this->info_list) { + if (item.second == info) { + this->selected = i; + break; + } + + i++; + } + } + } + + void SetStringParameters(int widget) const override + { + if (widget != WID_SCRL_CAPTION) return; + + SetDParam(0, (this->slot == OWNER_DEITY) ? STR_AI_LIST_CAPTION_GAMESCRIPT : STR_AI_LIST_CAPTION_AI); + } + + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override + { + if (widget != WID_SCRL_LIST) return; + + this->line_height = FONT_HEIGHT_NORMAL + padding.height; + + resize->width = 1; + resize->height = this->line_height; + size->height = 5 * this->line_height; + } + + void DrawWidget(const Rect &r, int widget) const override + { + switch (widget) { + case WID_SCRL_LIST: { + /* Draw a list of all available Scripts. */ + Rect tr = r.Shrink(WidgetDimensions::scaled.matrix); + /* First AI in the list is hardcoded to random */ + if (this->vscroll->IsVisible(0)) { + DrawString(tr, this->slot == OWNER_DEITY ? STR_AI_CONFIG_NONE : STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_ORANGE); + tr.top += this->line_height; + } + int i = 0; + for (const auto &item : *this->info_list) { + i++; + if (this->vscroll->IsVisible(i)) { + DrawString(tr, item.second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE); + tr.top += this->line_height; + } + } + break; + } + case WID_SCRL_INFO_BG: { + ScriptInfo *selected_info = nullptr; + int i = 0; + for (const auto &item : *this->info_list) { + i++; + if (this->selected == i - 1) selected_info = static_cast(item.second); + } + /* Some info about the currently selected Script. */ + if (selected_info != nullptr) { + Rect tr = r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect); + SetDParamStr(0, selected_info->GetAuthor()); + DrawString(tr, STR_AI_LIST_AUTHOR); + tr.top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; + SetDParam(0, selected_info->GetVersion()); + DrawString(tr, STR_AI_LIST_VERSION); + tr.top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; + if (selected_info->GetURL() != nullptr) { + SetDParamStr(0, selected_info->GetURL()); + DrawString(tr, STR_AI_LIST_URL); + tr.top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; + } + SetDParamStr(0, selected_info->GetDescription()); + DrawStringMultiLine(tr, STR_JUST_RAW_STRING, TC_WHITE); + } + break; + } + } + } + + /** + * Changes the Script of the current slot. + */ + void ChangeScript() + { + if (this->selected == -1) { + GetConfig(slot)->Change(nullptr); + } else { + ScriptInfoList::const_iterator it = this->info_list->begin(); + for (int i = 0; i < this->selected; i++) it++; + GetConfig(slot)->Change((*it).second->GetName(), (*it).second->GetVersion()); + } + InvalidateWindowData(WC_GAME_OPTIONS, slot == OWNER_DEITY ? WN_GAME_OPTIONS_GS : WN_GAME_OPTIONS_AI); + InvalidateWindowClassesData(WC_SCRIPT_SETTINGS); + CloseWindowByClass(WC_QUERY_STRING); + InvalidateWindowClassesData(WC_TEXTFILE); + } + + void OnClick(Point pt, int widget, int click_count) override + { + switch (widget) { + case WID_SCRL_LIST: { // Select one of the Scripts + int sel = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SCRL_LIST) - 1; + if (sel < (int)this->info_list->size()) { + this->selected = sel; + this->SetDirty(); + if (click_count > 1) { + this->ChangeScript(); + this->Close(); + } + } + break; + } + + case WID_SCRL_ACCEPT: { + this->ChangeScript(); + this->Close(); + break; + } + + case WID_SCRL_CANCEL: + this->Close(); + break; + } + } + + void OnResize() override + { + this->vscroll->SetCapacityFromWidget(this, WID_SCRL_LIST); + } + + /** + * Some data on this window has become invalid. + * @param data Information about the changed data. + * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. + */ + void OnInvalidateData(int data = 0, bool gui_scope = true) override + { + if (_game_mode == GM_NORMAL && Company::IsValidID(this->slot)) { + this->Close(); + return; + } + + if (!gui_scope) return; + + this->vscroll->SetCount((int)this->info_list->size() + 1); + + /* selected goes from -1 .. length of ai list - 1. */ + this->selected = std::min(this->selected, this->vscroll->GetCount() - 2); + } +}; + +/** Widgets for the AI list window. */ +static const NWidgetPart _nested_script_list_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), + NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_SCRL_CAPTION), SetDataTip(STR_AI_LIST_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_SCRL_LIST), SetMinimalSize(188, 112), SetFill(1, 1), SetResize(1, 1), SetMatrixDataTip(1, 0, STR_AI_LIST_TOOLTIP), SetScrollbar(WID_SCRL_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_SCRL_SCROLLBAR), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_MAUVE, WID_SCRL_INFO_BG), SetMinimalTextLines(8, WidgetDimensions::unscaled.framerect.Vertical() + WidgetDimensions::unscaled.vsep_normal * 3), SetResize(1, 0), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_SCRL_ACCEPT), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_LIST_ACCEPT, STR_AI_LIST_ACCEPT_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_SCRL_CANCEL), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_LIST_CANCEL, STR_AI_LIST_CANCEL_TOOLTIP), + EndContainer(), + NWidget(WWT_RESIZEBOX, COLOUR_MAUVE), + EndContainer(), +}; + +/** Window definition for the ai list window. */ +static WindowDesc _script_list_desc( + WDP_CENTER, "settings_script_list", 200, 234, + WC_SCRIPT_LIST, WC_NONE, + 0, + _nested_script_list_widgets, lengthof(_nested_script_list_widgets) +); + +/** + * Open the AI list window to chose an AI for the given company slot. + * @param slot The slot to change the AI of. + */ +void ShowScriptListWindow(CompanyID slot) +{ + CloseWindowByClass(WC_SCRIPT_LIST); + new ScriptListWindow(&_script_list_desc, slot); +} + + +/** + * Window for settings the parameters of an AI. + */ +struct ScriptSettingsWindow : public Window { + CompanyID slot; ///< The currently show company's setting. + ScriptConfig *script_config; ///< The configuration we're modifying. + int clicked_button; ///< The button we clicked. + bool clicked_increase; ///< Whether we clicked the increase or decrease button. + bool clicked_dropdown; ///< Whether the dropdown is open. + bool closing_dropdown; ///< True, if the dropdown list is currently closing. + GUITimer timeout; ///< Timeout for unclicking the button. + int clicked_row; ///< The clicked row of settings. + int line_height; ///< Height of a row in the matrix widget. + Scrollbar *vscroll; ///< Cache of the vertical scrollbar. + typedef std::vector VisibleSettingsList; ///< typdef for a vector of script settings + VisibleSettingsList visible_settings; ///< List of visible AI settings + + /** + * Constructor for the window. + * @param desc The description of the window. + * @param slot The company we're changing the settings for. + */ + ScriptSettingsWindow(WindowDesc *desc, CompanyID slot) : Window(desc), + slot(slot), + clicked_button(-1), + clicked_dropdown(false), + closing_dropdown(false), + timeout(0) + { + this->script_config = GetConfig(slot); + + this->CreateNestedTree(); + this->vscroll = this->GetScrollbar(WID_SCRS_SCROLLBAR); + this->FinishInitNested(slot); // Initializes 'this->line_height' as side effect. + + this->RebuildVisibleSettings(); + } + + /** + * Rebuilds the list of visible settings. AI settings with the flag + * AICONFIG_AI_DEVELOPER set will only be visible if the game setting + * gui.ai_developer_tools is enabled. + */ + void RebuildVisibleSettings() + { + visible_settings.clear(); + + for (const auto &item : *this->script_config->GetConfigList()) { + bool no_hide = (item.flags & SCRIPTCONFIG_DEVELOPER) == 0; + if (no_hide || _settings_client.gui.ai_developer_tools) { + visible_settings.push_back(&item); + } + } + + this->vscroll->SetCount((int)this->visible_settings.size()); + } + + void SetStringParameters(int widget) const override + { + if (widget != WID_SCRS_CAPTION) return; + + SetDParam(0, (this->slot == OWNER_DEITY) ? STR_AI_SETTINGS_CAPTION_GAMESCRIPT : STR_AI_SETTINGS_CAPTION_AI); + } + + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override + { + if (widget != WID_SCRS_BACKGROUND) return; + + this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + padding.height; + + resize->width = 1; + resize->height = this->line_height; + size->height = 5 * this->line_height; + } + + void DrawWidget(const Rect &r, int widget) const override + { + if (widget != WID_SCRS_BACKGROUND) return; + + ScriptConfig *config = this->script_config; + VisibleSettingsList::const_iterator it = this->visible_settings.begin(); + int i = 0; + for (; !this->vscroll->IsVisible(i); i++) it++; + + Rect ir = r.Shrink(WidgetDimensions::scaled.framerect); + bool rtl = _current_text_dir == TD_RTL; + Rect br = ir.WithWidth(SETTING_BUTTON_WIDTH, rtl); + Rect tr = ir.Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide, rtl); + + int y = r.top; + int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2; + int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2; + for (; this->vscroll->IsVisible(i) && it != visible_settings.end(); i++, it++) { + const ScriptConfigItem &config_item = **it; + int current_value = config->GetSetting((config_item).name); + bool editable = this->IsEditableItem(config_item); + + StringID str; + TextColour colour; + uint idx = 0; + if (StrEmpty(config_item.description)) { + if (this->slot != OWNER_DEITY && !strcmp(config_item.name, "start_date")) { + /* Build-in translation */ + str = STR_AI_SETTINGS_START_DELAY; + colour = TC_LIGHT_BLUE; + } else { + str = STR_JUST_STRING; + colour = TC_ORANGE; + } + } else { + str = STR_AI_SETTINGS_SETTING; + colour = TC_LIGHT_BLUE; + SetDParamStr(idx++, config_item.description); + } + + if ((config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0) { + DrawBoolButton(br.left, y + button_y_offset, current_value != 0, editable); + SetDParam(idx++, current_value == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON); + } else { + if (config_item.complete_labels) { + DrawDropDownButton(br.left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && clicked_dropdown, editable); + } else { + DrawArrowButtons(br.left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value); + } + if (config_item.labels != nullptr && config_item.labels->Contains(current_value)) { + SetDParam(idx++, STR_JUST_RAW_STRING); + SetDParamStr(idx++, config_item.labels->Find(current_value)->second); + } else { + SetDParam(idx++, STR_JUST_INT); + SetDParam(idx++, current_value); + } + } + + DrawString(tr.left, tr.right, y + text_y_offset, str, colour); + y += this->line_height; + } + } + + void OnPaint() override + { + if (this->closing_dropdown) { + this->closing_dropdown = false; + this->clicked_dropdown = false; + } + this->DrawWidgets(); + } + + void OnClick(Point pt, int widget, int click_count) override + { + switch (widget) { + case WID_SCRS_BACKGROUND: { + Rect r = this->GetWidget(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix, RectPadding::zero); + int num = (pt.y - r.top) / this->line_height + this->vscroll->GetPosition(); + if (num >= (int)this->visible_settings.size()) break; + + VisibleSettingsList::const_iterator it = this->visible_settings.begin(); + for (int i = 0; i < num; i++) it++; + const ScriptConfigItem config_item = **it; + if (!this->IsEditableItem(config_item)) return; + + if (this->clicked_row != num) { + this->CloseChildWindows(WC_QUERY_STRING); + HideDropDownMenu(this); + this->clicked_row = num; + this->clicked_dropdown = false; + } + + bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0; + + int x = pt.x - r.left; + if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x; + + /* One of the arrows is clicked (or green/red rect in case of bool value) */ + int old_val = this->script_config->GetSetting(config_item.name); + if (!bool_item && IsInsideMM(x, 0, SETTING_BUTTON_WIDTH) && config_item.complete_labels) { + if (this->clicked_dropdown) { + /* unclick the dropdown */ + HideDropDownMenu(this); + this->clicked_dropdown = false; + this->closing_dropdown = false; + } else { + int rel_y = (pt.y - r.top) % this->line_height; + + Rect wi_rect; + wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x); + wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1; + wi_rect.top = pt.y - rel_y + (this->line_height - SETTING_BUTTON_HEIGHT) / 2; + wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1; + + /* If the mouse is still held but dragged outside of the dropdown list, keep the dropdown open */ + if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) { + this->clicked_dropdown = true; + this->closing_dropdown = false; + + DropDownList list; + for (int i = config_item.min_value; i <= config_item.max_value; i++) { + list.emplace_back(new DropDownListCharStringItem(config_item.labels->Find(i)->second, i, false)); + } + + ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE, true); + } + } + } else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) { + int new_val = old_val; + if (bool_item) { + new_val = !new_val; + } else if (x >= SETTING_BUTTON_WIDTH / 2) { + /* Increase button clicked */ + new_val += config_item.step_size; + if (new_val > config_item.max_value) new_val = config_item.max_value; + this->clicked_increase = true; + } else { + /* Decrease button clicked */ + new_val -= config_item.step_size; + if (new_val < config_item.min_value) new_val = config_item.min_value; + this->clicked_increase = false; + } + + if (new_val != old_val) { + this->script_config->SetSetting(config_item.name, new_val); + this->clicked_button = num; + this->timeout.SetInterval(150); + } + } else if (!bool_item && !config_item.complete_labels) { + /* Display a query box so users can enter a custom value. */ + SetDParam(0, old_val); + ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, INT32_DIGITS_WITH_SIGN_AND_TERMINATION, this, CS_NUMERAL_SIGNED, QSF_NONE); + } + this->SetDirty(); + break; + } + + case WID_SCRS_ACCEPT: + this->Close(); + break; + + case WID_SCRS_RESET: + this->script_config->ResetEditableSettings(_game_mode == GM_MENU || ((this->slot != OWNER_DEITY) && !Company::IsValidID(this->slot))); + this->SetDirty(); + break; + } + } + + void OnQueryTextFinished(char *str) override + { + if (StrEmpty(str)) return; + int32 value = atoi(str); + + SetValue(value); + } + + void OnDropdownSelect(int widget, int index) override + { + assert(this->clicked_dropdown); + SetValue(index); + } + + void OnDropdownClose(Point pt, int widget, int index, bool instant_close) override + { + /* We cannot raise the dropdown button just yet. OnClick needs some hint, whether + * the same dropdown button was clicked again, and then not open the dropdown again. + * So, we only remember that it was closed, and process it on the next OnPaint, which is + * after OnClick. */ + assert(this->clicked_dropdown); + this->closing_dropdown = true; + this->SetDirty(); + } + + void OnResize() override + { + this->vscroll->SetCapacityFromWidget(this, WID_SCRS_BACKGROUND); + } + + void OnRealtimeTick(uint delta_ms) override + { + if (this->timeout.Elapsed(delta_ms)) { + this->clicked_button = -1; + this->SetDirty(); + } + } + + /** + * Some data on this window has become invalid. + * @param data Information about the changed data. + * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. + */ + void OnInvalidateData(int data = 0, bool gui_scope = true) override + { + this->RebuildVisibleSettings(); + HideDropDownMenu(this); + this->CloseChildWindows(WC_QUERY_STRING); + } + +private: + bool IsEditableItem(const ScriptConfigItem &config_item) const + { + return _game_mode == GM_MENU + || _game_mode == GM_EDITOR + || ((this->slot != OWNER_DEITY) && !Company::IsValidID(this->slot)) + || (config_item.flags & SCRIPTCONFIG_INGAME) != 0 + || _settings_client.gui.ai_developer_tools; + } + + void SetValue(int value) + { + VisibleSettingsList::const_iterator it = this->visible_settings.begin(); + for (int i = 0; i < this->clicked_row; i++) it++; + const ScriptConfigItem config_item = **it; + if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return; + this->script_config->SetSetting(config_item.name, value); + this->SetDirty(); + } +}; + +/** Widgets for the Script settings window. */ +static const NWidgetPart _nested_script_settings_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_MAUVE), + NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_SCRS_CAPTION), SetDataTip(STR_AI_SETTINGS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_SCRS_BACKGROUND), SetMinimalSize(188, 182), SetResize(1, 1), SetFill(1, 0), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_SCRS_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_SCRS_SCROLLBAR), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_SCRS_ACCEPT), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL), + NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_SCRS_RESET), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_SETTINGS_RESET, STR_NULL), + EndContainer(), + NWidget(WWT_RESIZEBOX, COLOUR_MAUVE), + EndContainer(), +}; + +/** Window definition for the Script settings window. */ +static WindowDesc _script_settings_desc( + WDP_CENTER, "settings_script", 500, 208, + WC_SCRIPT_SETTINGS, WC_NONE, + 0, + _nested_script_settings_widgets, lengthof(_nested_script_settings_widgets) +); + +/** + * Open the Script settings window to change the Script settings for a Script. + * @param slot The CompanyID of the Script to change the settings. + */ +void ShowScriptSettingsWindow(CompanyID slot) +{ + CloseWindowByClass(WC_SCRIPT_LIST); + CloseWindowByClass(WC_SCRIPT_SETTINGS); + new ScriptSettingsWindow(&_script_settings_desc, slot); +} + + +/** Window for displaying the textfile of a AI. */ +struct ScriptTextfileWindow : public TextfileWindow { + CompanyID slot; ///< View the textfile of this CompanyID slot. + + ScriptTextfileWindow(TextfileType file_type, CompanyID slot) : TextfileWindow(file_type), slot(slot) + { + this->OnInvalidateData(); + } + + void SetStringParameters(int widget) const override + { + if (widget == WID_TF_CAPTION) { + SetDParam(0, (slot == OWNER_DEITY) ? STR_CONTENT_TYPE_GAME_SCRIPT : STR_CONTENT_TYPE_AI); + SetDParamStr(1, GetConfig(slot)->GetInfo()->GetName()); + } + } + + void OnInvalidateData(int data = 0, bool gui_scope = true) override + { + const char *textfile = GetConfig(slot)->GetTextfile(file_type, slot); + if (textfile == nullptr) { + this->Close(); + } else { + this->LoadTextfile(textfile, (slot == OWNER_DEITY) ? GAME_DIR : AI_DIR); + } + } +}; + +/** + * Open the Script version of the textfile window. + * @param file_type The type of textfile to display. + * @param slot The slot the Script is using. + */ +void ShowScriptTextfileWindow(TextfileType file_type, CompanyID slot) +{ + CloseWindowById(WC_TEXTFILE, file_type); + new ScriptTextfileWindow(file_type, slot); +} + + +/** + * Set the widget colour of a button based on the + * state of the script. (dead or alive) + * @param button the button to update. + * @param dead true if the script is dead, otherwise false. + * @param paused true if the script is paused, otherwise false. + * @return true if the colour was changed and the window need to be marked as dirty. + */ +static bool SetScriptButtonColour(NWidgetCore &button, bool dead, bool paused) +{ + /* Dead scripts are indicated with red background and + * paused scripts are indicated with yellow background. */ + Colours colour = dead ? COLOUR_RED : + (paused ? COLOUR_YELLOW : COLOUR_GREY); + if (button.colour != colour) { + button.colour = colour; + return true; + } + return false; +} + +/** + * Window with everything an AI prints via ScriptLog. + */ +struct ScriptDebugWindow : public Window { + static const uint MAX_BREAK_STR_STRING_LENGTH = 256; ///< Maximum length of the break string. + + static CompanyID script_debug_company; ///< The AI that is (was last) being debugged. + int redraw_timer; ///< Timer for redrawing the window, otherwise it'll happen every tick. + int last_vscroll_pos; ///< Last position of the scrolling. + bool autoscroll; ///< Whether automatically scrolling should be enabled or not. + bool show_break_box; ///< Whether the break/debug box is visible. + static bool break_check_enabled; ///< Stop an AI when it prints a matching string + static char break_string[MAX_BREAK_STR_STRING_LENGTH]; ///< The string to match to the AI output + QueryString break_editbox; ///< Break editbox + static StringFilter break_string_filter; ///< Log filter for break. + static bool case_sensitive_break_check; ///< Is the matching done case-sensitive + int highlight_row; ///< The output row that matches the given string, or -1 + Scrollbar *vscroll; ///< Cache of the vertical scrollbar. + + ScriptLog::LogData *GetLogPointer() const + { + if (script_debug_company == OWNER_DEITY) return (ScriptLog::LogData *)Game::GetInstance()->GetLogPointer(); + return (ScriptLog::LogData *)Company::Get(script_debug_company)->ai_instance->GetLogPointer(); + } + + /** + * Check whether the currently selected AI/GS is dead. + * @return true if dead. + */ + bool IsDead() const + { + if (script_debug_company == OWNER_DEITY) { + GameInstance *game = Game::GetInstance(); + return game == nullptr || game->IsDead(); + } + return !Company::IsValidAiID(script_debug_company) || Company::Get(script_debug_company)->ai_instance->IsDead(); + } + + /** + * Check whether a company is a valid AI company or GS. + * @param company Company to check for validity. + * @return true if company is valid for debugging. + */ + bool IsValidDebugCompany(CompanyID company) const + { + switch (company) { + case INVALID_COMPANY: return false; + case OWNER_DEITY: return Game::GetInstance() != nullptr; + default: return Company::IsValidAiID(company); + } + } + + /** + * Ensure that \c script_debug_company refers to a valid AI company or GS, or is set to #INVALID_COMPANY. + * If no valid company is selected, it selects the first valid AI or GS if any. + */ + void SelectValidDebugCompany() + { + /* Check if the currently selected company is still active. */ + if (this->IsValidDebugCompany(script_debug_company)) return; + + script_debug_company = INVALID_COMPANY; + + for (const Company *c : Company::Iterate()) { + if (c->is_ai) { + ChangeToScript(c->index); + return; + } + } + + /* If no AI is available, see if there is a game script. */ + if (Game::GetInstance() != nullptr) ChangeToScript(OWNER_DEITY); + } + + /** + * Constructor for the window. + * @param desc The description of the window. + * @param number The window number (actually unused). + */ + ScriptDebugWindow(WindowDesc *desc, WindowNumber number) : Window(desc), break_editbox(MAX_BREAK_STR_STRING_LENGTH) + { + this->CreateNestedTree(); + this->vscroll = this->GetScrollbar(WID_SCRD_SCROLLBAR); + this->show_break_box = _settings_client.gui.ai_developer_tools; + this->GetWidget(WID_SCRD_BREAK_STRING_WIDGETS)->SetDisplayedPlane(this->show_break_box ? 0 : SZSP_HORIZONTAL); + this->FinishInitNested(number); + + if (!this->show_break_box) break_check_enabled = false; + + this->last_vscroll_pos = 0; + this->autoscroll = true; + this->highlight_row = -1; + + this->querystrings[WID_SCRD_BREAK_STR_EDIT_BOX] = &this->break_editbox; + + SetWidgetsDisabledState(!this->show_break_box, WID_SCRD_BREAK_STR_ON_OFF_BTN, WID_SCRD_BREAK_STR_EDIT_BOX, WID_SCRD_MATCH_CASE_BTN, WIDGET_LIST_END); + + /* Restore the break string value from static variable */ + this->break_editbox.text.Assign(this->break_string); + + this->SelectValidDebugCompany(); + this->InvalidateData(-1); + } + + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override + { + if (widget == WID_SCRD_LOG_PANEL) { + resize->height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; + size->height = 14 * resize->height + WidgetDimensions::scaled.framerect.Vertical(); + } + } + + void OnPaint() override + { + this->SelectValidDebugCompany(); + + /* Draw standard stuff */ + this->DrawWidgets(); + + if (this->IsShaded()) return; // Don't draw anything when the window is shaded. + + bool dirty = false; + + /* Paint the company icons */ + for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) { + NWidgetCore *button = this->GetWidget(i + WID_SCRD_COMPANY_BUTTON_START); + + bool valid = Company::IsValidAiID(i); + + /* Check whether the validity of the company changed */ + dirty |= (button->IsDisabled() == valid); + + /* Mark dead/paused AIs by setting the background colour. */ + bool dead = valid && Company::Get(i)->ai_instance->IsDead(); + bool paused = valid && Company::Get(i)->ai_instance->IsPaused(); + /* Re-paint if the button was updated. + * (note that it is intentional that SetScriptButtonColour is always called) */ + dirty |= SetScriptButtonColour(*button, dead, paused); + + /* Draw company icon only for valid AI companies */ + if (!valid) continue; + + byte offset = (i == script_debug_company) ? 1 : 0; + DrawCompanyIcon(i, button->pos_x + button->current_x / 2 - 7 + offset, this->GetWidget(WID_SCRD_COMPANY_BUTTON_START + i)->pos_y + 2 + offset); + } + + /* Set button colour for Game Script. */ + GameInstance *game = Game::GetInstance(); + bool valid = game != nullptr; + bool dead = valid && game->IsDead(); + bool paused = valid && game->IsPaused(); + + NWidgetCore *button = this->GetWidget(WID_SCRD_SCRIPT_GAME); + dirty |= (button->IsDisabled() == valid) || SetScriptButtonColour(*button, dead, paused); + + if (dirty) this->InvalidateData(-1); + + /* If there are no active companies, don't display anything else. */ + if (script_debug_company == INVALID_COMPANY) return; + + ScriptLog::LogData *log = this->GetLogPointer(); + + int scroll_count = (log == nullptr) ? 0 : log->used; + if (this->vscroll->GetCount() != scroll_count) { + this->vscroll->SetCount(scroll_count); + + /* We need a repaint */ + this->SetWidgetDirty(WID_SCRD_SCROLLBAR); + } + + if (log == nullptr) return; + + /* Detect when the user scrolls the window. Enable autoscroll when the + * bottom-most line becomes visible. */ + if (this->last_vscroll_pos != this->vscroll->GetPosition()) { + this->autoscroll = this->vscroll->GetPosition() >= log->used - this->vscroll->GetCapacity(); + } + if (this->autoscroll) { + int scroll_pos = std::max(0, log->used - this->vscroll->GetCapacity()); + if (this->vscroll->SetPosition(scroll_pos)) { + /* We need a repaint */ + this->SetWidgetDirty(WID_SCRD_SCROLLBAR); + this->SetWidgetDirty(WID_SCRD_LOG_PANEL); + } + } + this->last_vscroll_pos = this->vscroll->GetPosition(); + } + + void SetStringParameters(int widget) const override + { + if (widget != WID_SCRD_NAME_TEXT) return; + + if (script_debug_company == OWNER_DEITY) { + const GameInfo *info = Game::GetInfo(); + assert(info != nullptr); + SetDParam(0, STR_AI_DEBUG_NAME_AND_VERSION); + SetDParamStr(1, info->GetName()); + SetDParam(2, info->GetVersion()); + } else if (script_debug_company == INVALID_COMPANY || !Company::IsValidAiID(script_debug_company)) { + SetDParam(0, STR_EMPTY); + } else { + const AIInfo *info = Company::Get(script_debug_company)->ai_info; + assert(info != nullptr); + SetDParam(0, STR_AI_DEBUG_NAME_AND_VERSION); + SetDParamStr(1, info->GetName()); + SetDParam(2, info->GetVersion()); + } + } + + void DrawWidget(const Rect &r, int widget) const override + { + if (script_debug_company == INVALID_COMPANY) return; + + if (widget != WID_SCRD_LOG_PANEL) return; + + ScriptLog::LogData *log = this->GetLogPointer(); + if (log == nullptr) return; + + Rect br = r.Shrink(WidgetDimensions::scaled.bevel); + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); + for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < log->used; i++) { + int pos = (i + log->pos + 1 - log->used + log->count) % log->count; + if (log->lines[pos] == nullptr) break; + + TextColour colour; + switch (log->type[pos]) { + case ScriptLog::LOG_SQ_INFO: colour = TC_BLACK; break; + case ScriptLog::LOG_SQ_ERROR: colour = TC_WHITE; break; + case ScriptLog::LOG_INFO: colour = TC_BLACK; break; + case ScriptLog::LOG_WARNING: colour = TC_YELLOW; break; + case ScriptLog::LOG_ERROR: colour = TC_RED; break; + default: colour = TC_BLACK; break; + } + + /* Check if the current line should be highlighted */ + if (pos == this->highlight_row) { + GfxFillRect(br.left, tr.top, br.right, tr.top + this->resize.step_height - 1, PC_BLACK); + if (colour == TC_BLACK) colour = TC_WHITE; // Make black text readable by inverting it to white. + } + + DrawString(tr, log->lines[pos], colour, SA_LEFT | SA_FORCE); + tr.top += this->resize.step_height; + } + } + + /** + * Change all settings to select another Script. + * @param show_ai The new AI to show. + */ + void ChangeToScript(CompanyID show_script) + { + if (!this->IsValidDebugCompany(show_script)) return; + + script_debug_company = show_script; + + this->highlight_row = -1; // The highlight of one Script make little sense for another Script. + + /* Close AI settings window to prevent confusion */ + CloseWindowByClass(WC_SCRIPT_SETTINGS); + + this->InvalidateData(-1); + + this->autoscroll = true; + this->last_vscroll_pos = this->vscroll->GetPosition(); + } + + void OnClick(Point pt, int widget, int click_count) override + { + /* Also called for hotkeys, so check for disabledness */ + if (this->IsWidgetDisabled(widget)) return; + + /* Check which button is clicked */ + if (IsInsideMM(widget, WID_SCRD_COMPANY_BUTTON_START, WID_SCRD_COMPANY_BUTTON_END + 1)) { + ChangeToScript((CompanyID)(widget - WID_SCRD_COMPANY_BUTTON_START)); + } + + switch (widget) { + case WID_SCRD_SCRIPT_GAME: + ChangeToScript(OWNER_DEITY); + break; + + case WID_SCRD_RELOAD_TOGGLE: + if (script_debug_company == OWNER_DEITY) break; + /* First kill the company of the AI, then start a new one. This should start the current AI again */ + Command::Post(CCA_DELETE, script_debug_company, CRR_MANUAL, INVALID_CLIENT_ID); + Command::Post(CCA_NEW_AI, script_debug_company, CRR_NONE, INVALID_CLIENT_ID); + break; + + case WID_SCRD_SETTINGS: + ShowScriptSettingsWindow(script_debug_company); + break; + + case WID_SCRD_BREAK_STR_ON_OFF_BTN: + this->break_check_enabled = !this->break_check_enabled; + this->InvalidateData(-1); + break; + + case WID_SCRD_MATCH_CASE_BTN: + this->case_sensitive_break_check = !this->case_sensitive_break_check; + this->InvalidateData(-1); + break; + + case WID_SCRD_CONTINUE_BTN: + /* Unpause current AI / game script and mark the corresponding script button dirty. */ + if (!this->IsDead()) { + if (script_debug_company == OWNER_DEITY) { + Game::Unpause(); + } else { + AI::Unpause(script_debug_company); + } + } + + /* If the last AI/Game Script is unpaused, unpause the game too. */ + if ((_pause_mode & PM_PAUSED_NORMAL) == PM_PAUSED_NORMAL) { + bool all_unpaused = !Game::IsPaused(); + if (all_unpaused) { + for (const Company *c : Company::Iterate()) { + if (c->is_ai && AI::IsPaused(c->index)) { + all_unpaused = false; + break; + } + } + if (all_unpaused) { + /* All scripts have been unpaused => unpause the game. */ + Command::Post(PM_PAUSED_NORMAL, false); + } + } + } + + this->highlight_row = -1; + this->InvalidateData(-1); + break; + } + } + + void OnEditboxChanged(int wid) override + { + if (wid != WID_SCRD_BREAK_STR_EDIT_BOX) return; + + /* Save the current string to static member so it can be restored next time the window is opened. */ + strecpy(this->break_string, this->break_editbox.text.buf, lastof(this->break_string)); + break_string_filter.SetFilterTerm(this->break_string); + } + + /** + * Some data on this window has become invalid. + * @param data Information about the changed data. + * This is the company ID of the AI/GS which wrote a new log message, or -1 in other cases. + * @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details. + */ + void OnInvalidateData(int data = 0, bool gui_scope = true) override + { + /* If the log message is related to the active company tab, check the break string. + * This needs to be done in gameloop-scope, so the AI is suspended immediately. */ + if (!gui_scope && data == script_debug_company && this->IsValidDebugCompany(script_debug_company) && this->break_check_enabled && !this->break_string_filter.IsEmpty()) { + /* Get the log instance of the active company */ + ScriptLog::LogData *log = this->GetLogPointer(); + + if (log != nullptr) { + this->break_string_filter.ResetState(); + this->break_string_filter.AddLine(log->lines[log->pos]); + if (this->break_string_filter.GetState()) { + /* Pause execution of script. */ + if (!this->IsDead()) { + if (script_debug_company == OWNER_DEITY) { + Game::Pause(); + } else { + AI::Pause(script_debug_company); + } + } + + /* Pause the game. */ + if ((_pause_mode & PM_PAUSED_NORMAL) == PM_UNPAUSED) { + Command::Post(PM_PAUSED_NORMAL, true); + } + + /* Highlight row that matched */ + this->highlight_row = log->pos; + } + } + } + + if (!gui_scope) return; + + this->SelectValidDebugCompany(); + + ScriptLog::LogData *log = script_debug_company != INVALID_COMPANY ? this->GetLogPointer() : nullptr; + this->vscroll->SetCount((log == nullptr) ? 0 : log->used); + + /* Update company buttons */ + for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) { + this->SetWidgetDisabledState(i + WID_SCRD_COMPANY_BUTTON_START, !Company::IsValidAiID(i)); + this->SetWidgetLoweredState(i + WID_SCRD_COMPANY_BUTTON_START, script_debug_company == i); + } + + this->SetWidgetDisabledState(WID_SCRD_SCRIPT_GAME, Game::GetGameInstance() == nullptr); + this->SetWidgetLoweredState(WID_SCRD_SCRIPT_GAME, script_debug_company == OWNER_DEITY); + + this->SetWidgetLoweredState(WID_SCRD_BREAK_STR_ON_OFF_BTN, this->break_check_enabled); + this->SetWidgetLoweredState(WID_SCRD_MATCH_CASE_BTN, this->case_sensitive_break_check); + + this->SetWidgetDisabledState(WID_SCRD_SETTINGS, script_debug_company == INVALID_COMPANY); + extern CompanyID _local_company; + this->SetWidgetDisabledState(WID_SCRD_RELOAD_TOGGLE, script_debug_company == INVALID_COMPANY || script_debug_company == OWNER_DEITY || script_debug_company == _local_company); + this->SetWidgetDisabledState(WID_SCRD_CONTINUE_BTN, script_debug_company == INVALID_COMPANY || + (script_debug_company == OWNER_DEITY ? !Game::IsPaused() : !AI::IsPaused(script_debug_company))); + } + + void OnResize() override + { + this->vscroll->SetCapacityFromWidget(this, WID_SCRD_LOG_PANEL, WidgetDimensions::scaled.framerect.Vertical()); + } + + static HotkeyList hotkeys; +}; + +CompanyID ScriptDebugWindow::script_debug_company = INVALID_COMPANY; +char ScriptDebugWindow::break_string[MAX_BREAK_STR_STRING_LENGTH] = ""; +bool ScriptDebugWindow::break_check_enabled = true; +bool ScriptDebugWindow::case_sensitive_break_check = false; +StringFilter ScriptDebugWindow::break_string_filter(&ScriptDebugWindow::case_sensitive_break_check); + +/** Make a number of rows with buttons for each company for the Script debug window. */ +NWidgetBase *MakeCompanyButtonRowsScriptDebug(int *biggest_index) +{ + return MakeCompanyButtonRows(biggest_index, WID_SCRD_COMPANY_BUTTON_START, WID_SCRD_COMPANY_BUTTON_END, COLOUR_GREY, 8, STR_AI_DEBUG_SELECT_AI_TOOLTIP); +} + +/** + * Handler for global hotkeys of the ScriptDebugWindow. + * @param hotkey Hotkey + * @return ES_HANDLED if hotkey was accepted. + */ +static EventState ScriptDebugGlobalHotkeys(int hotkey) +{ + if (_game_mode != GM_NORMAL) return ES_NOT_HANDLED; + Window *w = ShowScriptDebugWindow(INVALID_COMPANY); + if (w == nullptr) return ES_NOT_HANDLED; + return w->OnHotkey(hotkey); +} + +static Hotkey scriptdebug_hotkeys[] = { + Hotkey('1', "company_1", WID_SCRD_COMPANY_BUTTON_START), + Hotkey('2', "company_2", WID_SCRD_COMPANY_BUTTON_START + 1), + Hotkey('3', "company_3", WID_SCRD_COMPANY_BUTTON_START + 2), + Hotkey('4', "company_4", WID_SCRD_COMPANY_BUTTON_START + 3), + Hotkey('5', "company_5", WID_SCRD_COMPANY_BUTTON_START + 4), + Hotkey('6', "company_6", WID_SCRD_COMPANY_BUTTON_START + 5), + Hotkey('7', "company_7", WID_SCRD_COMPANY_BUTTON_START + 6), + Hotkey('8', "company_8", WID_SCRD_COMPANY_BUTTON_START + 7), + Hotkey('9', "company_9", WID_SCRD_COMPANY_BUTTON_START + 8), + Hotkey((uint16)0, "company_10", WID_SCRD_COMPANY_BUTTON_START + 9), + Hotkey((uint16)0, "company_11", WID_SCRD_COMPANY_BUTTON_START + 10), + Hotkey((uint16)0, "company_12", WID_SCRD_COMPANY_BUTTON_START + 11), + Hotkey((uint16)0, "company_13", WID_SCRD_COMPANY_BUTTON_START + 12), + Hotkey((uint16)0, "company_14", WID_SCRD_COMPANY_BUTTON_START + 13), + Hotkey((uint16)0, "company_15", WID_SCRD_COMPANY_BUTTON_START + 14), + Hotkey('S', "settings", WID_SCRD_SETTINGS), + Hotkey('0', "game_script", WID_SCRD_SCRIPT_GAME), + Hotkey((uint16)0, "reload", WID_SCRD_RELOAD_TOGGLE), + Hotkey('B', "break_toggle", WID_SCRD_BREAK_STR_ON_OFF_BTN), + Hotkey('F', "break_string", WID_SCRD_BREAK_STR_EDIT_BOX), + Hotkey('C', "match_case", WID_SCRD_MATCH_CASE_BTN), + Hotkey(WKC_RETURN, "continue", WID_SCRD_CONTINUE_BTN), + HOTKEY_LIST_END +}; +HotkeyList ScriptDebugWindow::hotkeys("aidebug", scriptdebug_hotkeys, ScriptDebugGlobalHotkeys); + +/** Widgets for the Script debug window. */ +static const NWidgetPart _nested_script_debug_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_AI_DEBUG, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_SHADEBOX, COLOUR_GREY), + NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), + NWidget(WWT_STICKYBOX, COLOUR_GREY), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_SCRD_VIEW), + NWidgetFunction(MakeCompanyButtonRowsScriptDebug), SetPadding(0, 2, 1, 2), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCRD_SCRIPT_GAME), SetMinimalSize(100, 20), SetResize(1, 0), SetDataTip(STR_AI_GAME_SCRIPT, STR_AI_GAME_SCRIPT_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCRD_NAME_TEXT), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_JUST_STRING, STR_AI_DEBUG_NAME_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCRD_SETTINGS), SetMinimalSize(100, 20), SetDataTip(STR_AI_DEBUG_SETTINGS, STR_AI_DEBUG_SETTINGS_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCRD_RELOAD_TOGGLE), SetMinimalSize(100, 20), SetDataTip(STR_AI_DEBUG_RELOAD, STR_AI_DEBUG_RELOAD_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_VERTICAL), + /* Log panel */ + NWidget(WWT_PANEL, COLOUR_GREY, WID_SCRD_LOG_PANEL), SetMinimalSize(287, 180), SetResize(1, 1), SetScrollbar(WID_SCRD_SCROLLBAR), + EndContainer(), + /* Break string widgets */ + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SCRD_BREAK_STRING_WIDGETS), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_IMGBTN_2, COLOUR_GREY, WID_SCRD_BREAK_STR_ON_OFF_BTN), SetFill(0, 1), SetDataTip(SPR_FLAG_VEH_STOPPED, STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_LABEL, COLOUR_GREY), SetPadding(2, 2, 2, 4), SetDataTip(STR_AI_DEBUG_BREAK_ON_LABEL, 0x0), + NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SCRD_BREAK_STR_EDIT_BOX), SetFill(1, 1), SetResize(1, 0), SetPadding(2, 2, 2, 2), SetDataTip(STR_AI_DEBUG_BREAK_STR_OSKTITLE, STR_AI_DEBUG_BREAK_STR_TOOLTIP), + EndContainer(), + EndContainer(), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SCRD_MATCH_CASE_BTN), SetMinimalSize(100, 0), SetFill(0, 1), SetDataTip(STR_AI_DEBUG_MATCH_CASE, STR_AI_DEBUG_MATCH_CASE_TOOLTIP), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCRD_CONTINUE_BTN), SetMinimalSize(100, 0), SetFill(0, 1), SetDataTip(STR_AI_DEBUG_CONTINUE, STR_AI_DEBUG_CONTINUE_TOOLTIP), + EndContainer(), + EndContainer(), + EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_SCRD_SCROLLBAR), + NWidget(WWT_RESIZEBOX, COLOUR_GREY), + EndContainer(), +EndContainer(), +}; + +/** Window definition for the Script debug window. */ +static WindowDesc _script_debug_desc( + WDP_AUTO, "script_debug", 600, 450, + WC_SCRIPT_DEBUG, WC_NONE, + 0, + _nested_script_debug_widgets, lengthof(_nested_script_debug_widgets), + &ScriptDebugWindow::hotkeys +); + +/** + * Open the Script debug window and select the given company. + * @param show_company Display debug information about this AI company. + */ +Window *ShowScriptDebugWindow(CompanyID show_company) +{ + if (!_networking || _network_server) { + ScriptDebugWindow *w = (ScriptDebugWindow *)BringWindowToFrontById(WC_SCRIPT_DEBUG, 0); + if (w == nullptr) w = new ScriptDebugWindow(&_script_debug_desc, 0); + if (show_company != INVALID_COMPANY) w->ChangeToScript(show_company); + return w; + } else { + ShowErrorMessage(STR_ERROR_AI_DEBUG_SERVER_ONLY, INVALID_STRING_ID, WL_INFO); + } + + return nullptr; +} + +/** + * Reset the Script windows to their initial state. + */ +void InitializeScriptGui() +{ + ScriptDebugWindow::script_debug_company = INVALID_COMPANY; +} + +/** Open the AI debug window if one of the AI scripts has crashed. */ +void ShowScriptDebugWindowIfScriptError() +{ + /* Network clients can't debug AIs. */ + if (_networking && !_network_server) return; + + for (const Company *c : Company::Iterate()) { + if (c->is_ai && c->ai_instance->IsDead()) { + ShowScriptDebugWindow(c->index); + break; + } + } + + GameInstance *g = Game::GetGameInstance(); + if (g != nullptr && g->IsDead()) { + ShowScriptDebugWindow(OWNER_DEITY); + } +} diff --git a/src/script/script_gui.h b/src/script/script_gui.h new file mode 100644 index 0000000000000..d892feef3aac4 --- /dev/null +++ b/src/script/script_gui.h @@ -0,0 +1,23 @@ +/* + * 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 script_gui.hpp %Window for configuring the scripts */ + +#ifndef SCRIPT_GUI_HPP +#define SCRIPT_GUI_HPP + +#include "../company_type.h" +#include "../textfile_type.h" + +void ShowScriptListWindow(CompanyID slot); +Window *ShowScriptDebugWindow(CompanyID show_company = INVALID_COMPANY); +void ShowScriptSettingsWindow(CompanyID slot); +void ShowScriptTextfileWindow(TextfileType file_type, CompanyID slot); +void ShowScriptDebugWindowIfScriptError(); +void InitializeScriptGui(); + +#endif /* SCRIPT_GUI_HPP */ diff --git a/src/script/script_info.cpp b/src/script/script_info.cpp index d381ae9c2cfbf..79f4982fb6d05 100644 --- a/src/script/script_info.cpp +++ b/src/script/script_info.cpp @@ -146,42 +146,42 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm) } else if (strcmp(key, "min_value") == 0) { SQInteger res; if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR; - config.min_value = res; + config.min_value = ClampToI32(res); items |= 0x004; } else if (strcmp(key, "max_value") == 0) { SQInteger res; if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR; - config.max_value = res; + config.max_value = ClampToI32(res); items |= 0x008; } else if (strcmp(key, "easy_value") == 0) { SQInteger res; if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR; - config.easy_value = res; + config.easy_value = ClampToI32(res); items |= 0x010; } else if (strcmp(key, "medium_value") == 0) { SQInteger res; if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR; - config.medium_value = res; + config.medium_value = ClampToI32(res); items |= 0x020; } else if (strcmp(key, "hard_value") == 0) { SQInteger res; if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR; - config.hard_value = res; + config.hard_value = ClampToI32(res); items |= 0x040; } else if (strcmp(key, "random_deviation") == 0) { SQInteger res; if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR; - config.random_deviation = res; + config.random_deviation = ClampToI32(abs(res)); items |= 0x200; } else if (strcmp(key, "custom_value") == 0) { SQInteger res; if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR; - config.custom_value = res; + config.custom_value = ClampToI32(res); items |= 0x080; } else if (strcmp(key, "step_size") == 0) { SQInteger res; if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR; - config.step_size = res; + config.step_size = ClampToI32(res); } else if (strcmp(key, "flags") == 0) { SQInteger res; if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR; @@ -252,7 +252,14 @@ SQInteger ScriptInfo::AddLabels(HSQUIRRELVM vm) if (SQ_FAILED(sq_getstring(vm, -1, &label))) return SQ_ERROR; /* Because squirrel doesn't support identifiers starting with a digit, * we skip the first character. */ - int key = atoi(key_string + 1); + key_string++; + int sign = 1; + if (*key_string == '_') { + /* When the second character is '_', it indicates the value is negative. */ + sign = -1; + key_string++; + } + int key = atoi(key_string) * sign; StrMakeValidInPlace(const_cast(label)); /* !Contains() prevents stredup from leaking. */ diff --git a/src/script/script_info.hpp b/src/script/script_info.hpp index c2e952b821e0c..61af366462bd0 100644 --- a/src/script/script_info.hpp +++ b/src/script/script_info.hpp @@ -164,4 +164,7 @@ class ScriptInfo : public SimpleCountedObject { class ScriptScanner *scanner; ///< ScriptScanner object that was used to scan this script info. }; +void Script_CreateDummyInfo(HSQUIRRELVM vm, const char *type, const char *dir); +void Script_CreateDummy(HSQUIRRELVM vm, StringID string, const char *type); + #endif /* SCRIPT_INFO_HPP */ diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp index bcd8b2d4bd7eb..18f8ef39b67c7 100644 --- a/src/script/script_instance.cpp +++ b/src/script/script_instance.cpp @@ -12,6 +12,7 @@ #include "../saveload/saveload.h" #include "../script/squirrel_class.hpp" +#include "../script/squirrel_std.hpp" #include "script_fatalerror.hpp" #include "script_storage.hpp" @@ -26,6 +27,7 @@ #include "../company_base.h" #include "../company_func.h" #include "../fileio_func.h" +#include "../league_type.h" #include "../misc/endian_buffer.hpp" #include "../safeguards.h" @@ -109,7 +111,6 @@ void ScriptInstance::Initialize(const char *main_script, const char *instance_na void ScriptInstance::RegisterAPI() { - extern void squirrel_register_std(Squirrel *engine); squirrel_register_std(this->engine); } @@ -298,6 +299,17 @@ void ScriptInstance::CollectGarbage() instance->engine->InsertResult(EndianBufferReader::ToValue(ScriptObject::GetLastCommandResData())); } +/* static */ void ScriptInstance::DoCommandReturnLeagueTableElementID(ScriptInstance *instance) +{ + instance->engine->InsertResult(EndianBufferReader::ToValue(ScriptObject::GetLastCommandResData())); +} + +/* static */ void ScriptInstance::DoCommandReturnLeagueTableID(ScriptInstance *instance) +{ + instance->engine->InsertResult(EndianBufferReader::ToValue(ScriptObject::GetLastCommandResData())); +} + + ScriptStorage *ScriptInstance::GetStorage() { return this->storage; @@ -331,17 +343,6 @@ void *ScriptInstance::GetLogPointer() * - null: No data. */ -/** The type of the data that follows in the savegame. */ -enum SQSaveLoadType { - SQSL_INT = 0x00, ///< The following data is an integer. - SQSL_STRING = 0x01, ///< The following data is an string. - SQSL_ARRAY = 0x02, ///< The following data is an array. - SQSL_TABLE = 0x03, ///< The following data is an table. - SQSL_BOOL = 0x04, ///< The following data is a boolean. - SQSL_NULL = 0x05, ///< A null variable. - SQSL_ARRAY_TABLE_END = 0xFF, ///< Marks the end of an array or table, no data follows. -}; - static byte _script_sl_byte; ///< Used as source/target by the script saveload code to store/load a single byte. /** SaveLoad array that saves/loads exactly one byte. */ @@ -560,14 +561,14 @@ bool ScriptInstance::IsPaused() return this->is_paused; } -/* static */ bool ScriptInstance::LoadObjects(HSQUIRRELVM vm) +/* static */ bool ScriptInstance::LoadObjects(ScriptData *data) { SlObject(nullptr, _script_byte); switch (_script_sl_byte) { case SQSL_INT: { int64 value; SlCopy(&value, 1, IsSavegameVersionBefore(SLV_SCRIPT_INT64) ? SLE_FILE_I32 | SLE_VAR_I64 : SLE_INT64); - if (vm != nullptr) sq_pushinteger(vm, (SQInteger)value); + if (data != nullptr) data->push_back((SQInteger)value); return true; } @@ -576,37 +577,79 @@ bool ScriptInstance::IsPaused() static char buf[std::numeric_limits::max()]; SlCopy(buf, _script_sl_byte, SLE_CHAR); StrMakeValidInPlace(buf, buf + _script_sl_byte); - if (vm != nullptr) sq_pushstring(vm, buf, -1); + if (data != nullptr) data->push_back(std::string(buf)); + return true; + } + + case SQSL_ARRAY: + case SQSL_TABLE: { + if (data != nullptr) data->push_back((SQSaveLoadType)_script_sl_byte); + while (LoadObjects(data)); + return true; + } + + case SQSL_BOOL: { + SlObject(nullptr, _script_byte); + if (data != nullptr) data->push_back((SQBool)(_script_sl_byte != 0)); + return true; + } + + case SQSL_NULL: { + if (data != nullptr) data->push_back((SQSaveLoadType)_script_sl_byte); return true; } + case SQSL_ARRAY_TABLE_END: { + if (data != nullptr) data->push_back((SQSaveLoadType)_script_sl_byte); + return false; + } + + default: SlErrorCorrupt("Invalid script data type"); + } +} + +/* static */ bool ScriptInstance::LoadObjects(HSQUIRRELVM vm, ScriptData *data) +{ + ScriptDataVariant value = data->front(); + data->pop_front(); + + if (std::holds_alternative(value)) { + sq_pushinteger(vm, std::get(value)); + return true; + } + + if (std::holds_alternative(value)) { + sq_pushstring(vm, std::get(value).c_str(), -1); + return true; + } + + if (std::holds_alternative(value)) { + sq_pushbool(vm, std::get(value)); + return true; + } + + switch (std::get(value)) { case SQSL_ARRAY: { - if (vm != nullptr) sq_newarray(vm, 0); - while (LoadObjects(vm)) { - if (vm != nullptr) sq_arrayappend(vm, -2); + sq_newarray(vm, 0); + while (LoadObjects(vm, data)) { + sq_arrayappend(vm, -2); /* The value is popped from the stack by squirrel. */ } return true; } case SQSL_TABLE: { - if (vm != nullptr) sq_newtable(vm); - while (LoadObjects(vm)) { - LoadObjects(vm); - if (vm != nullptr) sq_rawset(vm, -3); + sq_newtable(vm); + while (LoadObjects(vm, data)) { + LoadObjects(vm, data); + sq_rawset(vm, -3); /* The key (-2) and value (-1) are popped from the stack by squirrel. */ } return true; } - case SQSL_BOOL: { - SlObject(nullptr, _script_byte); - if (vm != nullptr) sq_pushbool(vm, (SQBool)(_script_sl_byte != 0)); - return true; - } - case SQSL_NULL: { - if (vm != nullptr) sq_pushnull(vm); + sq_pushnull(vm); return true; } @@ -627,22 +670,35 @@ bool ScriptInstance::IsPaused() LoadObjects(nullptr); } -void ScriptInstance::Load(int version) +/* static */ ScriptInstance::ScriptData *ScriptInstance::Load(int version) { - ScriptObject::ActiveInstance active(this); - - if (this->engine == nullptr || version == -1) { + if (version == -1) { LoadEmpty(); - return; + return nullptr; } - HSQUIRRELVM vm = this->engine->GetVM(); SlObject(nullptr, _script_byte); /* Check if there was anything saved at all. */ - if (_script_sl_byte == 0) return; + if (_script_sl_byte == 0) return nullptr; + + ScriptData *data = new ScriptData(); + data->push_back((SQInteger)version); + LoadObjects(data); + return data; +} + +void ScriptInstance::LoadOnStack(ScriptData *data) +{ + ScriptObject::ActiveInstance active(this); + + if (this->IsDead() || data == nullptr) return; + + HSQUIRRELVM vm = this->engine->GetVM(); - sq_pushinteger(vm, version); - LoadObjects(vm); + ScriptDataVariant version = data->front(); + data->pop_front(); + sq_pushinteger(vm, std::get(version)); + LoadObjects(vm, data); this->is_save_data_on_stack = true; } @@ -688,11 +744,11 @@ SQInteger ScriptInstance::GetOpsTillSuspend() return this->engine->GetOpsTillSuspend(); } -bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, CommandDataBuffer result_data, Commands cmd) +bool ScriptInstance::DoCommandCallback(const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data, Commands cmd) { ScriptObject::ActiveInstance active(this); - if (!ScriptObject::CheckLastCommand(tile, data, cmd)) { + if (!ScriptObject::CheckLastCommand(data, cmd)) { Debug(script, 1, "DoCommandCallback terminating a script, last command does not match expected command"); return false; } @@ -707,7 +763,7 @@ bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile ScriptObject::SetLastCost(result.GetCost()); } - ScriptObject::SetLastCommand(INVALID_TILE, {}, CMD_END); + ScriptObject::SetLastCommand({}, CMD_END); return true; } diff --git a/src/script/script_instance.hpp b/src/script/script_instance.hpp index 57f8dcc72f588..65a6414bb5e20 100644 --- a/src/script/script_instance.hpp +++ b/src/script/script_instance.hpp @@ -10,6 +10,8 @@ #ifndef SCRIPT_INSTANCE_HPP #define SCRIPT_INSTANCE_HPP +#include +#include #include #include "script_suspend.hpp" @@ -21,10 +23,25 @@ static const uint SQUIRREL_MAX_DEPTH = 25; ///< The maximum recursive depth for /** Runtime information about a script like a pointer to the squirrel vm and the current state. */ class ScriptInstance { +private: + /** The type of the data that follows in the savegame. */ + enum SQSaveLoadType { + SQSL_INT = 0x00, ///< The following data is an integer. + SQSL_STRING = 0x01, ///< The following data is an string. + SQSL_ARRAY = 0x02, ///< The following data is an array. + SQSL_TABLE = 0x03, ///< The following data is an table. + SQSL_BOOL = 0x04, ///< The following data is a boolean. + SQSL_NULL = 0x05, ///< A null variable. + SQSL_ARRAY_TABLE_END = 0xFF, ///< Marks the end of an array or table, no data follows. + }; + public: friend class ScriptObject; friend class ScriptController; + typedef std::variant ScriptDataVariant; + typedef std::list ScriptData; + /** * Create a new script. */ @@ -115,6 +132,16 @@ class ScriptInstance { */ static void DoCommandReturnStoryPageElementID(ScriptInstance *instance); + /** + * Return a LeagueTableID reply for a DoCommand. + */ + static void DoCommandReturnLeagueTableID(ScriptInstance *instance); + + /** + * Return a LeagueTableElementID reply for a DoCommand. + */ + static void DoCommandReturnLeagueTableElementID(ScriptInstance *instance); + /** * Get the controller attached to the instance. */ @@ -136,11 +163,18 @@ class ScriptInstance { static void SaveEmpty(); /** - * Load data from a savegame and store it on the stack. + * Load data from a savegame. * @param version The version of the script when saving, or -1 if this was * not the original script saving the game. + * @return a pointer to loaded data. + */ + static ScriptData *Load(int version); + + /** + * Store loaded data on the stack. + * @param data The loaded data to store on the stack. */ - void Load(int version); + void LoadOnStack(ScriptData *data); /** * Load and discard data from a savegame. @@ -183,7 +217,7 @@ class ScriptInstance { * @param cmd cmd as given to DoCommandPInternal. * @return true if we handled result. */ - bool DoCommandCallback(const CommandCost &result, TileIndex tile, const CommandDataBuffer &data, CommandDataBuffer result_data, Commands cmd); + bool DoCommandCallback(const CommandCost &result, const CommandDataBuffer &data, CommandDataBuffer result_data, Commands cmd); /** * Insert an event for this script. @@ -279,7 +313,9 @@ class ScriptInstance { * Load all objects from a savegame. * @return True if the loading was successful. */ - static bool LoadObjects(HSQUIRRELVM vm); + static bool LoadObjects(ScriptData *data); + + static bool LoadObjects(HSQUIRRELVM vm, ScriptData *data); }; #endif /* SCRIPT_INSTANCE_HPP */ diff --git a/src/script/script_scanner.cpp b/src/script/script_scanner.cpp index 319a1c7fc0089..3b76b7b651fc9 100644 --- a/src/script/script_scanner.cpp +++ b/src/script/script_scanner.cpp @@ -145,15 +145,16 @@ void ScriptScanner::RegisterScript(ScriptInfo *info) } } -char *ScriptScanner::GetConsoleList(char *p, const char *last, bool newest_only) const +std::string ScriptScanner::GetConsoleList(bool newest_only) const { - p += seprintf(p, last, "List of %s:\n", this->GetScannerName()); + std::string p; + p += fmt::format("List of {}:\n", this->GetScannerName()); const ScriptInfoList &list = newest_only ? this->info_single_list : this->info_list; for (const auto &item : list) { ScriptInfo *i = item.second; - p += seprintf(p, last, "%10s (v%d): %s\n", i->GetName(), i->GetVersion(), i->GetDescription()); + p += fmt::format("{:>10} (v{:d}): {}\n", i->GetName(), i->GetVersion(), i->GetDescription()); } - p += seprintf(p, last, "\n"); + p += "\n"; return p; } diff --git a/src/script/script_scanner.hpp b/src/script/script_scanner.hpp index ca9068ca109a9..9781e07b69063 100644 --- a/src/script/script_scanner.hpp +++ b/src/script/script_scanner.hpp @@ -57,7 +57,7 @@ class ScriptScanner : public FileScanner { /** * Get the list of registered scripts to print on the console. */ - char *GetConsoleList(char *p, const char *last, bool newest_only) const; + std::string GetConsoleList(bool newest_only) const; /** * Check whether we have a script with the exact characteristics as ci. diff --git a/src/script/script_storage.hpp b/src/script/script_storage.hpp index 2afb03827d8d7..44d17af837911 100644 --- a/src/script/script_storage.hpp +++ b/src/script/script_storage.hpp @@ -44,7 +44,6 @@ friend class ScriptObject; uint last_error; ///< The last error of the command. bool last_command_res; ///< The last result of the command. - TileIndex last_tile; ///< The last tile passed to a command. CommandDataBuffer last_data; ///< The last data passed to a command. Commands last_cmd; ///< The last cmd passed to a command. CommandDataBuffer last_cmd_ret; ///< The extra data returned by the last command. @@ -69,7 +68,6 @@ friend class ScriptObject; last_cost (0), last_error (STR_NULL), last_command_res (true), - last_tile (INVALID_TILE), last_cmd (CMD_END), /* calback_value (can't be set) */ road_type (INVALID_ROADTYPE), diff --git a/src/script/squirrel_helper.hpp b/src/script/squirrel_helper.hpp index e6ce02786ca54..47c5eb62a0b76 100644 --- a/src/script/squirrel_helper.hpp +++ b/src/script/squirrel_helper.hpp @@ -37,92 +37,83 @@ namespace SQConvert { /** - * Special class to make it possible for the compiler to pick the correct GetParam(). + * To return a value to squirrel, we use this helper class. It converts to the right format. + * We use a class instead of a plain function to allow us to use partial template specializations. */ - template class ForceType { }; + template struct Return; + + template <> struct Return { static inline int Set(HSQUIRRELVM vm, uint8 res) { sq_pushinteger(vm, (int32)res); return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, uint16 res) { sq_pushinteger(vm, (int32)res); return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, uint32 res) { sq_pushinteger(vm, (int32)res); return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, int8 res) { sq_pushinteger(vm, res); return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, int16 res) { sq_pushinteger(vm, res); return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, int32 res) { sq_pushinteger(vm, res); return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, int64 res) { sq_pushinteger(vm, res); return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, Money res) { sq_pushinteger(vm, res); return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, TileIndex res) { sq_pushinteger(vm, (int32)res.value); return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, bool res) { sq_pushbool (vm, res); return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, char *res) { if (res == nullptr) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); free(res); } return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, const char *res) { if (res == nullptr) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); } return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, void *res) { sq_pushuserpointer(vm, res); return 1; } }; + template <> struct Return { static inline int Set(HSQUIRRELVM vm, HSQOBJECT res) { sq_pushobject(vm, res); return 1; } }; /** - * To return a value to squirrel, we call this function. It converts to the right format. + * To get a param from squirrel, we use this helper class. It converts to the right format. + * We use a class instead of a plain function to allow us to use partial template specializations. */ - template static int Return(HSQUIRRELVM vm, T t); - - template <> inline int Return (HSQUIRRELVM vm, uint8 res) { sq_pushinteger(vm, (int32)res); return 1; } - template <> inline int Return (HSQUIRRELVM vm, uint16 res) { sq_pushinteger(vm, (int32)res); return 1; } - template <> inline int Return (HSQUIRRELVM vm, uint32 res) { sq_pushinteger(vm, (int32)res); return 1; } - template <> inline int Return (HSQUIRRELVM vm, int8 res) { sq_pushinteger(vm, res); return 1; } - template <> inline int Return (HSQUIRRELVM vm, int16 res) { sq_pushinteger(vm, res); return 1; } - template <> inline int Return (HSQUIRRELVM vm, int32 res) { sq_pushinteger(vm, res); return 1; } - template <> inline int Return (HSQUIRRELVM vm, int64 res) { sq_pushinteger(vm, res); return 1; } - template <> inline int Return (HSQUIRRELVM vm, Money res) { sq_pushinteger(vm, res); return 1; } - template <> inline int Return (HSQUIRRELVM vm, TileIndex res) { sq_pushinteger(vm, (int32)res.value); return 1; } - template <> inline int Return (HSQUIRRELVM vm, bool res) { sq_pushbool (vm, res); return 1; } - template <> inline int Return (HSQUIRRELVM vm, char *res) { if (res == nullptr) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); free(res); } return 1; } - template <> inline int Return(HSQUIRRELVM vm, const char *res) { if (res == nullptr) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); } return 1; } - template <> inline int Return (HSQUIRRELVM vm, void *res) { sq_pushuserpointer(vm, res); return 1; } - template <> inline int Return (HSQUIRRELVM vm, HSQOBJECT res) { sq_pushobject(vm, res); return 1; } - - /** - * To get a param from squirrel, we call this function. It converts to the right format. - */ - template static T GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr); - - template <> inline uint8 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } - template <> inline uint16 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } - template <> inline uint32 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } - template <> inline int8 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } - template <> inline int16 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } - template <> inline int32 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } - template <> inline int64 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } - template <> inline TileIndex GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return TileIndex((uint32)(int32)tmp); } - template <> inline Money GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } - template <> inline bool GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool tmp; sq_getbool (vm, index, &tmp); return tmp != 0; } - template <> inline void *GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; } - template <> inline const char *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) - { - /* Convert what-ever there is as parameter to a string */ - sq_tostring(vm, index); - - const SQChar *tmp; - sq_getstring(vm, -1, &tmp); - char *tmp_str = stredup(tmp); - sq_poptop(vm); - ptr->push_back((void *)tmp_str); - StrMakeValidInPlace(tmp_str); - return tmp_str; - } + template struct Param; + + template <> struct Param { static inline uint8 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } }; + template <> struct Param { static inline uint16 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } }; + template <> struct Param { static inline uint32 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } }; + template <> struct Param { static inline int8 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } }; + template <> struct Param { static inline int16 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } }; + template <> struct Param { static inline int32 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } }; + template <> struct Param { static inline int64 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } }; + template <> struct Param { static inline TileIndex Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return TileIndex((uint32)(int32)tmp); } }; + template <> struct Param { static inline Money Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } }; + template <> struct Param { static inline bool Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool tmp; sq_getbool (vm, index, &tmp); return tmp != 0; } }; + template <> struct Param { static inline void *Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; } }; + + template <> struct Param { + static inline const char *Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) + { + /* Convert what-ever there is as parameter to a string */ + sq_tostring(vm, index); + + const SQChar *tmp; + sq_getstring(vm, -1, &tmp); + char *tmp_str = stredup(tmp); + sq_poptop(vm); + ptr->push_back((void *)tmp_str); + StrMakeValidInPlace(tmp_str); + return tmp_str; + } + }; - template <> inline Array *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) - { - /* Sanity check of the size. */ - if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, "an array used as parameter to a function is too large"); + template + struct Param> { + static inline Array Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) + { + /* Sanity check of the size. */ + if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, "an array used as parameter to a function is too large"); - SQObject obj; - sq_getstackobj(vm, index, &obj); - sq_pushobject(vm, obj); - sq_pushnull(vm); + SQObject obj; + sq_getstackobj(vm, index, &obj); + sq_pushobject(vm, obj); + sq_pushnull(vm); - std::vector data; + Array data; - while (SQ_SUCCEEDED(sq_next(vm, -2))) { - SQInteger tmp; - if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) { - data.push_back((int32)tmp); - } else { - sq_pop(vm, 4); - throw sq_throwerror(vm, "a member of an array used as parameter to a function is not numeric"); + while (SQ_SUCCEEDED(sq_next(vm, -2))) { + data.emplace_back(Param::Get(vm, -1, ptr)); + sq_pop(vm, 2); } - sq_pop(vm, 2); - } - sq_pop(vm, 2); - Array *arr = (Array*)MallocT(sizeof(Array) + sizeof(int32) * data.size()); - arr->size = data.size(); - memcpy(arr->array, data.data(), sizeof(int32) * data.size()); - - ptr->push_back(arr); - return arr; - } + return data; + } + }; /** * Helper class to recognize the function type (retval type, args) and use the proper specialization @@ -148,14 +139,14 @@ namespace SQConvert { [[maybe_unused]] SQAutoFreePointers ptr; if constexpr (std::is_void_v) { (*func)( - GetParam(ForceType(), vm, 2 + i, &ptr)... + Param::Get(vm, 2 + i, &ptr)... ); return 0; } else { Tretval ret = (*func)( - GetParam(ForceType(), vm, 2 + i, &ptr)... + Param::Get(vm, 2 + i, &ptr)... ); - return Return(vm, ret); + return Return::Set(vm, ret); } } }; @@ -182,14 +173,14 @@ namespace SQConvert { [[maybe_unused]] SQAutoFreePointers ptr; if constexpr (std::is_void_v) { (instance->*func)( - GetParam(ForceType(), vm, 2 + i, &ptr)... + Param::Get(vm, 2 + i, &ptr)... ); return 0; } else { Tretval ret = (instance->*func)( - GetParam(ForceType(), vm, 2 + i, &ptr)... + Param::Get(vm, 2 + i, &ptr)... ); - return Return(vm, ret); + return Return::Set(vm, ret); } } @@ -198,7 +189,7 @@ namespace SQConvert { { [[maybe_unused]] SQAutoFreePointers ptr; Tcls *inst = new Tcls( - GetParam(ForceType(), vm, 2 + i, &ptr)... + Param::Get(vm, 2 + i, &ptr)... ); return inst; diff --git a/src/script/squirrel_helper_type.hpp b/src/script/squirrel_helper_type.hpp index c20655ca19365..05f3824fd9bdb 100644 --- a/src/script/squirrel_helper_type.hpp +++ b/src/script/squirrel_helper_type.hpp @@ -10,10 +10,10 @@ #ifndef SQUIRREL_HELPER_TYPE_HPP #define SQUIRREL_HELPER_TYPE_HPP +#include + /** Definition of a simple array. */ -struct Array { - size_t size; ///< The size of the array. - int32 array[]; ///< The data of the array. -}; +template +using Array = std::vector; #endif /* SQUIRREL_HELPER_TYPE_HPP */ diff --git a/src/settings.cpp b/src/settings.cpp index 1a98b8342189f..39d635328e2b5 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -59,7 +59,6 @@ std::string _config_file; ///< Configuration file of OpenTTD. std::string _private_file; ///< Private configuration file of OpenTTD. std::string _secrets_file; ///< Secrets configuration file of OpenTTD. -typedef std::list ErrorList; static ErrorList _settings_error_list; ///< Errors while loading minimal settings. /** @@ -1017,7 +1016,7 @@ static GRFConfig *GRFLoadConfig(IniFile &ini, const char *grpname, bool is_stati SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN); } - SetDParamStr(0, StrEmpty(filename) ? item->name : filename); + SetDParamStr(0, StrEmpty(filename) ? item->name.c_str() : filename); ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_GRF, WL_CRITICAL); delete c; continue; @@ -1251,7 +1250,6 @@ void LoadFromConfig(bool startup) DebugReconsiderSendRemoteMessages(); /* Display scheduled errors */ - extern void ScheduleErrorMessage(ErrorList &datas); ScheduleErrorMessage(_settings_error_list); if (FindWindowById(WC_ERRMSG, 0) == nullptr) ShowFirstError(); } @@ -1603,8 +1601,8 @@ void SyncCompanySettings() const void *new_object = &_settings_client.company; for (auto &desc : _company_settings) { const SettingDesc *sd = GetSettingDesc(desc); - uint32 old_value = (uint32)sd->AsIntSetting()->Read(new_object); - uint32 new_value = (uint32)sd->AsIntSetting()->Read(old_object); + uint32 old_value = (uint32)sd->AsIntSetting()->Read(old_object); + uint32 new_value = (uint32)sd->AsIntSetting()->Read(new_object); if (old_value != new_value) Command::SendNet(STR_NULL, _local_company, sd->GetName(), new_value); } } diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index bc7eb985958d6..5d14637e6452d 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -39,6 +39,8 @@ #include "rev.h" #include "video/video_driver.hpp" #include "music/music_driver.hpp" +#include "gui.h" +#include "mixer.h" #include #include @@ -56,22 +58,6 @@ static const StringID _autosave_dropdown[] = { INVALID_STRING_ID, }; -static const StringID _gui_zoom_dropdown[] = { - STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO, - STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL, - STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM, - STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM, - INVALID_STRING_ID, -}; - -static const StringID _font_zoom_dropdown[] = { - STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO, - STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL, - STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM, - STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM, - INVALID_STRING_ID, -}; - static Dimension _circle_size; ///< Dimension of the circle +/- icon. This is here as not all users are within the class of the settings window. static const void *ResolveObject(const GameSettings *settings_ptr, const IntSettingDesc *sd); @@ -157,14 +143,36 @@ static void AddCustomRefreshRates() std::copy(monitorRates.begin(), monitorRates.end(), std::inserter(_refresh_rates, _refresh_rates.end())); } +static const std::map _scale_labels = { + { 100, STR_GAME_OPTIONS_GUI_SCALE_1X }, + { 125, STR_NULL }, + { 150, STR_NULL }, + { 175, STR_NULL }, + { 200, STR_GAME_OPTIONS_GUI_SCALE_2X }, + { 225, STR_NULL }, + { 250, STR_NULL }, + { 275, STR_NULL }, + { 300, STR_GAME_OPTIONS_GUI_SCALE_3X }, + { 325, STR_NULL }, + { 350, STR_NULL }, + { 375, STR_NULL }, + { 400, STR_GAME_OPTIONS_GUI_SCALE_4X }, + { 425, STR_NULL }, + { 450, STR_NULL }, + { 475, STR_NULL }, + { 500, STR_GAME_OPTIONS_GUI_SCALE_5X }, +}; + struct GameOptionsWindow : Window { GameSettings *opt; bool reload; + int gui_scale; GameOptionsWindow(WindowDesc *desc) : Window(desc) { this->opt = &GetGameSettings(); this->reload = false; + this->gui_scale = _gui_scale; AddCustomRefreshRates(); @@ -263,24 +271,6 @@ struct GameOptionsWindow : Window { } break; - case WID_GO_GUI_ZOOM_DROPDOWN: { - *selected_index = _gui_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _gui_zoom + 1 : 0; - const StringID *items = _gui_zoom_dropdown; - for (int i = 0; *items != INVALID_STRING_ID; items++, i++) { - list.emplace_back(new DropDownListStringItem(*items, i, i != 0 && _settings_client.gui.zoom_min > ZOOM_LVL_OUT_4X - i + 1)); - } - break; - } - - case WID_GO_FONT_ZOOM_DROPDOWN: { - *selected_index = _font_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _font_zoom + 1 : 0; - const StringID *items = _font_zoom_dropdown; - for (int i = 0; *items != INVALID_STRING_ID; items++, i++) { - list.emplace_back(new DropDownListStringItem(*items, i, false)); - } - break; - } - case WID_GO_BASE_GRF_DROPDOWN: list = BuildSetDropDownList(selected_index, (_game_mode == GM_MENU)); break; @@ -303,8 +293,6 @@ struct GameOptionsWindow : Window { case WID_GO_CURRENCY_DROPDOWN: SetDParam(0, _currency_specs[this->opt->locale.currency].name); break; case WID_GO_AUTOSAVE_DROPDOWN: SetDParam(0, _autosave_dropdown[_settings_client.gui.autosave]); break; case WID_GO_LANG_DROPDOWN: SetDParamStr(0, _current_language->own_name); break; - case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[_gui_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _gui_zoom_cfg + 1 : 0]); break; - case WID_GO_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[_font_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _font_zoom_cfg + 1 : 0]); break; case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name); break; case WID_GO_BASE_GRF_STATUS: SetDParam(0, BaseGraphics::GetUsedSet()->GetNumInvalid()); break; case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->name); break; @@ -345,12 +333,16 @@ struct GameOptionsWindow : Window { DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_BLACK_RAW_STRING); break; + case WID_GO_GUI_SCALE: + DrawSliderWidget(r, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, this->gui_scale, _scale_labels); + break; + case WID_GO_BASE_SFX_VOLUME: - DrawVolumeSliderWidget(r, _settings_client.music.effect_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.effect_vol, {}); break; case WID_GO_BASE_MUSIC_VOLUME: - DrawVolumeSliderWidget(r, _settings_client.music.music_vol); + DrawSliderWidget(r, 0, INT8_MAX, _settings_client.music.music_vol, {}); break; } } @@ -474,11 +466,50 @@ struct GameOptionsWindow : Window { this->SetWidgetDirty(WID_GO_REFRESH_RATE_DROPDOWN); break; + case WID_GO_GUI_SCALE_BEVEL_BUTTON: { + _settings_client.gui.scale_bevels = !_settings_client.gui.scale_bevels; + + this->SetWidgetLoweredState(WID_GO_GUI_SCALE_BEVEL_BUTTON, _settings_client.gui.scale_bevels); + this->SetDirty(); + + SetupWidgetDimensions(); + ReInitAllWindows(true); + break; + } + + case WID_GO_GUI_SCALE: + if (ClickSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, this->gui_scale)) { + if (!_ctrl_pressed) this->gui_scale = ((this->gui_scale + 12) / 25) * 25; + this->SetWidgetDirty(widget); + } + + if (click_count > 0) this->mouse_capture_widget = widget; + break; + + case WID_GO_GUI_SCALE_AUTO: + { + if (_gui_scale_cfg == -1) { + _gui_scale_cfg = _gui_scale; + this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, false); + } else { + _gui_scale_cfg = -1; + this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, true); + if (AdjustGUIZoom(false)) ReInitAllWindows(true); + this->gui_scale = _gui_scale; + } + this->SetWidgetDirty(widget); + break; + } + case WID_GO_BASE_SFX_VOLUME: case WID_GO_BASE_MUSIC_VOLUME: { byte &vol = (widget == WID_GO_BASE_MUSIC_VOLUME) ? _settings_client.music.music_vol : _settings_client.music.effect_vol; - if (ClickVolumeSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, vol)) { - if (widget == WID_GO_BASE_MUSIC_VOLUME) MusicDriver::GetInstance()->SetVolume(vol); + if (ClickSliderWidget(this->GetWidget(widget)->GetCurrentRect(), pt, 0, INT8_MAX, vol)) { + if (widget == WID_GO_BASE_MUSIC_VOLUME) { + MusicDriver::GetInstance()->SetVolume(vol); + } else { + SetEffectVolume(vol); + } this->SetWidgetDirty(widget); SetWindowClassesDirty(WC_MUSIC_WINDOW); } @@ -487,6 +518,11 @@ struct GameOptionsWindow : Window { break; } + case WID_GO_BASE_MUSIC_JUKEBOX: { + ShowMusicWindow(); + break; + } + default: { int selected; DropDownList list = this->BuildDropDownList(widget, &selected); @@ -500,6 +536,19 @@ struct GameOptionsWindow : Window { } } + void OnMouseLoop() override + { + if (_left_button_down || this->gui_scale == _gui_scale) return; + + _gui_scale_cfg = this->gui_scale; + + if (AdjustGUIZoom(false)) { + ReInitAllWindows(true); + this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, false); + this->SetDirty(); + } + } + /** * Set the base media set. * @param index the index of the media set @@ -559,34 +608,6 @@ struct GameOptionsWindow : Window { break; } - case WID_GO_GUI_ZOOM_DROPDOWN: { - int8 new_zoom = index > 0 ? ZOOM_LVL_OUT_4X - index + 1 : ZOOM_LVL_CFG_AUTO; - if (new_zoom != _gui_zoom_cfg) { - GfxClearSpriteCache(); - _gui_zoom_cfg = new_zoom; - UpdateGUIZoom(); - UpdateCursorSize(); - UpdateAllVirtCoords(); - FixTitleGameZoom(); - ReInitAllWindows(true); - } - break; - } - - case WID_GO_FONT_ZOOM_DROPDOWN: { - int8 new_zoom = index > 0 ? ZOOM_LVL_OUT_4X - index + 1 : ZOOM_LVL_CFG_AUTO; - if (new_zoom != _font_zoom_cfg) { - GfxClearSpriteCache(); - _font_zoom_cfg = new_zoom; - UpdateGUIZoom(); - ClearFontCache(); - LoadStringWidthTable(); - UpdateAllVirtCoords(); - ReInitAllWindows(true); - } - break; - } - case WID_GO_BASE_GRF_DROPDOWN: this->SetMediaSet(index); break; @@ -618,6 +639,9 @@ struct GameOptionsWindow : Window { this->SetWidgetDisabledState(WID_GO_VIDEO_VSYNC_BUTTON, !_video_hw_accel); #endif + this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, _gui_scale_cfg == -1); + this->SetWidgetLoweredState(WID_GO_GUI_SCALE_BEVEL_BUTTON, _settings_client.gui.scale_bevels); + bool missing_files = BaseGraphics::GetUsedSet()->GetNumMissing() == 0; this->GetWidget(WID_GO_BASE_GRF_STATUS)->SetDataTip(missing_files ? STR_EMPTY : STR_GAME_OPTIONS_BASE_GRF_STATUS, STR_NULL); @@ -643,9 +667,6 @@ static const NWidgetPart _nested_game_options_widgets[] = { NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_AUTOSAVE_FRAME, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_AUTOSAVE_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP), SetFill(1, 0), EndContainer(), - NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GUI_ZOOM_FRAME, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_GUI_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0), - EndContainer(), NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_CURRENCY_UNITS_FRAME, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_CURRENCY_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_CURRENCY_UNITS_DROPDOWN_TOOLTIP), SetFill(1, 0), EndContainer(), @@ -655,8 +676,20 @@ static const NWidgetPart _nested_game_options_widgets[] = { NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_LANGUAGE, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_LANG_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_RAW_STRING, STR_GAME_OPTIONS_LANGUAGE_TOOLTIP), SetFill(1, 0), EndContainer(), - NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_FONT_ZOOM, STR_NULL), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GO_FONT_ZOOM_DROPDOWN), SetMinimalSize(150, 12), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP), SetFill(1, 0), + NWidget(WWT_FRAME, COLOUR_GREY), SetDataTip(STR_GAME_OPTIONS_GUI_SCALE_FRAME, STR_NULL), + NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), + NWidget(WWT_EMPTY, COLOUR_GREY, WID_GO_GUI_SCALE), SetMinimalSize(67, 0), SetMinimalTextLines(1, 12 + WidgetDimensions::unscaled.vsep_normal, FS_SMALL), SetFill(0, 0), SetDataTip(0x0, STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetDataTip(STR_GAME_OPTIONS_GUI_SCALE_AUTO, STR_NULL), + NWidget(NWID_SPACER), SetMinimalSize(1, 0), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_SCALE_AUTO), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetDataTip(STR_GAME_OPTIONS_GUI_SCALE_BEVELS, STR_NULL), + NWidget(NWID_SPACER), SetMinimalSize(1, 0), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_SCALE_BEVEL_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP), + EndContainer(), + EndContainer(), EndContainer(), EndContainer(), EndContainer(), @@ -731,7 +764,12 @@ static const NWidgetPart _nested_game_options_widgets[] = { NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_STATUS), SetMinimalSize(150, 12), SetDataTip(STR_EMPTY, STR_NULL), SetFill(1, 0), NWidget(WWT_EMPTY, COLOUR_GREY, WID_GO_BASE_MUSIC_VOLUME), SetMinimalSize(67, 12), SetFill(0, 0), SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC), EndContainer(), - NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0), + NWidget(NWID_HORIZONTAL), SetPIP(0, 30, 7), + NWidget(WWT_TEXT, COLOUR_GREY, WID_GO_BASE_MUSIC_DESCRIPTION), SetMinimalSize(330, 0), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP), SetFill(1, 0), SetPadding(6, 0, 6, 0), + NWidget(NWID_VERTICAL), SetPIP(0, 0, 0), + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_JUKEBOX), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_MUSIC, STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW), SetPadding(6, 0, 6, 0), + EndContainer(), + EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GO_BASE_MUSIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL), @@ -756,7 +794,6 @@ void ShowGameOptions() } static int SETTING_HEIGHT = 11; ///< Height of a single setting in the tree view in pixels -static const int LEVEL_WIDTH = 15; ///< Indenting width of a sub-page in pixels /** * Flags for #SettingEntry @@ -989,8 +1026,8 @@ uint BaseSettingEntry::Draw(GameSettings *settings_ptr, int left, int right, int if (cur_row >= max_row) return cur_row; bool rtl = _current_text_dir == TD_RTL; - int offset = rtl ? -4 : 4; - int level_width = rtl ? -LEVEL_WIDTH : LEVEL_WIDTH; + int offset = (rtl ? -(int)_circle_size.width : _circle_size.width) / 2; + int level_width = rtl ? -WidgetDimensions::scaled.hsep_indent : WidgetDimensions::scaled.hsep_indent; int x = rtl ? right : left; if (cur_row >= first_row) { @@ -1007,7 +1044,7 @@ uint BaseSettingEntry::Draw(GameSettings *settings_ptr, int left, int right, int int bottom_y = (flags & SEF_LAST_FIELD) ? halfway_y : y + SETTING_HEIGHT - 1; GfxDrawLine(x + offset, y, x + offset, bottom_y, colour); /* Small horizontal line from the last vertical line */ - GfxDrawLine(x + offset, halfway_y, x + level_width - offset, halfway_y, colour); + GfxDrawLine(x + offset, halfway_y, x + level_width - WidgetDimensions::scaled.hsep_normal, halfway_y, colour); x += level_width; this->DrawSetting(settings_ptr, rtl ? left : x, rtl ? x : right, y, this == selected); @@ -1199,8 +1236,8 @@ void SettingEntry::DrawSetting(GameSettings *settings_ptr, int left, int right, bool rtl = _current_text_dir == TD_RTL; uint buttons_left = rtl ? right + 1 - SETTING_BUTTON_WIDTH : left; - uint text_left = left + (rtl ? 0 : SETTING_BUTTON_WIDTH + 5); - uint text_right = right - (rtl ? SETTING_BUTTON_WIDTH + 5 : 0); + uint text_left = left + (rtl ? 0 : SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide); + uint text_right = right - (rtl ? SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide : 0); uint button_y = y + (SETTING_HEIGHT - SETTING_BUTTON_HEIGHT) / 2; /* We do not allow changes of some items when we are a client in a networkgame */ @@ -1547,7 +1584,7 @@ void SettingsPage::DrawSetting(GameSettings *settings_ptr, int left, int right, { bool rtl = _current_text_dir == TD_RTL; DrawSprite((this->folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED), PAL_NONE, rtl ? right - _circle_size.width : left, y + (SETTING_HEIGHT - _circle_size.height) / 2); - DrawString(rtl ? left : left + _circle_size.width + 2, rtl ? right - _circle_size.width - 2 : right, y + (SETTING_HEIGHT - FONT_HEIGHT_NORMAL) / 2, this->title); + DrawString(rtl ? left : left + _circle_size.width + WidgetDimensions::scaled.hsep_normal, rtl ? right - _circle_size.width - WidgetDimensions::scaled.hsep_normal : right, y + (SETTING_HEIGHT - FONT_HEIGHT_NORMAL) / 2, this->title); } /** Construct settings tree */ @@ -1644,6 +1681,7 @@ static SettingsContainer &GetSettingsTree() interface->Add(new SettingEntry("gui.timetable_in_ticks")); interface->Add(new SettingEntry("gui.timetable_arrival_departure")); interface->Add(new SettingEntry("gui.show_newgrf_name")); + interface->Add(new SettingEntry("gui.show_cargo_in_vehicle_lists")); } SettingsPage *advisors = main->Add(new SettingsPage(STR_CONFIG_SETTING_ADVISORS)); @@ -1896,11 +1934,6 @@ static void ResetAllSettingsConfirmationCallback(Window *w, bool confirmed) /** Window to edit settings of the game. */ struct GameSettingsWindow : Window { - static const int SETTINGTREE_LEFT_OFFSET = 5; ///< Position of left edge of setting values - static const int SETTINGTREE_RIGHT_OFFSET = 5; ///< Position of right edge of setting values - static const int SETTINGTREE_TOP_OFFSET = 5; ///< Position of top edge of setting values - static const int SETTINGTREE_BOTTOM_OFFSET = 5; ///< Position of bottom edge of setting values - static GameSettings *settings_ptr; ///< Pointer to the game settings being displayed and modified. SettingEntry *valuewindow_entry; ///< If non-nullptr, pointer to setting for which a value-entering window has been opened. @@ -1927,7 +1960,6 @@ struct GameSettingsWindow : Window { this->filter.type_hides = false; this->settings_ptr = &GetGameSettings(); - _circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED)); GetSettingsTree().FoldAll(); // Close all sub-pages this->valuewindow_entry = nullptr; // No setting entry for which a entry window is opened @@ -1948,14 +1980,19 @@ struct GameSettingsWindow : Window { this->InvalidateData(); } + void OnInit() override + { + _circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED)); + } + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_GS_OPTIONSPANEL: - resize->height = SETTING_HEIGHT = std::max({(int)_circle_size.height, SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL}) + 1; - resize->width = 1; + resize->height = SETTING_HEIGHT = std::max({(int)_circle_size.height, SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL}) + WidgetDimensions::scaled.vsep_normal; + resize->width = 1; - size->height = 5 * resize->height + SETTINGTREE_TOP_OFFSET + SETTINGTREE_BOTTOM_OFFSET; + size->height = 5 * resize->height + WidgetDimensions::scaled.framerect.Vertical(); break; case WID_GS_HELP_TEXT: { @@ -1968,7 +2005,7 @@ struct GameSettingsWindow : Window { SetDParam(0, setting_types[i]); size->width = std::max(size->width, GetStringBoundingBox(STR_CONFIG_SETTING_TYPE).width); } - size->height = 2 * FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL + + size->height = 2 * FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal + std::max(size->height, GetSettingsTree().GetMaxHelpHeight(size->width)); break; } @@ -1993,14 +2030,14 @@ struct GameSettingsWindow : Window { } /* Reserve the correct number of lines for the 'some search results are hidden' notice in the central settings display panel. */ - const NWidgetBase *panel = this->GetWidget(WID_GS_OPTIONSPANEL); + const Rect panel = this->GetWidget(WID_GS_OPTIONSPANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext); StringID warn_str = STR_CONFIG_SETTING_CATEGORY_HIDES - 1 + this->warn_missing; int new_warn_lines; if (this->warn_missing == WHR_NONE) { new_warn_lines = 0; } else { SetDParam(0, _game_settings_restrict_dropdown[this->filter.min_cat]); - new_warn_lines = GetStringLineCount(warn_str, panel->current_x); + new_warn_lines = GetStringLineCount(warn_str, panel.Width()); } if (this->warn_lines != new_warn_lines) { this->vscroll->SetCount(this->vscroll->GetCount() - this->warn_lines + new_warn_lines); @@ -2011,16 +2048,8 @@ struct GameSettingsWindow : Window { /* Draw the 'some search results are hidden' notice. */ if (this->warn_missing != WHR_NONE) { - const int left = panel->pos_x; - const int right = left + panel->current_x - 1; - const int top = panel->pos_y + WD_FRAMETEXT_TOP + (SETTING_HEIGHT - FONT_HEIGHT_NORMAL) * this->warn_lines / 2; SetDParam(0, _game_settings_restrict_dropdown[this->filter.min_cat]); - if (this->warn_lines == 1) { - /* If the warning fits at one line, center it. */ - DrawString(left + WD_FRAMETEXT_LEFT, right - WD_FRAMETEXT_RIGHT, top, warn_str, TC_FROMSTRING, SA_HOR_CENTER); - } else { - DrawStringMultiLine(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, INT32_MAX, warn_str, TC_FROMSTRING, SA_HOR_CENTER); - } + DrawStringMultiLine(panel.WithHeight(this->warn_lines * FONT_HEIGHT_NORMAL), warn_str, TC_FROMSTRING, SA_CENTER); } } @@ -2070,11 +2099,12 @@ struct GameSettingsWindow : Window { { switch (widget) { case WID_GS_OPTIONSPANEL: { - int top_pos = r.top + SETTINGTREE_TOP_OFFSET + 1 + this->warn_lines * SETTING_HEIGHT; + Rect tr = r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect); + tr.top += this->warn_lines * SETTING_HEIGHT; uint last_row = this->vscroll->GetPosition() + this->vscroll->GetCapacity() - this->warn_lines; - int next_row = GetSettingsTree().Draw(settings_ptr, r.left + SETTINGTREE_LEFT_OFFSET, r.right - SETTINGTREE_RIGHT_OFFSET, top_pos, + int next_row = GetSettingsTree().Draw(settings_ptr, tr.left, tr.right, tr.top, this->vscroll->GetPosition(), last_row, this->last_clicked); - if (next_row == 0) DrawString(r.left + SETTINGTREE_LEFT_OFFSET, r.right - SETTINGTREE_RIGHT_OFFSET, top_pos, STR_CONFIG_SETTINGS_NONE); + if (next_row == 0) DrawString(tr, STR_CONFIG_SETTINGS_NONE); break; } @@ -2082,21 +2112,21 @@ struct GameSettingsWindow : Window { if (this->last_clicked != nullptr) { const IntSettingDesc *sd = this->last_clicked->setting; - int y = r.top; + Rect tr = r; switch (sd->GetType()) { case ST_COMPANY: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_COMPANY_INGAME); break; case ST_CLIENT: SetDParam(0, STR_CONFIG_SETTING_TYPE_CLIENT); break; case ST_GAME: SetDParam(0, _game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_GAME_MENU : STR_CONFIG_SETTING_TYPE_GAME_INGAME); break; default: NOT_REACHED(); } - DrawString(r.left, r.right, y, STR_CONFIG_SETTING_TYPE); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_CONFIG_SETTING_TYPE); + tr.top += FONT_HEIGHT_NORMAL; this->last_clicked->SetValueDParams(0, sd->def); - DrawString(r.left, r.right, y, STR_CONFIG_SETTING_DEFAULT_VALUE); - y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL; + DrawString(tr, STR_CONFIG_SETTING_DEFAULT_VALUE); + tr.top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; - DrawStringMultiLine(r.left, r.right, y, r.bottom, this->last_clicked->GetHelpText(), TC_WHITE); + DrawStringMultiLine(tr, this->last_clicked->GetHelpText(), TC_WHITE); } break; @@ -2158,7 +2188,7 @@ struct GameSettingsWindow : Window { if (widget != WID_GS_OPTIONSPANEL) return; - uint btn = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GS_OPTIONSPANEL, SETTINGTREE_TOP_OFFSET); + uint btn = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GS_OPTIONSPANEL, WidgetDimensions::scaled.framerect.top); if (btn == INT_MAX || (int)btn < this->warn_lines) return; btn -= this->warn_lines; @@ -2167,7 +2197,7 @@ struct GameSettingsWindow : Window { if (clicked_entry == nullptr) return; // Clicked below the last setting of the page - int x = (_current_text_dir == TD_RTL ? this->width - 1 - pt.x : pt.x) - SETTINGTREE_LEFT_OFFSET - (clicked_entry->level + 1) * LEVEL_WIDTH; // Shift x coordinate + int x = (_current_text_dir == TD_RTL ? this->width - 1 - pt.x : pt.x) - WidgetDimensions::scaled.frametext.left - (clicked_entry->level + 1) * WidgetDimensions::scaled.hsep_indent; // Shift x coordinate if (x < 0) return; // Clicked left of the entry SettingsPage *clicked_page = dynamic_cast(clicked_entry); @@ -2208,7 +2238,7 @@ struct GameSettingsWindow : Window { this->closing_dropdown = false; const NWidgetBase *wid = this->GetWidget(WID_GS_OPTIONSPANEL); - int rel_y = (pt.y - (int)wid->pos_y - SETTINGTREE_TOP_OFFSET) % wid->resize_y; + int rel_y = (pt.y - (int)wid->pos_y - WidgetDimensions::scaled.framerect.top) % wid->resize_y; Rect wi_rect; wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x); @@ -2288,10 +2318,13 @@ struct GameSettingsWindow : Window { /* Show the correct currency-translated value */ if (sd->flags & SF_GUI_CURRENCY) value64 *= _currency->rate; + CharSetFilter charset_filter = CS_NUMERAL; //default, only numeric input allowed + if (sd->min < 0) charset_filter = CS_NUMERAL_SIGNED; // special case, also allow '-' sign for negative input + this->valuewindow_entry = pe; SetDParam(0, value64); /* Limit string length to 14 so that MAX_INT32 * max currency rate doesn't exceed MAX_INT64. */ - ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 15, this, CS_NUMERAL, QSF_ENABLE_DEFAULT); + ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 15, this, charset_filter, QSF_ENABLE_DEFAULT); } this->SetDisplayedHelpText(pe); } @@ -2433,7 +2466,7 @@ struct GameSettingsWindow : Window { void OnResize() override { - this->vscroll->SetCapacityFromWidget(this, WID_GS_OPTIONSPANEL, SETTINGTREE_TOP_OFFSET + SETTINGTREE_BOTTOM_OFFSET); + this->vscroll->SetCapacityFromWidget(this, WID_GS_OPTIONSPANEL, WidgetDimensions::scaled.framerect.Vertical()); } }; @@ -2446,30 +2479,28 @@ static const NWidgetPart _nested_settings_selection_widgets[] = { NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE), EndContainer(), NWidget(WWT_PANEL, COLOUR_MAUVE), - NWidget(NWID_VERTICAL), SetPIP(0, WD_PAR_VSEP_NORMAL, 0), SetPadding(WD_TEXTPANEL_TOP, 0, WD_TEXTPANEL_BOTTOM, 0), - NWidget(NWID_HORIZONTAL), SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_RIGHT), + NWidget(NWID_VERTICAL), SetPIP(WidgetDimensions::unscaled.frametext.top, WidgetDimensions::unscaled.vsep_normal, WidgetDimensions::unscaled.frametext.bottom), + NWidget(NWID_HORIZONTAL), SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.hsep_wide, WidgetDimensions::unscaled.frametext.right), NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_CATEGORY), SetDataTip(STR_CONFIG_SETTING_RESTRICT_CATEGORY, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_RESTRICT_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), EndContainer(), - NWidget(NWID_HORIZONTAL), SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_RIGHT), + NWidget(NWID_HORIZONTAL), SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.hsep_wide, WidgetDimensions::unscaled.frametext.right), NWidget(WWT_TEXT, COLOUR_MAUVE, WID_GS_RESTRICT_TYPE), SetDataTip(STR_CONFIG_SETTING_RESTRICT_TYPE, STR_NULL), NWidget(WWT_DROPDOWN, COLOUR_MAUVE, WID_GS_TYPE_DROPDOWN), SetMinimalSize(100, 12), SetDataTip(STR_BLACK_STRING, STR_CONFIG_SETTING_TYPE_DROPDOWN_HELPTEXT), SetFill(1, 0), SetResize(1, 0), EndContainer(), - EndContainer(), - NWidget(NWID_HORIZONTAL), SetPadding(0, 0, WD_TEXTPANEL_BOTTOM, 0), - SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_RIGHT), - NWidget(WWT_TEXT, COLOUR_MAUVE), SetFill(0, 1), SetDataTip(STR_CONFIG_SETTING_FILTER_TITLE, STR_NULL), - NWidget(WWT_EDITBOX, COLOUR_MAUVE, WID_GS_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0), - SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), + NWidget(NWID_HORIZONTAL), SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.hsep_wide, WidgetDimensions::unscaled.frametext.right), + NWidget(WWT_TEXT, COLOUR_MAUVE), SetFill(0, 1), SetDataTip(STR_CONFIG_SETTING_FILTER_TITLE, STR_NULL), + NWidget(WWT_EDITBOX, COLOUR_MAUVE, WID_GS_FILTER), SetMinimalSize(50, 12), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), SetFill(1, 0), SetResize(1, 0), + EndContainer(), EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_MAUVE, WID_GS_OPTIONSPANEL), SetMinimalSize(400, 174), SetScrollbar(WID_GS_SCROLLBAR), EndContainer(), NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_GS_SCROLLBAR), EndContainer(), - NWidget(WWT_PANEL, COLOUR_MAUVE), SetMinimalSize(400, 40), + NWidget(WWT_PANEL, COLOUR_MAUVE), NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GS_HELP_TEXT), SetMinimalSize(300, 25), SetFill(1, 1), SetResize(1, 0), - SetPadding(WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM, WD_FRAMETEXT_LEFT), + SetPadding(WidgetDimensions::unscaled.frametext), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GS_EXPAND_ALL), SetDataTip(STR_CONFIG_SETTING_EXPAND_ALL, STR_NULL), @@ -2510,18 +2541,21 @@ void DrawArrowButtons(int x, int y, Colours button_colour, byte state, bool clic int colour = _colour_gradient[button_colour][2]; Dimension dim = NWidgetScrollbar::GetHorizontalDimension(); - DrawFrameRect(x, y, x + dim.width - 1, y + dim.height - 1, button_colour, (state == 1) ? FR_LOWERED : FR_NONE); - DrawFrameRect(x + dim.width, y, x + dim.width + dim.width - 1, y + dim.height - 1, button_colour, (state == 2) ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_LEFT, PAL_NONE, x + WD_IMGBTN_LEFT, y + WD_IMGBTN_TOP); - DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, x + WD_IMGBTN_LEFT + dim.width, y + WD_IMGBTN_TOP); + Rect lr = {x, y, x + (int)dim.width - 1, y + (int)dim.height - 1}; + Rect rr = {x + (int)dim.width, y, x + (int)dim.width * 2 - 1, y + (int)dim.height - 1}; + + DrawFrameRect(lr, button_colour, (state == 1) ? FR_LOWERED : FR_NONE); + DrawFrameRect(rr, button_colour, (state == 2) ? FR_LOWERED : FR_NONE); + DrawSpriteIgnorePadding(SPR_ARROW_LEFT, PAL_NONE, lr, (state == 1), SA_CENTER); + DrawSpriteIgnorePadding(SPR_ARROW_RIGHT, PAL_NONE, rr, (state == 2), SA_CENTER); /* Grey out the buttons that aren't clickable */ bool rtl = _current_text_dir == TD_RTL; if (rtl ? !clickable_right : !clickable_left) { - GfxFillRect(x + 1, y, x + dim.width - 1, y + dim.height - 2, colour, FILLRECT_CHECKER); + GfxFillRect(lr.Shrink(WidgetDimensions::scaled.bevel), colour, FILLRECT_CHECKER); } if (rtl ? !clickable_left : !clickable_right) { - GfxFillRect(x + dim.width + 1, y, x + dim.width + dim.width - 1, y + dim.height - 2, colour, FILLRECT_CHECKER); + GfxFillRect(rr.Shrink(WidgetDimensions::scaled.bevel), colour, FILLRECT_CHECKER); } } @@ -2537,11 +2571,13 @@ void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool cl { int colour = _colour_gradient[button_colour][2]; - DrawFrameRect(x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1, button_colour, state ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_DOWN, PAL_NONE, x + (SETTING_BUTTON_WIDTH - NWidgetScrollbar::GetVerticalDimension().width) / 2 + state, y + 2 + state); + Rect r = {x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1}; + + DrawFrameRect(r, button_colour, state ? FR_LOWERED : FR_NONE); + DrawSpriteIgnorePadding(SPR_ARROW_DOWN, PAL_NONE, r, state, SA_CENTER); if (!clickable) { - GfxFillRect(x + 1, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 2, colour, FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), colour, FILLRECT_CHECKER); } } @@ -2555,7 +2591,9 @@ void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool cl void DrawBoolButton(int x, int y, bool state, bool clickable) { static const Colours _bool_ctabs[2][2] = {{COLOUR_CREAM, COLOUR_RED}, {COLOUR_DARK_GREEN, COLOUR_GREEN}}; - DrawFrameRect(x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1, _bool_ctabs[state][clickable], state ? FR_LOWERED : FR_NONE); + + Rect r = {x, y, x + SETTING_BUTTON_WIDTH - 1, y + SETTING_BUTTON_HEIGHT - 1}; + DrawFrameRect(r, _bool_ctabs[state][clickable], state ? FR_LOWERED : FR_NONE); } struct CustomCurrencyWindow : Window { diff --git a/src/settings_internal.h b/src/settings_internal.h index 75b520222c623..914c8a79fa53a 100644 --- a/src/settings_internal.h +++ b/src/settings_internal.h @@ -70,7 +70,7 @@ struct IniItem; /** Properties of config file settings. */ struct SettingDesc { - SettingDesc(SaveLoad save, SettingFlag flags, bool startup) : + SettingDesc(const SaveLoad &save, SettingFlag flags, bool startup) : flags(flags), startup(startup), save(save) {} virtual ~SettingDesc() {} @@ -149,7 +149,7 @@ struct IntSettingDesc : SettingDesc { */ typedef void PostChangeCallback(int32 value); - IntSettingDesc(SaveLoad save, SettingFlag flags, bool startup, int32 def, + IntSettingDesc(const SaveLoad &save, SettingFlag flags, bool startup, int32 def, int32 min, uint32 max, int32 interval, StringID str, StringID str_help, StringID str_val, SettingCategory cat, PreChangeCheck pre_check, PostChangeCallback post_callback) : SettingDesc(save, flags, startup), def(def), min(min), max(max), interval(interval), @@ -191,7 +191,7 @@ struct IntSettingDesc : SettingDesc { /** Boolean setting. */ struct BoolSettingDesc : IntSettingDesc { - BoolSettingDesc(SaveLoad save, SettingFlag flags, bool startup, bool def, + BoolSettingDesc(const SaveLoad &save, SettingFlag flags, bool startup, bool def, StringID str, StringID str_help, StringID str_val, SettingCategory cat, PreChangeCheck pre_check, PostChangeCallback post_callback) : IntSettingDesc(save, flags, startup, def, 0, 1, 0, str, str_help, str_val, cat, @@ -207,7 +207,7 @@ struct BoolSettingDesc : IntSettingDesc { struct OneOfManySettingDesc : IntSettingDesc { typedef size_t OnConvert(const char *value); ///< callback prototype for conversion error - OneOfManySettingDesc(SaveLoad save, SettingFlag flags, bool startup, int32 def, + OneOfManySettingDesc(const SaveLoad &save, SettingFlag flags, bool startup, int32 def, int32 max, StringID str, StringID str_help, StringID str_val, SettingCategory cat, PreChangeCheck pre_check, PostChangeCallback post_callback, std::initializer_list many, OnConvert *many_cnvt) : @@ -231,7 +231,7 @@ struct OneOfManySettingDesc : IntSettingDesc { /** Many of many setting. */ struct ManyOfManySettingDesc : OneOfManySettingDesc { - ManyOfManySettingDesc(SaveLoad save, SettingFlag flags, bool startup, + ManyOfManySettingDesc(const SaveLoad &save, SettingFlag flags, bool startup, int32 def, StringID str, StringID str_help, StringID str_val, SettingCategory cat, PreChangeCheck pre_check, PostChangeCallback post_callback, std::initializer_list many, OnConvert *many_cnvt) : @@ -260,7 +260,7 @@ struct StringSettingDesc : SettingDesc { */ typedef void PostChangeCallback(const std::string &value); - StringSettingDesc(SaveLoad save, SettingFlag flags, bool startup, const char *def, + StringSettingDesc(const SaveLoad &save, SettingFlag flags, bool startup, const char *def, uint32 max_length, PreChangeCheck pre_check, PostChangeCallback post_callback) : SettingDesc(save, flags, startup), def(def == nullptr ? "" : def), max_length(max_length), pre_check(pre_check), post_callback(post_callback) {} @@ -286,7 +286,7 @@ struct StringSettingDesc : SettingDesc { /** List/array settings. */ struct ListSettingDesc : SettingDesc { - ListSettingDesc(SaveLoad save, SettingFlag flags, bool startup, const char *def) : + ListSettingDesc(const SaveLoad &save, SettingFlag flags, bool startup, const char *def) : SettingDesc(save, flags, startup), def(def) {} virtual ~ListSettingDesc() {} @@ -299,7 +299,7 @@ struct ListSettingDesc : SettingDesc { /** Placeholder for settings that have been removed, but might still linger in the savegame. */ struct NullSettingDesc : SettingDesc { - NullSettingDesc(SaveLoad save) : + NullSettingDesc(const SaveLoad &save) : SettingDesc(save, SF_NOT_IN_CONFIG, false) {} virtual ~NullSettingDesc() {} diff --git a/src/settings_table.cpp b/src/settings_table.cpp index d0b1fb95e3ee3..9fda41720f90a 100644 --- a/src/settings_table.cpp +++ b/src/settings_table.cpp @@ -42,7 +42,9 @@ #include "ship.h" #include "smallmap_gui.h" #include "roadveh.h" +#include "roadveh_cmd.h" #include "vehicle_func.h" +#include "viewport_func.h" #include "void_map.h" #include "table/strings.h" @@ -258,7 +260,6 @@ static void TownFoundingChanged(int32 new_value) static void ZoomMinMaxChanged(int32 new_value) { - extern void ConstrainAllViewportsZoom(); ConstrainAllViewportsZoom(); GfxClearSpriteCache(); if (_settings_client.gui.zoom_min > _gui_zoom) { @@ -286,7 +287,7 @@ static void InvalidateNewGRFChangeWindows(int32 new_value) { InvalidateWindowClassesData(WC_SAVELOAD); CloseWindowByClass(WC_GAME_OPTIONS); - ReInitAllWindows(_gui_zoom_cfg); + ReInitAllWindows(false); } static void InvalidateCompanyLiveryWindow(int32 new_value) @@ -323,7 +324,6 @@ static void MaxNoAIsChange(int32 new_value) */ static bool CheckRoadSide(int32 &new_value) { - extern bool RoadVehiclesAreBuilt(); return _game_mode == GM_MENU || !RoadVehiclesAreBuilt(); } @@ -360,26 +360,26 @@ static bool CheckFreeformEdges(int32 &new_value) } } } else { - for (uint i = 0; i < MapMaxX(); i++) { + for (uint i = 0; i < Map::MaxX(); i++) { if (TileHeight(TileXY(i, 1)) != 0) { ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); return false; } } - for (uint i = 1; i < MapMaxX(); i++) { - if (!IsTileType(TileXY(i, MapMaxY() - 1), MP_WATER) || TileHeight(TileXY(1, MapMaxY())) != 0) { + for (uint i = 1; i < Map::MaxX(); i++) { + if (!IsTileType(TileXY(i, Map::MaxY() - 1), MP_WATER) || TileHeight(TileXY(1, Map::MaxY())) != 0) { ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); return false; } } - for (uint i = 0; i < MapMaxY(); i++) { + for (uint i = 0; i < Map::MaxY(); i++) { if (TileHeight(TileXY(1, i)) != 0) { ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); return false; } } - for (uint i = 1; i < MapMaxY(); i++) { - if (!IsTileType(TileXY(MapMaxX() - 1, i), MP_WATER) || TileHeight(TileXY(MapMaxX(), i)) != 0) { + for (uint i = 1; i < Map::MaxY(); i++) { + if (!IsTileType(TileXY(Map::MaxX() - 1, i), MP_WATER) || TileHeight(TileXY(Map::MaxX(), i)) != 0) { ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_WATER, INVALID_STRING_ID, WL_ERROR); return false; } @@ -393,15 +393,15 @@ static void UpdateFreeformEdges(int32 new_value) if (_game_mode == GM_MENU) return; if (new_value != 0) { - for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0)); - for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y)); + for (uint x = 0; x < Map::SizeX(); x++) MakeVoid(TileXY(x, 0)); + for (uint y = 0; y < Map::SizeY(); y++) MakeVoid(TileXY(0, y)); } else { /* Make tiles at the border water again. */ - for (uint i = 0; i < MapMaxX(); i++) { + for (uint i = 0; i < Map::MaxX(); i++) { SetTileHeight(TileXY(i, 0), 0); SetTileType(TileXY(i, 0), MP_WATER); } - for (uint i = 0; i < MapMaxY(); i++) { + for (uint i = 0; i < Map::MaxY(); i++) { SetTileHeight(TileXY(0, i), 0); SetTileType(TileXY(0, i), MP_WATER); } @@ -432,7 +432,7 @@ static bool CheckMaxHeightLevel(int32 &new_value) /* Check if at least one mountain on the map is higher than the new value. * If yes, disallow the change. */ - for (TileIndex t = 0; t < MapSize(); t++) { + for (TileIndex t = 0; t < Map::Size(); t++) { if ((int32)TileHeight(t) > new_value) { ShowErrorMessage(STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN, INVALID_STRING_ID, WL_ERROR); /* Return old, unchanged value */ @@ -477,7 +477,11 @@ static bool ReplaceAsteriskWithEmptyPassword(std::string &newval) static void UpdateClientConfigValues() { NetworkServerUpdateGameInfo(); - if (_network_server) NetworkServerSendConfigUpdate(); + + if (_network_server) { + NetworkServerSendConfigUpdate(); + SetWindowClassesDirty(WC_CLIENT_LIST); + } } /* End - Callback Functions */ diff --git a/src/settings_type.h b/src/settings_type.h index 43bf96f169d39..5d669c093ca54 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -58,6 +58,8 @@ enum IndustryDensity { ID_NORMAL, ///< Normal amount of industries at game start. ID_HIGH, ///< Many industries at game start. + ID_CUSTOM, ///< Custom number of industries. + ID_END, ///< Number of industry density settings. }; @@ -76,7 +78,7 @@ struct DifficultySettings { byte max_no_competitors; ///< the number of competitors (AIs) byte number_towns; ///< the amount of towns byte industry_density; ///< The industry density. @see IndustryDensity - uint32 max_loan; ///< the maximum initial loan + uint32 max_loan; ///< the maximum initial loan. NOT Pace scaled! byte initial_interest; ///< amount of interest (to pay over the loan) byte vehicle_costs; ///< amount of money spent on vehicle running cost byte competitor_speed; ///< the speed at which the AI builds @@ -170,6 +172,7 @@ struct GUISettings { uint8 osk_activation; ///< Mouse gesture to trigger the OSK. byte starting_colour; ///< default color scheme for the company to start a new game with bool show_newgrf_name; ///< Show the name of the NewGRF in the build vehicle window + bool show_cargo_in_vehicle_lists; ///< Show the cargoes the vehicles can carry in the list windows bool auto_remove_signals; ///< automatically remove signals when in the way during rail construction uint16 refresh_rate; ///< How often we refresh the screen (time between draw-ticks). uint16 fast_forward_speed_limit; ///< Game speed to use when fast-forward is enabled. @@ -187,12 +190,14 @@ struct GUISettings { uint8 developer; ///< print non-fatal warnings in console (>= 1), copy debug output to console (== 2) bool show_date_in_logs; ///< whether to show dates in console logs bool newgrf_developer_tools; ///< activate NewGRF developer tools and allow modifying NewGRFs in an existing game - bool ai_developer_tools; ///< activate AI developer tools + bool ai_developer_tools; ///< activate AI/GS developer tools bool scenario_developer; ///< activate scenario developer: allow modifying NewGRFs in an existing game uint8 settings_restriction_mode; ///< selected restriction mode in adv. settings GUI. @see RestrictionMode bool newgrf_show_old_versions; ///< whether to show old versions in the NewGRF list uint8 newgrf_default_palette; ///< default palette to use for NewGRFs without action 14 palette information + bool scale_bevels; ///< bevels are scaled with GUI scale. + /** * Returns true when the user has sufficient privileges to edit newgrfs on a running game * @return whether the user has sufficient privileges to edit newgrfs in an existing game @@ -323,6 +328,7 @@ struct GameCreationSettings { byte landscape; ///< the landscape we're currently in byte water_borders; ///< bitset of the borders that are water uint16 custom_town_number; ///< manually entered number of towns + uint16 custom_industry_number; ///< manually entered number of industries byte variety; ///< variety level applied to TGP byte custom_terrain_type; ///< manually entered height for TGP to aim for byte custom_sea_level; ///< manually entered percentage of water in the map @@ -357,6 +363,8 @@ struct ConstructionSettings { uint16 clear_frame_burst; ///< how many tiles may, over a short period, be cleared? uint32 tree_per_64k_frames; ///< how many trees may, over a long period, be planted per 65536 frames? uint16 tree_frame_burst; ///< how many trees may, over a short period, be planted? + uint32 build_object_per_64k_frames; ///< how many tiles may, over a long period, be purchased or have objects built on them per 65536 frames? + uint16 build_object_frame_burst; ///< how many tiles may, over a short period, be purchased or have objects built on them? }; /** Settings related to the AI. */ @@ -570,7 +578,7 @@ struct VehicleDefaultSettings { struct CompanySettings { bool engine_renew; ///< is autorenew enabled int16 engine_renew_months; ///< months before/after the maximum vehicle age a vehicle should be renewed - uint32 engine_renew_money; ///< minimum amount of money before autorenew is used + uint32 engine_renew_money; ///< minimum amount of money before autorenew is used. NOT Pace scaled bool renew_keep_length; ///< sell some wagons if after autoreplace the train is longer than before VehicleDefaultSettings vehicle; ///< default settings for vehicles }; diff --git a/src/ship.h b/src/ship.h index b3540914981ca..416f56e54c4aa 100644 --- a/src/ship.h +++ b/src/ship.h @@ -35,25 +35,25 @@ struct Ship FINAL : public SpecializedVehicle { /** We want to 'destruct' the right class. */ virtual ~Ship() { this->PreDestructor(); } - void MarkDirty(); - void UpdateDeltaXY(); - ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_SHIP_REVENUE : EXPENSES_SHIP_RUN; } - void PlayLeaveStationSound() const; - bool IsPrimaryVehicle() const { return true; } - void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const; - int GetDisplaySpeed() const { return this->cur_speed / 2; } - int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; } - int GetCurrentMaxSpeed() const { return std::min(this->vcache.cached_max_speed, this->current_order.GetMaxSpeed() * 2); } - Money GetRunningCost() const; - bool IsInDepot() const { return this->state == TRACK_BIT_DEPOT; } - bool Tick(); - void OnNewVanillaDay(); - void OnNewDay(); - Trackdir GetVehicleTrackdir() const; - TileIndex GetOrderStationLocation(StationID station); - bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse); + void MarkDirty() override; + void UpdateDeltaXY() override; + ExpensesType GetExpenseType(bool income) const override { return income ? EXPENSES_SHIP_REVENUE : EXPENSES_SHIP_RUN; } + void PlayLeaveStationSound(bool force = false) const override; + bool IsPrimaryVehicle() const override { return true; } + void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override; + int GetDisplaySpeed() const override { return this->cur_speed / 2; } + int GetDisplayMaxSpeed() const override { return this->vcache.cached_max_speed / 2; } + int GetCurrentMaxSpeed() const override { return std::min(this->vcache.cached_max_speed, this->current_order.GetMaxSpeed() * 2); } + Money GetRunningCost() const override; + bool IsInDepot() const override { return this->state == TRACK_BIT_DEPOT; } + bool Tick() override; + void OnNewVanillaDay() override; + void OnNewDay() override; + Trackdir GetVehicleTrackdir() const override; + TileIndex GetOrderStationLocation(StationID station) override; + ClosestDepot FindClosestDepot() override; void UpdateCache(); - void SetDestTile(TileIndex tile); + void SetDestTile(TileIndex tile) override; }; bool IsShipDestinationTile(TileIndex tile, StationID station); diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 8db354f5461a1..4e07109155cdb 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -119,8 +119,8 @@ void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, i Rect rect; seq.GetBounds(&rect); - width = UnScaleGUI(rect.right - rect.left + 1); - height = UnScaleGUI(rect.bottom - rect.top + 1); + width = UnScaleGUI(rect.Width()); + height = UnScaleGUI(rect.Height()); xoffs = UnScaleGUI(rect.left); yoffs = UnScaleGUI(rect.top); } @@ -274,16 +274,10 @@ void Ship::MarkDirty() this->UpdateCache(); } -static void PlayShipSound(const Vehicle *v) +void Ship::PlayLeaveStationSound(bool force) const { - if (!PlayVehicleSound(v, VSE_START)) { - SndPlayVehicleFx(ShipVehInfo(v->engine_type)->sfx, v); - } -} - -void Ship::PlayLeaveStationSound() const -{ - PlayShipSound(this); + if (PlayVehicleSound(this, VSE_START, force)) return; + SndPlayVehicleFx(ShipVehInfo(this->engine_type)->sfx, this); } TileIndex Ship::GetOrderStationLocation(StationID station) @@ -400,7 +394,7 @@ static bool CheckShipLeaveDepot(Ship *v) v->UpdateViewport(true, true); SetWindowDirty(WC_VEHICLE_DEPOT, v->tile); - PlayShipSound(v); + v->PlayLeaveStationSound(); VehicleServiceInDepot(v); InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); SetWindowClassesDirty(WC_SHIPS_LIST); @@ -921,14 +915,10 @@ CommandCost CmdBuildShip(DoCommandFlag flags, TileIndex tile, const Engine *e, V return CommandCost(); } -bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) +ClosestDepot Ship::FindClosestDepot() { const Depot *depot = FindClosestShipDepot(this, 0); + if (depot == nullptr) return ClosestDepot(); - if (depot == nullptr) return false; - - if (location != nullptr) *location = depot->xy; - if (destination != nullptr) *destination = depot->index; - - return true; + return ClosestDepot(depot->xy, depot->index); } diff --git a/src/ship_gui.cpp b/src/ship_gui.cpp index aff7077f076ef..d5991c9b936ad 100644 --- a/src/ship_gui.cpp +++ b/src/ship_gui.cpp @@ -24,12 +24,10 @@ /** * Draws an image of a ship * @param v Front vehicle - * @param left The minimum horizontal position - * @param right The maximum horizontal position - * @param y Vertical position to draw at + * @param r Rect to draw at * @param selection Selected vehicle to draw a frame around */ -void DrawShipImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type) +void DrawShipImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type) { bool rtl = _current_text_dir == TD_RTL; @@ -39,17 +37,19 @@ void DrawShipImage(const Vehicle *v, int left, int right, int y, VehicleID selec Rect rect; seq.GetBounds(&rect); - int width = UnScaleGUI(rect.right - rect.left + 1); + int width = UnScaleGUI(rect.Width()); int x_offs = UnScaleGUI(rect.left); - int x = rtl ? right - width - x_offs : left - x_offs; + int x = rtl ? r.right - width - x_offs : r.left - x_offs; + /* This magic -1 offset is related to the sprite_y_offsets in build_vehicle_gui.cpp */ + int y = ScaleSpriteTrad(-1) + CenterBounds(r.top, r.bottom, 0); - y += ScaleGUITrad(10); seq.Draw(x, y, GetVehiclePalette(v), false); if (v->index == selection) { x += x_offs; y += UnScaleGUI(rect.top); - DrawFrameRect(x - 1, y - 1, x + width + 1, y + UnScaleGUI(rect.bottom - rect.top + 1) + 1, COLOUR_WHITE, FR_BORDERONLY); + Rect hr = {x, y, x + width - 1, y + UnScaleGUI(rect.Height()) - 1}; + DrawFrameRect(hr.Expand(WidgetDimensions::scaled.bevel), COLOUR_WHITE, FR_BORDERONLY); } } @@ -57,21 +57,23 @@ void DrawShipImage(const Vehicle *v, int left, int right, int y, VehicleID selec * Draw the details for the given vehicle at the given position * * @param v current vehicle - * @param left The left most coordinate to draw - * @param right The right most coordinate to draw - * @param y The y coordinate + * @param r the Rect to draw within */ -void DrawShipDetails(const Vehicle *v, int left, int right, int y) +void DrawShipDetails(const Vehicle *v, const Rect &r) { - SetDParam(0, v->engine_type); + int y = r.top; + + SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails)); SetDParam(1, v->build_year); SetDParam(2, v->value); - DrawString(left, right, y, STR_VEHICLE_INFO_BUILT_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_BUILT_VALUE); + y += FONT_HEIGHT_NORMAL; SetDParam(0, v->cargo_type); SetDParam(1, v->cargo_cap); SetDParam(4, GetCargoSubtypeText(v)); - DrawString(left, right, y + FONT_HEIGHT_NORMAL, STR_VEHICLE_INFO_CAPACITY); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_CAPACITY); + y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; StringID str = STR_VEHICLE_DETAILS_CARGO_EMPTY; if (v->cargo.StoredCount() > 0) { @@ -80,9 +82,10 @@ void DrawShipDetails(const Vehicle *v, int left, int right, int y) SetDParam(2, v->cargo.Source()); str = STR_VEHICLE_DETAILS_CARGO_FROM; } - DrawString(left, right, y + 2 * FONT_HEIGHT_NORMAL + 1, str); + DrawString(r.left, r.right, y, str); + y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; /* Draw Transfer credits text */ SetDParam(0, v->cargo.FeederShare()); - DrawString(left, right, y + 3 * FONT_HEIGHT_NORMAL + 3, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); + DrawString(r.left, r.right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); } diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp index a3685c5c5015c..911e0c9363a11 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -194,30 +194,30 @@ struct SignListWindow : Window, SignList { { switch (widget) { case WID_SIL_LIST: { - uint y = r.top + WD_FRAMERECT_TOP; // Offset from top of widget. + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); uint text_offset_y = (this->resize.step_height - FONT_HEIGHT_NORMAL + 1) / 2; /* No signs? */ if (this->vscroll->GetCount() == 0) { - DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y + text_offset_y, STR_STATION_LIST_NONE); + DrawString(tr.left, tr.right, tr.top + text_offset_y, STR_STATION_LIST_NONE); return; } Dimension d = GetSpriteSize(SPR_COMPANY_ICON); bool rtl = _current_text_dir == TD_RTL; int sprite_offset_y = (this->resize.step_height - d.height + 1) / 2; - uint icon_left = 4 + (rtl ? r.right - this->text_offset : r.left); - uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : this->text_offset); - uint text_right = r.right - (rtl ? this->text_offset : WD_FRAMERECT_RIGHT); + uint icon_left = rtl ? tr.right - this->text_offset : tr.left; + tr = tr.Indent(this->text_offset, rtl); /* At least one sign available. */ - for (uint16 i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) { + for (uint16 i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) + { const Sign *si = this->signs[i]; - if (si->owner != OWNER_NONE) DrawCompanyIcon(si->owner, icon_left, y + sprite_offset_y); + if (si->owner != OWNER_NONE) DrawCompanyIcon(si->owner, icon_left, tr.top + sprite_offset_y); SetDParam(0, si->index); - DrawString(text_left, text_right, y + text_offset_y, STR_SIGN_NAME, TC_YELLOW); - y += this->resize.step_height; + DrawString(tr.left, tr.right, tr.top + text_offset_y, STR_SIGN_NAME, TC_YELLOW); + tr.top += this->resize.step_height; } break; } @@ -233,7 +233,7 @@ struct SignListWindow : Window, SignList { { switch (widget) { case WID_SIL_LIST: { - uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SIL_LIST, WD_FRAMERECT_TOP); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SIL_LIST, WidgetDimensions::scaled.framerect.top); if (id_v == INT_MAX) return; const Sign *si = this->signs[id_v]; @@ -258,7 +258,7 @@ struct SignListWindow : Window, SignList { void OnResize() override { - this->vscroll->SetCapacityFromWidget(this, WID_SIL_LIST, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + this->vscroll->SetCapacityFromWidget(this, WID_SIL_LIST, WidgetDimensions::scaled.framerect.Vertical()); } void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override @@ -266,9 +266,9 @@ struct SignListWindow : Window, SignList { switch (widget) { case WID_SIL_LIST: { Dimension spr_dim = GetSpriteSize(SPR_COMPANY_ICON); - this->text_offset = WD_FRAMETEXT_LEFT + spr_dim.width + 2; // 2 pixels space between icon and the sign text. + this->text_offset = WidgetDimensions::scaled.frametext.left + spr_dim.width + 2; // 2 pixels space between icon and the sign text. resize->height = std::max(FONT_HEIGHT_NORMAL, spr_dim.height + 2); - Dimension d = {(uint)(this->text_offset + WD_FRAMETEXT_RIGHT), WD_FRAMERECT_TOP + 5 * resize->height + WD_FRAMERECT_BOTTOM}; + Dimension d = {(uint)(this->text_offset + WidgetDimensions::scaled.frametext.right), padding.height + 5 * resize->height}; *size = maxdim(*size, d); break; } @@ -368,7 +368,7 @@ static const NWidgetPart _nested_sign_list_widgets[] = { EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(NWID_VERTICAL), - NWidget(WWT_PANEL, COLOUR_BROWN, WID_SIL_LIST), SetMinimalSize(WD_FRAMETEXT_LEFT + 16 + 255 + WD_FRAMETEXT_RIGHT, 0), + NWidget(WWT_PANEL, COLOUR_BROWN, WID_SIL_LIST), SetMinimalSize(WidgetDimensions::unscaled.frametext.Horizontal() + 16 + 255, 0), SetResize(1, 1), SetFill(1, 0), SetScrollbar(WID_SIL_SCROLLBAR), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_BROWN), SetFill(1, 1), diff --git a/src/slope_type.h b/src/slope_type.h index ea2ed1aca5860..86faa7bb68c5d 100644 --- a/src/slope_type.h +++ b/src/slope_type.h @@ -81,7 +81,7 @@ DECLARE_ENUM_AS_BIT_SET(Slope) * Helper for creating a bitset of slopes. * @param x The slope to convert into a bitset. */ -#define M(x) (1 << (x)) +#define M(x) (1U << (x)) /** Constant bitset with safe slopes for building a level crossing. */ static const uint32 VALID_LEVEL_CROSSING_SLOPES = M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT); #undef M diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 4c28f2baa6858..7514fdbe992fd 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -8,6 +8,7 @@ /** @file smallmap_gui.cpp GUI that shows a small map of the world with metadata like owner or height. */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "clear_map.h" #include "industry.h" #include "station_map.h" @@ -556,15 +557,18 @@ static inline uint32 GetSmallMapVegetationPixels(TileIndex tile, TileType t) /** * Return the colour a tile would be displayed with in the small map in mode "Owner". * - * @param tile The tile of which we would like to get the colour. - * @param t Effective tile type of the tile (see #SmallMapWindow::GetTileColours). + * @note If include_heightmap is IH_NEVER, the return value can safely be used as a palette colour (by masking it to a uint8) + * @param tile The tile of which we would like to get the colour. + * @param t Effective tile type of the tile (see #SmallMapWindow::GetTileColours). + * @param include_heightmap Whether to return the heightmap/contour colour of this tile (instead of the default land tile colour) * @return The colour of tile in the small map in mode "Owner" */ -static inline uint32 GetSmallMapOwnerPixels(TileIndex tile, TileType t) +uint32 GetSmallMapOwnerPixels(TileIndex tile, TileType t, IncludeHeightmap include_heightmap) { Owner o; switch (t) { + case MP_VOID: return MKCOLOUR_XXXX(PC_BLACK); case MP_INDUSTRY: return MKCOLOUR_XXXX(PC_DARK_GREY); case MP_HOUSE: return MKCOLOUR_XXXX(PC_DARK_RED); default: o = GetTileOwner(tile); break; @@ -577,7 +581,8 @@ static inline uint32 GetSmallMapOwnerPixels(TileIndex tile, TileType t) if ((o < MAX_COMPANIES && !_legend_land_owners[_company_to_list_pos[o]].show_on_map) || o == OWNER_NONE || o == OWNER_WATER) { if (t == MP_WATER) return MKCOLOUR_XXXX(PC_WATER); const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour]; - return _smallmap_show_heightmap ? cs->height_colours[TileHeight(tile)] : cs->default_colour; + return ((include_heightmap == IncludeHeightmap::IfEnabled && _smallmap_show_heightmap) || include_heightmap == IncludeHeightmap::Always) + ? cs->height_colours[TileHeight(tile)] : cs->default_colour; } else if (o == OWNER_TOWN) { return MKCOLOUR_XXXX(PC_DARK_RED); } @@ -814,7 +819,7 @@ inline uint32 SmallMapWindow::GetTileColours(const TileArea &ta) const return GetSmallMapVegetationPixels(tile, et); case SMT_OWNER: - return GetSmallMapOwnerPixels(tile, et); + return GetSmallMapOwnerPixels(tile, et, IncludeHeightmap::IfEnabled); default: NOT_REACHED(); } @@ -840,7 +845,7 @@ void SmallMapWindow::DrawSmallMapColumn(void *dst, uint xc, uint yc, int pitch, do { /* Check if the tile (xc,yc) is within the map range */ - if (xc >= MapMaxX() || yc >= MapMaxY()) continue; + if (xc >= Map::MaxX() || yc >= Map::MaxY()) continue; /* Check if the dst pointer points to a pixel inside the screen buffer */ if (dst < _screen.dst_ptr) continue; @@ -937,7 +942,7 @@ void SmallMapWindow::DrawTowns(const DrawPixelInfo *dpi) const void SmallMapWindow::DrawMapIndicators() const { /* Find main viewport. */ - const Viewport *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; + const Viewport *vp = GetMainWindow()->viewport; Point upper_left_smallmap_coord = InverseRemapCoords2(vp->virtual_left, vp->virtual_top); Point lower_right_smallmap_coord = InverseRemapCoords2(vp->virtual_left + vp->virtual_width - 1, vp->virtual_top + vp->virtual_height - 1); @@ -969,10 +974,7 @@ void SmallMapWindow::DrawMapIndicators() const void SmallMapWindow::DrawSmallMap(DrawPixelInfo *dpi) const { Blitter *blitter = BlitterFactory::GetCurrentBlitter(); - DrawPixelInfo *old_dpi; - - old_dpi = _cur_dpi; - _cur_dpi = dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, dpi); /* Clear it */ GfxFillRect(dpi->left, dpi->top, dpi->left + dpi->width - 1, dpi->top + dpi->height - 1, PC_BLACK); @@ -1023,8 +1025,6 @@ void SmallMapWindow::DrawSmallMap(DrawPixelInfo *dpi) const /* Draw map indicators */ this->DrawMapIndicators(); - - _cur_dpi = old_dpi; } /** @@ -1184,10 +1184,10 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() } /* Width of the legend blob. */ - this->legend_width = (FONT_HEIGHT_SMALL - ScaleFontTrad(1)) * 8 / 5; + this->legend_width = (FONT_HEIGHT_SMALL - ScaleGUITrad(1)) * 8 / 5; /* The width of a column is the minimum width of all texts + the size of the blob + some spacing */ - this->column_width = min_width + this->legend_width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + this->column_width = min_width + this->legend_width + WidgetDimensions::scaled.framerect.Horizontal(); } /* virtual */ void SmallMapWindow::OnPaint() @@ -1210,27 +1210,24 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() { switch (widget) { case WID_SM_MAP: { + Rect ir = r.Shrink(WidgetDimensions::scaled.bevel); DrawPixelInfo new_dpi; - if (!FillDrawPixelInfo(&new_dpi, r.left + 1, r.top + 1, r.right - r.left - 1, r.bottom - r.top - 1)) return; + if (!FillDrawPixelInfo(&new_dpi, ir.left, ir.top, ir.Width(), ir.Height())) return; this->DrawSmallMap(&new_dpi); break; } case WID_SM_LEGEND: { - uint columns = this->GetNumberColumnsLegend(r.right - r.left + 1); + uint columns = this->GetNumberColumnsLegend(r.Width()); uint number_of_rows = this->GetNumberRowsLegend(columns); bool rtl = _current_text_dir == TD_RTL; - uint y_org = r.top + WD_FRAMERECT_TOP; - uint x = rtl ? r.right - this->column_width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT; - uint y = y_org; uint i = 0; // Row counter for industry legend. uint row_height = FONT_HEIGHT_SMALL; - int padding = ScaleFontTrad(1); + int padding = WidgetDimensions::scaled.hsep_normal; - uint text_left = rtl ? 0 : this->legend_width + WD_FRAMERECT_LEFT; - uint text_right = this->column_width - padding - (rtl ? this->legend_width + WD_FRAMERECT_RIGHT : 0); - uint blob_left = rtl ? this->column_width - padding - this->legend_width : 0; - uint blob_right = rtl ? this->column_width - padding : this->legend_width; + Rect origin = r.WithWidth(this->column_width, rtl).Shrink(WidgetDimensions::scaled.framerect).WithHeight(row_height); + Rect text = origin.Indent(this->legend_width + WidgetDimensions::scaled.hsep_normal, rtl); + Rect icon = origin.WithWidth(this->legend_width, rtl).Shrink(0, padding, 0, 0); StringID string = STR_NULL; switch (this->map_type) { @@ -1251,8 +1248,10 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() if (tbl->col_break || ((this->map_type == SMT_INDUSTRY || this->map_type == SMT_OWNER || this->map_type == SMT_LINKSTATS) && i++ >= number_of_rows)) { /* Column break needed, continue at top, COLUMN_WIDTH pixels * (one "row") to the right. */ - x += rtl ? -(int)this->column_width : this->column_width; - y = y_org; + int x = rtl ? -(int)this->column_width : this->column_width; + int y = origin.top - text.top; + text = text.Translate(x, y); + icon = icon.Translate(x, y); i = 1; } @@ -1279,10 +1278,10 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() if (!tbl->show_on_map) { /* Simply draw the string, not the black border of the legend colour. * This will enforce the idea of the disabled item */ - DrawString(x + text_left, x + text_right, y, string, TC_GREY); + DrawString(text, string, TC_GREY); } else { - DrawString(x + text_left, x + text_right, y, string, TC_BLACK); - GfxFillRect(x + blob_left, y + padding, x + blob_right, y + row_height - 1, PC_BLACK); // Outer border of the legend colour + DrawString(text, string, TC_BLACK); + GfxFillRect(icon, PC_BLACK); // Outer border of the legend colour } break; } @@ -1291,13 +1290,14 @@ void SmallMapWindow::RebuildColourIndexIfNecessary() default: if (this->map_type == SMT_CONTOUR) SetDParam(0, tbl->height * TILE_HEIGHT_STEP); /* Anything that is not an industry or a company is using normal process */ - GfxFillRect(x + blob_left, y + padding, x + blob_right, y + row_height - 1, PC_BLACK); - DrawString(x + text_left, x + text_right, y, tbl->legend); + GfxFillRect(icon, PC_BLACK); + DrawString(text, tbl->legend); break; } - GfxFillRect(x + blob_left + 1, y + padding + 1, x + blob_right - 1, y + row_height - 2, legend_colour); // Legend colour + GfxFillRect(icon.Shrink(WidgetDimensions::scaled.bevel), legend_colour); // Legend colour - y += row_height; + text = text.Translate(0, row_height); + icon = icon.Translate(0, row_height); } } } @@ -1392,7 +1392,7 @@ void SmallMapWindow::SetOverlayCargoMask() int SmallMapWindow::GetPositionOnLegend(Point pt) { const NWidgetBase *wi = this->GetWidget(WID_SM_LEGEND); - uint line = (pt.y - wi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_SMALL; + uint line = (pt.y - wi->pos_y - WidgetDimensions::scaled.framerect.top) / FONT_HEIGHT_SMALL; uint columns = this->GetNumberColumnsLegend(wi->current_x); uint number_of_rows = this->GetNumberRowsLegend(columns); if (line >= number_of_rows) return -1; @@ -1400,7 +1400,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) bool rtl = _current_text_dir == TD_RTL; int x = pt.x - wi->pos_x; if (rtl) x = wi->current_x - x; - uint column = (x - WD_FRAMERECT_LEFT) / this->column_width; + uint column = (x - WidgetDimensions::scaled.framerect.left) / this->column_width; return (column * number_of_rows) + line; } @@ -1429,7 +1429,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) if (click_count > 0) this->mouse_capture_widget = widget; const NWidgetBase *wid = this->GetWidget(WID_SM_MAP); - Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + Window *w = GetMainWindow(); int sub; pt = this->PixelToTile(pt.x - wid->pos_x, pt.y - wid->pos_y, &sub); ScrollWindowTo(this->scroll_x + pt.x * TILE_SIZE, this->scroll_y + pt.y * TILE_SIZE, -1, w); @@ -1625,16 +1625,16 @@ void SmallMapWindow::SetNewScroll(int sx, int sy, int sub) sx = -hv.x; sub = 0; } - if (sx > (int)(MapMaxX() * TILE_SIZE) - hv.x) { - sx = MapMaxX() * TILE_SIZE - hv.x; + if (sx > (int)(Map::MaxX() * TILE_SIZE) - hv.x) { + sx = Map::MaxX() * TILE_SIZE - hv.x; sub = 0; } if (sy < -hv.y) { sy = -hv.y; sub = 0; } - if (sy > (int)(MapMaxY() * TILE_SIZE) - hv.y) { - sy = MapMaxY() * TILE_SIZE - hv.y; + if (sy > (int)(Map::MaxY() * TILE_SIZE) - hv.y) { + sy = Map::MaxY() * TILE_SIZE - hv.y; sub = 0; } @@ -1661,7 +1661,7 @@ void SmallMapWindow::SetNewScroll(int sx, int sy, int sub) */ void SmallMapWindow::SmallMapCenterOnCurrentPos() { - const Viewport *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport; + const Viewport *vp = GetMainWindow()->viewport; Point viewport_center = InverseRemapCoords2(vp->virtual_left + vp->virtual_width / 2, vp->virtual_top + vp->virtual_height / 2); int sub; @@ -1679,8 +1679,8 @@ void SmallMapWindow::SmallMapCenterOnCurrentPos() */ Point SmallMapWindow::GetStationMiddle(const Station *st) const { - int x = (st->rect.right + st->rect.left + 1) / 2; - int y = (st->rect.bottom + st->rect.top + 1) / 2; + int x = CenterBounds(st->rect.left, st->rect.right, 0); + int y = CenterBounds(st->rect.top, st->rect.bottom, 0); Point ret = this->RemapTile(x, y); /* Same magic 3 as in DrawVehicles; that's where I got it from. @@ -1878,7 +1878,7 @@ void ShowSmallMap() */ bool ScrollMainWindowTo(int x, int y, int z, bool instant) { - bool res = ScrollWindowTo(x, y, z, FindWindowById(WC_MAIN_WINDOW, 0), instant); + bool res = ScrollWindowTo(x, y, z, GetMainWindow(), instant); /* If a user scrolls to a tile (via what way what so ever) and already is on * that tile (e.g.: pressed twice), move the smallmap to that location, diff --git a/src/smallmap_gui.h b/src/smallmap_gui.h index a5552333cde9e..cb2992bbaea33 100644 --- a/src/smallmap_gui.h +++ b/src/smallmap_gui.h @@ -27,6 +27,15 @@ void ShowSmallMap(); void BuildLandLegend(); void BuildOwnerLegend(); +/** Enum for how to include the heightmap pixels/colours in small map related functions */ +enum class IncludeHeightmap { + Never, ///< Never include the heightmap + IfEnabled, ///< Only include the heightmap if its enabled in the gui by the player + Always ///< Always include the heightmap +}; + +uint32 GetSmallMapOwnerPixels(TileIndex tile, TileType t, IncludeHeightmap include_heightmap); + /** Structure for holding relevant data for legends in small map */ struct LegendAndColour { uint8 colour; ///< Colour of the item on the map. @@ -114,7 +123,7 @@ class SmallMapWindow : public Window { */ inline uint GetMinLegendWidth() const { - return WD_FRAMERECT_LEFT + this->min_number_of_columns * this->column_width; + return WidgetDimensions::scaled.framerect.left + this->min_number_of_columns * this->column_width; } /** @@ -133,7 +142,7 @@ class SmallMapWindow : public Window { */ inline uint GetLegendHeight(uint num_columns) const { - return WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + + return WidgetDimensions::scaled.framerect.Vertical() + this->GetNumberRowsLegend(num_columns) * FONT_HEIGHT_SMALL; } diff --git a/src/sound.cpp b/src/sound.cpp index 1d0f7e8417913..2c77e0fed8beb 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -235,6 +235,7 @@ void SndCopyToPool() /** * Decide 'where' (between left and right speaker) to play the sound effect. + * Note: Callers must determine if sound effects are enabled. This plays a sound regardless of the setting. * @param sound Sound effect to play * @param left Left edge of virtual coordinates where the sound is produced * @param right Right edge of virtual coordinates where the sound is produced @@ -243,8 +244,6 @@ void SndCopyToPool() */ static void SndPlayScreenCoordFx(SoundID sound, int left, int right, int top, int bottom) { - if (_settings_client.music.effect_vol == 0) return; - /* Iterate from back, so that main viewport is checked first */ for (const Window *w : Window::IterateFromBack()) { const Viewport *vp = w->viewport; @@ -269,8 +268,8 @@ static void SndPlayScreenCoordFx(SoundID sound, int left, int right, int top, in void SndPlayTileFx(SoundID sound, TileIndex tile) { /* emits sound from center of the tile */ - int x = std::min(MapMaxX() - 1, TileX(tile)) * TILE_SIZE + TILE_SIZE / 2; - int y = std::min(MapMaxY() - 1, TileY(tile)) * TILE_SIZE - TILE_SIZE / 2; + int x = std::min(Map::MaxX() - 1, TileX(tile)) * TILE_SIZE + TILE_SIZE / 2; + int y = std::min(Map::MaxY() - 1, TileY(tile)) * TILE_SIZE - TILE_SIZE / 2; int z = (y < 0 ? 0 : GetSlopePixelZ(x, y)); Point pt = RemapCoords(x, y, z); y += 2 * TILE_SIZE; diff --git a/src/sound/allegro_s.h b/src/sound/allegro_s.h index 6d40c58760938..de609f647fe48 100644 --- a/src/sound/allegro_s.h +++ b/src/sound/allegro_s.h @@ -26,7 +26,7 @@ class SoundDriver_Allegro : public SoundDriver { /** Factory for the allegro sound driver. */ class FSoundDriver_Allegro : public DriverFactoryBase { public: - FSoundDriver_Allegro() : DriverFactoryBase(Driver::DT_SOUND, 4, "allegro", "Allegro Sound Driver") {} + FSoundDriver_Allegro() : DriverFactoryBase(Driver::DT_SOUND, 4, "allegro", "Allegro Sound Driver (param hz,samples)") {} /* virtual */ Driver *CreateInstance() const { return new SoundDriver_Allegro(); } }; diff --git a/src/sound/cocoa_s.h b/src/sound/cocoa_s.h index dca5421915d1f..f1e623ce5a91a 100644 --- a/src/sound/cocoa_s.h +++ b/src/sound/cocoa_s.h @@ -22,7 +22,7 @@ class SoundDriver_Cocoa : public SoundDriver { class FSoundDriver_Cocoa : public DriverFactoryBase { public: - FSoundDriver_Cocoa() : DriverFactoryBase(Driver::DT_SOUND, 10, "cocoa", "Cocoa Sound Driver") {} + FSoundDriver_Cocoa() : DriverFactoryBase(Driver::DT_SOUND, 10, "cocoa", "Cocoa Sound Driver (param hz)") {} Driver *CreateInstance() const override { return new SoundDriver_Cocoa(); } }; diff --git a/src/sound/sdl_s.h b/src/sound/sdl_s.h index 2b3be4d14c868..fbe7d77d84aef 100644 --- a/src/sound/sdl_s.h +++ b/src/sound/sdl_s.h @@ -24,7 +24,7 @@ class SoundDriver_SDL : public SoundDriver { /** Factory for the SDL sound driver. */ class FSoundDriver_SDL : public DriverFactoryBase { public: - FSoundDriver_SDL() : DriverFactoryBase(Driver::DT_SOUND, 5, "sdl", "SDL Sound Driver") {} + FSoundDriver_SDL() : DriverFactoryBase(Driver::DT_SOUND, 5, "sdl", "SDL Sound Driver (param hz,samples)") {} Driver *CreateInstance() const override { return new SoundDriver_SDL(); } }; diff --git a/src/sound/win32_s.h b/src/sound/win32_s.h index 6f8f9791db901..5722b2089dbe3 100644 --- a/src/sound/win32_s.h +++ b/src/sound/win32_s.h @@ -24,7 +24,7 @@ class SoundDriver_Win32 : public SoundDriver { /** Factory for the sound driver for Windows. */ class FSoundDriver_Win32 : public DriverFactoryBase { public: - FSoundDriver_Win32() : DriverFactoryBase(Driver::DT_SOUND, 9, "win32", "Win32 WaveOut Sound Driver") {} + FSoundDriver_Win32() : DriverFactoryBase(Driver::DT_SOUND, 9, "win32", "Win32 WaveOut Sound Driver (param bufsize,hz)") {} Driver *CreateInstance() const override { return new SoundDriver_Win32(); } }; diff --git a/src/sound/xaudio2_s.h b/src/sound/xaudio2_s.h index 9fcd26fd0a4a0..621655d8d5fdf 100644 --- a/src/sound/xaudio2_s.h +++ b/src/sound/xaudio2_s.h @@ -24,7 +24,7 @@ class SoundDriver_XAudio2 : public SoundDriver { /** Factory for the XAudio2 sound driver. */ class FSoundDriver_XAudio2 : public DriverFactoryBase { public: - FSoundDriver_XAudio2() : DriverFactoryBase(Driver::DT_SOUND, 10, "xaudio2", "XAudio2 Sound Driver") {} + FSoundDriver_XAudio2() : DriverFactoryBase(Driver::DT_SOUND, 10, "xaudio2", "XAudio2 Sound Driver (param bufsize,hz)") {} Driver *CreateInstance() const override { return new SoundDriver_XAudio2(); } }; diff --git a/src/sprite.cpp b/src/sprite.cpp index a6ff4c92248f0..7f2bfb1bb9ed7 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -125,7 +125,7 @@ void DrawCommonTileSeqInGUI(int x, int y, const DrawTileSprites *dts, int32 orig } else { int offs_x = child_offset_is_unsigned ? (uint8)dtss->delta_x : dtss->delta_x; int offs_y = child_offset_is_unsigned ? (uint8)dtss->delta_y : dtss->delta_y; - DrawSprite(image, pal, x + child_offset.x + ScaleGUITrad(offs_x), y + child_offset.y + ScaleGUITrad(offs_y)); + DrawSprite(image, pal, x + child_offset.x + ScaleSpriteTrad(offs_x), y + child_offset.y + ScaleSpriteTrad(offs_y)); } } } diff --git a/src/spritecache.cpp b/src/spritecache.cpp index 6d5ce0189c028..aee8661c4dec8 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -36,6 +36,7 @@ struct SpriteCache { int16 lru; SpriteType type; ///< In some cases a single sprite is misused by two NewGRFs. Once as real sprite and once as recolour sprite. If the recolour sprite gets into the cache it might be drawn as real sprite which causes enormous trouble. bool warned; ///< True iff the user has been warned about incorrect use of this sprite + byte control_flags; ///< Control flags, see SpriteCacheCtrlFlags }; @@ -50,7 +51,7 @@ static inline SpriteCache *GetSpriteCache(uint index) static inline bool IsMapgenSpriteID(SpriteID sprite) { - return IsInsideMM(sprite, 4845, 4882); + return IsInsideMM(sprite, SPR_MAPGEN_BEGIN, SPR_MAPGEN_END); } static SpriteCache *AllocateSpriteCache(uint index) @@ -235,7 +236,7 @@ static bool ResizeSpriteIn(SpriteLoader::Sprite *sprite, ZoomLevel src, ZoomLeve sprite[tgt].y_offs = sprite[src].y_offs * scaled_1; sprite[tgt].colours = sprite[src].colours; - sprite[tgt].AllocateData(tgt, sprite[tgt].width * sprite[tgt].height); + sprite[tgt].AllocateData(tgt, static_cast(sprite[tgt].width) * sprite[tgt].height); SpriteLoader::CommonPixel *dst = sprite[tgt].data; for (int y = 0; y < sprite[tgt].height; y++) { @@ -258,7 +259,7 @@ static void ResizeSpriteOut(SpriteLoader::Sprite *sprite, ZoomLevel zoom) sprite[zoom].y_offs = UnScaleByZoom(sprite[ZOOM_LVL_NORMAL].y_offs, zoom); sprite[zoom].colours = sprite[ZOOM_LVL_NORMAL].colours; - sprite[zoom].AllocateData(zoom, sprite[zoom].height * sprite[zoom].width); + sprite[zoom].AllocateData(zoom, static_cast(sprite[zoom].height) * sprite[zoom].width); SpriteLoader::CommonPixel *dst = sprite[zoom].data; const SpriteLoader::CommonPixel *src = sprite[zoom - 1].data; @@ -289,9 +290,10 @@ static bool PadSingleSprite(SpriteLoader::Sprite *sprite, ZoomLevel zoom, uint p if (width > UINT16_MAX || height > UINT16_MAX) return false; /* Copy source data and reallocate sprite memory. */ - SpriteLoader::CommonPixel *src_data = MallocT(sprite->width * sprite->height); - MemCpyT(src_data, sprite->data, sprite->width * sprite->height); - sprite->AllocateData(zoom, width * height); + size_t sprite_size = static_cast(sprite->width) * sprite->height; + SpriteLoader::CommonPixel *src_data = MallocT(sprite_size); + MemCpyT(src_data, sprite->data, sprite_size); + sprite->AllocateData(zoom, static_cast(width) * height); /* Copy with padding to destination. */ SpriteLoader::CommonPixel *src = src_data; @@ -471,10 +473,10 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty SpriteLoaderGrf sprite_loader(file.GetContainerVersion()); if (sprite_type != ST_MAPGEN && encoder->Is32BppSupported()) { /* Try for 32bpp sprites first. */ - sprite_avail = sprite_loader.LoadSprite(sprite, file, file_pos, sprite_type, true); + sprite_avail = sprite_loader.LoadSprite(sprite, file, file_pos, sprite_type, true, sc->control_flags); } if (sprite_avail == 0) { - sprite_avail = sprite_loader.LoadSprite(sprite, file, file_pos, sprite_type, false); + sprite_avail = sprite_loader.LoadSprite(sprite, file, file_pos, sprite_type, false, sc->control_flags); } if (sprite_avail == 0) { @@ -516,22 +518,26 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty return (void*)GetRawSprite(SPR_IMG_QUERY, ST_NORMAL, allocator, encoder); } - if (sprite->type == ST_FONT && ZOOM_LVL_FONT != ZOOM_LVL_NORMAL) { - /* Make ZOOM_LVL_NORMAL be ZOOM_LVL_FONT */ - sprite[ZOOM_LVL_NORMAL].width = sprite[ZOOM_LVL_FONT].width; - sprite[ZOOM_LVL_NORMAL].height = sprite[ZOOM_LVL_FONT].height; - sprite[ZOOM_LVL_NORMAL].x_offs = sprite[ZOOM_LVL_FONT].x_offs; - sprite[ZOOM_LVL_NORMAL].y_offs = sprite[ZOOM_LVL_FONT].y_offs; - sprite[ZOOM_LVL_NORMAL].data = sprite[ZOOM_LVL_FONT].data; - sprite[ZOOM_LVL_NORMAL].colours = sprite[ZOOM_LVL_FONT].colours; + if (sprite->type == ST_FONT && ZOOM_LVL_GUI != ZOOM_LVL_NORMAL) { + /* Make ZOOM_LVL_NORMAL be ZOOM_LVL_GUI */ + sprite[ZOOM_LVL_NORMAL].width = sprite[ZOOM_LVL_GUI].width; + sprite[ZOOM_LVL_NORMAL].height = sprite[ZOOM_LVL_GUI].height; + sprite[ZOOM_LVL_NORMAL].x_offs = sprite[ZOOM_LVL_GUI].x_offs; + sprite[ZOOM_LVL_NORMAL].y_offs = sprite[ZOOM_LVL_GUI].y_offs; + sprite[ZOOM_LVL_NORMAL].data = sprite[ZOOM_LVL_GUI].data; + sprite[ZOOM_LVL_NORMAL].colours = sprite[ZOOM_LVL_GUI].colours; } return encoder->Encode(sprite, allocator); } +struct GrfSpriteOffset { + size_t file_pos; + byte control_flags; +}; /** Map from sprite numbers to position in the GRF file. */ -static std::map _grf_sprite_offsets; +static std::map _grf_sprite_offsets; /** * Get the file offset for a specific sprite in the sprite section of a GRF. @@ -540,7 +546,7 @@ static std::map _grf_sprite_offsets; */ size_t GetGRFSpriteOffset(uint32 id) { - return _grf_sprite_offsets.find(id) != _grf_sprite_offsets.end() ? _grf_sprite_offsets[id] : SIZE_MAX; + return _grf_sprite_offsets.find(id) != _grf_sprite_offsets.end() ? _grf_sprite_offsets[id].file_pos : SIZE_MAX; } /** @@ -557,14 +563,37 @@ void ReadGRFSpriteOffsets(SpriteFile &file) size_t old_pos = file.GetPos(); file.SeekTo(data_offset, SEEK_CUR); + GrfSpriteOffset offset = { 0, 0 }; + /* Loop over all sprite section entries and store the file * offset for each newly encountered ID. */ uint32 id, prev_id = 0; while ((id = file.ReadDword()) != 0) { - if (id != prev_id) _grf_sprite_offsets[id] = file.GetPos() - 4; + if (id != prev_id) { + _grf_sprite_offsets[prev_id] = offset; + offset.file_pos = file.GetPos() - 4; + offset.control_flags = 0; + } prev_id = id; - file.SkipBytes(file.ReadDword()); + uint length = file.ReadDword(); + if (length > 0) { + byte colour = file.ReadByte() & SCC_MASK; + length--; + if (length > 0) { + byte zoom = file.ReadByte(); + length--; + if (colour != 0 && zoom == 0) { // ZOOM_LVL_OUT_4X (normal zoom) + SetBit(offset.control_flags, (colour != SCC_PAL) ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL); + SetBit(offset.control_flags, (colour != SCC_PAL) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL); + } + if (colour != 0 && zoom == 2) { // ZOOM_LVL_OUT_2X (2x zoomed in) + SetBit(offset.control_flags, (colour != SCC_PAL) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL); + } + } + } + file.SkipBytes(length); } + if (prev_id != 0) _grf_sprite_offsets[prev_id] = offset; /* Continue processing the data section. */ file.SeekTo(old_pos, SEEK_SET); @@ -591,6 +620,7 @@ bool LoadNextSprite(int load_index, SpriteFile &file, uint file_sprite_id) SpriteType type; void *data = nullptr; + byte control_flags = 0; if (grf_type == 0xFF) { /* Some NewGRF files have "empty" pseudo-sprites which are 1 * byte long. Catch these so the sprites won't be displayed. */ @@ -607,7 +637,13 @@ bool LoadNextSprite(int load_index, SpriteFile &file, uint file_sprite_id) return false; } /* It is not an error if no sprite with the provided ID is found in the sprite section. */ - file_pos = GetGRFSpriteOffset(file.ReadDword()); + auto iter = _grf_sprite_offsets.find(file.ReadDword()); + if (iter != _grf_sprite_offsets.end()) { + file_pos = iter->second.file_pos; + control_flags = iter->second.control_flags; + } else { + file_pos = SIZE_MAX; + } type = ST_NORMAL; } else { file.SkipBytes(7); @@ -637,6 +673,7 @@ bool LoadNextSprite(int load_index, SpriteFile &file, uint file_sprite_id) sc->id = file_sprite_id; sc->type = type; sc->warned = false; + sc->control_flags = control_flags; return true; } @@ -951,12 +988,8 @@ static void GfxInitSpriteCache() _allocated_sprite_cache_size = target_size; do { - try { - /* Try to allocate 50% more to make sure we do not allocate almost all available. */ - _spritecache_ptr = reinterpret_cast(new byte[_allocated_sprite_cache_size + _allocated_sprite_cache_size / 2]); - } catch (std::bad_alloc &) { - _spritecache_ptr = nullptr; - } + /* Try to allocate 50% more to make sure we do not allocate almost all available. */ + _spritecache_ptr = reinterpret_cast(new(std::nothrow) byte[_allocated_sprite_cache_size + _allocated_sprite_cache_size / 2]); if (_spritecache_ptr != nullptr) { /* Allocation succeeded, but we wanted less. */ diff --git a/src/spritecache.h b/src/spritecache.h index 367d690951196..be64843b5a846 100644 --- a/src/spritecache.h +++ b/src/spritecache.h @@ -22,6 +22,13 @@ struct Sprite { byte data[]; ///< Sprite data. }; +enum SpriteCacheCtrlFlags { + SCCF_ALLOW_ZOOM_MIN_1X_PAL = 0, ///< Allow use of sprite min zoom setting at 1x in palette mode. + SCCF_ALLOW_ZOOM_MIN_1X_32BPP = 1, ///< Allow use of sprite min zoom setting at 1x in 32bpp mode. + SCCF_ALLOW_ZOOM_MIN_2X_PAL = 2, ///< Allow use of sprite min zoom setting at 2x in palette mode. + SCCF_ALLOW_ZOOM_MIN_2X_32BPP = 3, ///< Allow use of sprite min zoom setting at 2x in 32bpp mode. +}; + extern uint _sprite_cache_size; typedef void *AllocatorProc(size_t size); diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp index 1530db0c819cd..169f4409e62f0 100644 --- a/src/spriteloader/grf.cpp +++ b/src/spriteloader/grf.cpp @@ -17,6 +17,7 @@ #include "../core/math_func.hpp" #include "../core/alloc_type.hpp" #include "../core/bitmath_func.hpp" +#include "../spritecache.h" #include "grf.hpp" #include "../safeguards.h" @@ -58,6 +59,15 @@ static bool WarnCorruptSprite(const SpriteFile &file, size_t file_pos, int line) */ bool DecodeSingleSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, int64 num, byte type, ZoomLevel zoom_lvl, byte colour_fmt, byte container_format) { + /* + * Original sprite height was max 255 pixels, with 4x extra zoom => 1020 pixels. + * Original maximum width for sprites was 640 pixels, with 4x extra zoom => 2560 pixels. + * Now up to 5 bytes per pixel => 1020 * 2560 * 5 => ~ 12.5 MiB. + * + * So, any sprite data more than 64 MiB is way larger that we would even expect; prevent allocating more memory! + */ + if (num < 0 || num > 64 * 1024 * 1024) return WarnCorruptSprite(file, file_pos, __LINE__); + std::unique_ptr dest_orig(new byte[num]); byte *dest = dest_orig.get(); const int64 dest_size = num; @@ -91,7 +101,7 @@ bool DecodeSingleSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t f if (num != 0) return WarnCorruptSprite(file, file_pos, __LINE__); - sprite->AllocateData(zoom_lvl, sprite->width * sprite->height); + sprite->AllocateData(zoom_lvl, static_cast(sprite->width) * sprite->height); /* Convert colour depth to pixel size. */ int bpp = 0; @@ -167,13 +177,14 @@ bool DecodeSingleSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t f } while (!last_item); } } else { - if (dest_size < sprite->width * sprite->height * bpp) { + int64 sprite_size = static_cast(sprite->width) * sprite->height * bpp; + if (dest_size < sprite_size) { return WarnCorruptSprite(file, file_pos, __LINE__); } - if (dest_size > sprite->width * sprite->height * bpp) { + if (dest_size > sprite_size) { static byte warning_level = 0; - Debug(sprite, warning_level, "Ignoring {} unused extra bytes from the sprite from {} at position {}", dest_size - sprite->width * sprite->height * bpp, file.GetSimplifiedFilename(), file_pos); + Debug(sprite, warning_level, "Ignoring {} unused extra bytes from the sprite from {} at position {}", dest_size - sprite_size, file.GetSimplifiedFilename(), file_pos); warning_level = 6; } @@ -241,7 +252,7 @@ uint8 LoadSpriteV1(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_p return 0; } -uint8 LoadSpriteV2(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp) +uint8 LoadSpriteV2(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, byte control_flags) { static const ZoomLevel zoom_lvl_map[6] = {ZOOM_LVL_OUT_4X, ZOOM_LVL_NORMAL, ZOOM_LVL_OUT_2X, ZOOM_LVL_OUT_8X, ZOOM_LVL_OUT_16X, ZOOM_LVL_OUT_32X}; @@ -269,7 +280,19 @@ uint8 LoadSpriteV2(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_p bool is_wanted_zoom_lvl; if (sprite_type != ST_MAPGEN) { - is_wanted_zoom_lvl = (zoom < lengthof(zoom_lvl_map) && zoom_lvl_map[zoom] >= _settings_client.gui.sprite_zoom_min); + if (zoom < lengthof(zoom_lvl_map)) { + is_wanted_zoom_lvl = true; + if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_OUT_2X && + HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL) && zoom_lvl_map[zoom] < ZOOM_LVL_OUT_2X) { + is_wanted_zoom_lvl = false; + } + if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_OUT_4X && + HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL) && zoom_lvl_map[zoom] < ZOOM_LVL_OUT_4X) { + is_wanted_zoom_lvl = false; + } + } else { + is_wanted_zoom_lvl = false; + } } else { is_wanted_zoom_lvl = (zoom == 0); } @@ -326,10 +349,10 @@ uint8 LoadSpriteV2(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_p return loaded_sprites; } -uint8 SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp) +uint8 SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, byte control_flags) { if (this->container_ver >= 2) { - return LoadSpriteV2(sprite, file, file_pos, sprite_type, load_32bpp); + return LoadSpriteV2(sprite, file, file_pos, sprite_type, load_32bpp, control_flags); } else { return LoadSpriteV1(sprite, file, file_pos, sprite_type, load_32bpp); } diff --git a/src/spriteloader/grf.hpp b/src/spriteloader/grf.hpp index c100590afb7ef..27253bc398815 100644 --- a/src/spriteloader/grf.hpp +++ b/src/spriteloader/grf.hpp @@ -17,7 +17,7 @@ class SpriteLoaderGrf : public SpriteLoader { byte container_ver; public: SpriteLoaderGrf(byte container_ver) : container_ver(container_ver) {} - uint8 LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp); + uint8 LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, byte control_flags); }; #endif /* SPRITELOADER_GRF_HPP */ diff --git a/src/spriteloader/spriteloader.hpp b/src/spriteloader/spriteloader.hpp index beadbb65911f9..fdd8be8612a62 100644 --- a/src/spriteloader/spriteloader.hpp +++ b/src/spriteloader/spriteloader.hpp @@ -72,9 +72,10 @@ class SpriteLoader { * @param file_pos The position within the file the image begins. * @param sprite_type The type of sprite we're trying to load. * @param load_32bpp True if 32bpp sprites should be loaded, false for a 8bpp sprite. + * @param control_flags Control flags, see SpriteCacheCtrlFlags. * @return Bit mask of the zoom levels successfully loaded or 0 if no sprite could be loaded. */ - virtual uint8 LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp) = 0; + virtual uint8 LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, byte control_flags) = 0; virtual ~SpriteLoader() { } }; diff --git a/src/station.cpp b/src/station.cpp index fc258fcc92d71..700ca7241d78d 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -51,8 +51,6 @@ void RebuildStationKdtree() BaseStation::~BaseStation() { - free(this->speclist); - if (CleaningPool()) return; CloseWindowById(WC_TRAINS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_TRAIN, this->owner, this->index).Pack()); @@ -106,9 +104,9 @@ Station::~Station() if (lg == nullptr) continue; for (NodeID node = 0; node < lg->Size(); ++node) { - Station *st = Station::Get((*lg)[node].Station()); + Station *st = Station::Get((*lg)[node].station); st->goods[c].flows.erase(this->index); - if ((*lg)[node][this->goods[c].node].LastUpdate() != INVALID_DATE) { + if ((*lg)[node].HasEdgeTo(this->goods[c].node) && (*lg)[node][this->goods[c].node].LastUpdate() != INVALID_DATE) { st->goods[c].flows.DeleteFlows(this->index); RerouteCargo(st, c, this->index, st->index); } @@ -172,6 +170,36 @@ void BaseStation::PostDestructor(size_t index) InvalidateWindowData(WC_SELECT_STATION, 0, 0); } +void BaseStation::SetRoadStopTileData(TileIndex tile, byte data, bool animation) +{ + for (RoadStopTileData &tile_data : this->custom_roadstop_tile_data) { + if (tile_data.tile == tile) { + if (animation) { + tile_data.animation_frame = data; + } else { + tile_data.random_bits = data; + } + return; + } + } + RoadStopTileData tile_data; + tile_data.tile = tile; + tile_data.animation_frame = animation ? data : 0; + tile_data.random_bits = animation ? 0 : data; + this->custom_roadstop_tile_data.push_back(tile_data); +} + +void BaseStation::RemoveRoadStopTileData(TileIndex tile) +{ + for (RoadStopTileData &tile_data : this->custom_roadstop_tile_data) { + if (tile_data.tile == tile) { + tile_data = this->custom_roadstop_tile_data.back(); + this->custom_roadstop_tile_data.pop_back(); + return; + } + } +} + /** * Get the primary road stop (the first road stop) that the given vehicle can load/unload. * @param v the vehicle to get the first road stop for @@ -227,7 +255,7 @@ void Station::MarkTilesDirty(bool cargo_change) const /* Don't waste time updating if there are no custom station graphics * that might change. Even if there are custom graphics, they might * not change. Unfortunately we have no way of telling. */ - if (this->num_specs == 0) return; + if (this->speclist.size() == 0) return; } for (h = 0; h < train_station.h; h++) { @@ -348,8 +376,8 @@ Rect Station::GetCatchmentRect() const Rect ret = { std::max(this->rect.left - catchment_radius, 0), std::max(this->rect.top - catchment_radius, 0), - std::min(this->rect.right + catchment_radius, MapMaxX()), - std::min(this->rect.bottom + catchment_radius, MapMaxY()) + std::min(this->rect.right + catchment_radius, Map::MaxX()), + std::min(this->rect.bottom + catchment_radius, Map::MaxY()) }; return ret; @@ -427,11 +455,12 @@ bool Station::CatchmentCoversTown(TownID t) const /** * Recompute tiles covered in our catchment area. * This will additionally recompute nearby towns and industries. + * @param no_clear_nearby_lists If Station::RemoveFromAllNearbyLists does not need to be called. */ -void Station::RecomputeCatchment() +void Station::RecomputeCatchment(bool no_clear_nearby_lists) { this->industries_near.clear(); - this->RemoveFromAllNearbyLists(); + if (!no_clear_nearby_lists) this->RemoveFromAllNearbyLists(); if (this->rect.IsEmpty()) { this->catchment_tiles.Reset(); @@ -498,7 +527,9 @@ void Station::RecomputeCatchment() */ /* static */ void Station::RecomputeCatchmentForAll() { - for (Station *st : Station::Iterate()) { st->RecomputeCatchment(); } + for (Town *t : Town::Iterate()) { t->stations_near.clear(); } + for (Industry *i : Industry::Iterate()) { i->stations_near.clear(); } + for (Station *st : Station::Iterate()) { st->RecomputeCatchment(true); } } /************************************************************************/ @@ -551,8 +582,8 @@ CommandCost StationRect::BeforeAddTile(TileIndex tile, StationRectMode mode) Rect new_rect = {std::min(x, this->left), std::min(y, this->top), std::max(x, this->right), std::max(y, this->bottom)}; /* check new rect dimensions against preset max */ - int w = new_rect.right - new_rect.left + 1; - int h = new_rect.bottom - new_rect.top + 1; + int w = new_rect.Width(); + int h = new_rect.Height(); if (mode != ADD_FORCE && (w > _settings_game.station.station_spread || h > _settings_game.station.station_spread)) { assert(mode != ADD_TRY); return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT); diff --git a/src/station_base.h b/src/station_base.h index ebb29026a9598..bd7f00b9f9181 100644 --- a/src/station_base.h +++ b/src/station_base.h @@ -501,7 +501,7 @@ struct Station FINAL : SpecializedStation { uint GetPlatformLength(TileIndex tile, DiagDirection dir) const override; uint GetPlatformLength(TileIndex tile) const override; - void RecomputeCatchment(); + void RecomputeCatchment(bool no_clear_nearby_lists = false); static void RecomputeCatchmentForAll(); uint GetCatchmentRadius() const; @@ -521,6 +521,11 @@ struct Station FINAL : SpecializedStation { return IsRailStationTile(tile) && GetStationIndex(tile) == this->index; } + inline bool TileBelongsToRoadStop(TileIndex tile) const + { + return IsRoadStopTile(tile) && GetStationIndex(tile) == this->index; + } + inline bool TileBelongsToAirport(TileIndex tile) const { return IsAirportTile(tile) && GetStationIndex(tile) == this->index; @@ -555,9 +560,9 @@ class AirportTileIterator : public OrthogonalTileIterator { return *this; } - virtual TileIterator *Clone() const + virtual std::unique_ptr Clone() const { - return new AirportTileIterator(*this); + return std::make_unique(*this); } }; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index abeeb611b7e0f..7930cad1af3b4 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -59,6 +59,7 @@ #include "waypoint_cmd.h" #include "landscape_cmd.h" #include "rail_cmd.h" +#include "newgrf_roadstop.h" #include "table/strings.h" @@ -77,7 +78,7 @@ * @pre IsTileType(t, MP_STATION) * @return true if and only if the tile is a hangar. */ -bool IsHangar(TileIndex t) +bool IsHangar(Tile t) { assert(IsTileType(t, MP_STATION)); @@ -88,7 +89,7 @@ bool IsHangar(TileIndex t) const AirportSpec *as = st->airport.GetSpec(); for (uint i = 0; i < as->nof_depots; i++) { - if (st->airport.GetHangarTile(i) == t) return true; + if (st->airport.GetHangarTile(i) == TileIndex(t)) return true; } return false; @@ -424,7 +425,7 @@ void Station::UpdateVirtCoord() SetDParam(0, this->index); SetDParam(1, this->facilities); - this->sign.UpdatePosition(pt.x, pt.y, STR_VIEWPORT_STATION); + this->sign.UpdatePosition(pt.x, pt.y, STR_VIEWPORT_STATION, STR_VIEWPORT_STATION_TINY); _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeStation(this->index)); @@ -931,7 +932,7 @@ static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag fl affected_vehicles.push_back(v); } } - CommandCost ret = Command::Do(flags, tile_cur, track); + ret = Command::Do(flags, tile_cur, track); if (ret.Failed()) return ret; cost.AddCost(ret); /* With flags & ~DC_EXEC CmdLandscapeClear would fail since the rail still exists */ @@ -1018,7 +1019,7 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags if (road_owner == OWNER_TOWN) { if (!_settings_game.construction.road_stop_on_town_road) return_cmd_error(STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD); } else if (!_settings_game.construction.road_stop_on_competitor_road && road_owner != OWNER_NONE) { - CommandCost ret = CheckOwnership(road_owner); + ret = CheckOwnership(road_owner); if (ret.Failed()) return ret; } uint num_pieces = CountBits(GetRoadBits(cur_tile, RTT_ROAD)); @@ -1026,7 +1027,7 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags if (RoadTypeIsRoad(rt) && !HasPowerOnRoad(rt, road_rt)) return_cmd_error(STR_ERROR_NO_SUITABLE_ROAD); if (GetDisallowedRoadDirections(cur_tile) != DRD_NONE && road_owner != OWNER_TOWN) { - CommandCost ret = CheckOwnership(road_owner); + ret = CheckOwnership(road_owner); if (ret.Failed()) return ret; } @@ -1044,7 +1045,7 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags /* Disallow breaking end-of-line of someone else * so trams can still reverse on this tile. */ HasExactlyOneBit(GetRoadBits(cur_tile, RTT_TRAM)))) { - CommandCost ret = CheckOwnership(tram_owner); + ret = CheckOwnership(tram_owner); if (ret.Failed()) return ret; } uint num_pieces = CountBits(GetRoadBits(cur_tile, RTT_TRAM)); @@ -1126,7 +1127,7 @@ void GetStationLayout(byte *layout, uint numtracks, uint plat_len, const Station !statspec->layouts[plat_len - 1][numtracks - 1].empty()) { /* Custom layout defined, follow it. */ memcpy(layout, statspec->layouts[plat_len - 1][numtracks - 1].data(), - plat_len * numtracks); + static_cast(plat_len) * numtracks); return; } @@ -1243,6 +1244,59 @@ static void RestoreTrainReservation(Train *v) if (IsRailStationTile(v->tile)) SetRailStationPlatformReservation(v->tile, TrackdirToExitdir(ReverseTrackdir(v->GetVehicleTrackdir())), true); } +/** + * Calculates cost of new rail stations within the area. + * @param tile_area Area to check. + * @param flags Operation to perform. + * @param axis Rail station axis. + * @param station StationID to be queried and returned if available. + * @param rt The rail type to check for (overbuilding rail stations over rail). + * @param affected_vehicles List of trains with PBS reservations on the tiles + * @param spec_class Station class. + * @param spec_index Index into the station class. + * @param plat_len Platform length. + * @param numtracks Number of platforms. + * @return The cost in case of success, or an error code if it failed. + */ +static CommandCost CalculateRailStationCost(TileArea tile_area, DoCommandFlag flags, Axis axis, StationID *station, RailType rt, std::vector &affected_vehicles, StationClassID spec_class, byte spec_index, byte plat_len, byte numtracks) +{ + CommandCost cost(EXPENSES_CONSTRUCTION); + bool success = false; + bool length_price_ready = true; + byte tracknum = 0; + for (TileIndex cur_tile : tile_area) { + /* Clear the land below the station. */ + CommandCost ret = CheckFlatLandRailStation(TileArea(cur_tile, 1, 1), flags, axis, station, rt, affected_vehicles, spec_class, spec_index, plat_len, numtracks); + if (ret.Failed()) return ret; + + /* Only add _price[PR_BUILD_STATION_RAIL_LENGTH] once for each valid plat_len. */ + if (tracknum == numtracks) { + length_price_ready = true; + tracknum = 0; + } else { + tracknum++; + } + + /* AddCost for new or rotated rail stations. */ + if (!IsRailStationTile(cur_tile) || (IsRailStationTile(cur_tile) && GetRailStationAxis(cur_tile) != axis)) { + + cost.AddCost(ret); + cost.AddCost(_price[PR_BUILD_STATION_RAIL]); + cost.AddCost(RailBuildCost(rt)); + + if (length_price_ready) { + cost.AddCost(_price[PR_BUILD_STATION_RAIL_LENGTH]); + length_price_ready = false; + } + success = true; + } + } + + if (!success) return_cmd_error(STR_ERROR_ALREADY_BUILT); + + return cost; +} + /** * Build rail station * @param flags operation to perform @@ -1293,12 +1347,9 @@ CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailTyp /* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */ StationID est = INVALID_STATION; std::vector affected_vehicles; - /* Clear the land below the station. */ - CommandCost cost = CheckFlatLandRailStation(new_location, flags, axis, &est, rt, affected_vehicles, spec_class, spec_index, plat_len, numtracks); + /* Add construction and clearing expenses. */ + CommandCost cost = CalculateRailStationCost(new_location, flags, axis, &est, rt, affected_vehicles, spec_class, spec_index, plat_len, numtracks); if (cost.Failed()) return cost; - /* Add construction expenses. */ - cost.AddCost((numtracks * _price[PR_BUILD_STATION_RAIL] + _price[PR_BUILD_STATION_RAIL_LENGTH]) * plat_len); - cost.AddCost(numtracks * plat_len * RailBuildCost(rt)); Station *st = nullptr; ret = FindJoiningStation(est, station_to_join, adjacent, new_location, &st); @@ -1308,7 +1359,7 @@ CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailTyp if (ret.Failed()) return ret; if (st != nullptr && st->train_station.tile != INVALID_TILE) { - CommandCost ret = CanExpandRailStation(st, new_location, axis); + ret = CanExpandRailStation(st, new_location, axis); if (ret.Failed()) return ret; } @@ -1573,7 +1624,7 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector &affected_st if (st == nullptr) continue; if (_current_company != OWNER_WATER) { - CommandCost ret = CheckOwnership(st->owner); + ret = CheckOwnership(st->owner); error.AddCost(ret); if (ret.Failed()) continue; } @@ -1657,7 +1708,7 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector &affected_st CommandCost CmdRemoveFromRailStation(DoCommandFlag flags, TileIndex start, TileIndex end, bool keep_rail) { if (end == 0) end = start; - if (start >= MapSize() || end >= MapSize()) return CMD_ERROR; + if (start >= Map::Size() || end >= Map::Size()) return CMD_ERROR; TileArea ta(start, end); std::vector affected_stations; @@ -1690,7 +1741,7 @@ CommandCost CmdRemoveFromRailStation(DoCommandFlag flags, TileIndex start, TileI CommandCost CmdRemoveFromRailWaypoint(DoCommandFlag flags, TileIndex start, TileIndex end, bool keep_rail) { if (end == 0) end = start; - if (start >= MapSize() || end >= MapSize()) return CMD_ERROR; + if (start >= Map::Size() || end >= Map::Size()) return CMD_ERROR; TileArea ta(start, end); std::vector affected_stations; @@ -1794,7 +1845,7 @@ static RoadStop **FindRoadStopSpot(bool truck_station, Station *st) } } -static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags); +static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags, int replacement_spec_index = -1); /** * Find a nearby station that joins this road stop. @@ -1810,6 +1861,54 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio return FindJoiningBaseStation(existing_stop, station_to_join, adjacent, ta, st); } +/** + * Calculates cost of new road stops within the area. + * @param tile_area Area to check. + * @param flags Operation to perform. + * @param is_drive_through True if trying to build a drive-through station. + * @param is_truck_stop True when building a truck stop, false otherwise. + * @param axis Axis of a drive-through road stop. + * @param ddir Entrance direction (#DiagDirection) for normal stops. Converted to the axis for drive-through stops. + * @param station StationID to be queried and returned if available. + * @param rt Road type to build. + * @param unit_cost The cost to build one road stop of the current type. + * @return The cost in case of success, or an error code if it failed. + */ +static CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlag flags, bool is_drive_through, bool is_truck_stop, Axis axis, DiagDirection ddir, StationID *est, RoadType rt, Money unit_cost) +{ + CommandCost cost(EXPENSES_CONSTRUCTION); + bool success = false; + /* Check every tile in the area. */ + for (TileIndex cur_tile : tile_area) { + uint invalid_dirs = 0; + if (is_drive_through) { + SetBit(invalid_dirs, AxisToDiagDir(axis)); + SetBit(invalid_dirs, ReverseDiagDir(AxisToDiagDir(axis))); + } else { + SetBit(invalid_dirs, ddir); + } + CommandCost ret = CheckFlatLandRoadStop(TileArea(cur_tile, cur_tile), flags, invalid_dirs, is_drive_through, is_truck_stop, axis, est, rt); + if (ret.Failed()) return ret; + + bool is_preexisting_roadstop = IsTileType(cur_tile, MP_STATION) && IsRoadStop(cur_tile); + + /* Only add costs if a stop doesn't already exist in the location */ + if (!is_preexisting_roadstop) { + cost.AddCost(ret); + cost.AddCost(unit_cost); + success = true; + } else if (is_preexisting_roadstop && !is_drive_through) { + /* Allow rotating non-drive through stops for free */ + success = true; + } + + } + + if (!success) return_cmd_error(STR_ERROR_ALREADY_BUILT); + + return cost; +} + /** * Build a bus or truck stop. * @param flags Operation to perform. @@ -1820,17 +1919,31 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio * @param is_drive_through False for normal stops, true for drive-through. * @param ddir Entrance direction (#DiagDirection) for normal stops. Converted to the axis for drive-through stops. * @param rt The roadtype. + * @param spec_class Road stop spec class. + * @param spec_index Road stop spec index. * @param station_to_join Station ID to join (NEW_STATION if build new one). * @param adjacent Allow stations directly adjacent to other stations. * @return The cost of this operation or an error. */ -CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, uint8 length, RoadStopType stop_type, bool is_drive_through, DiagDirection ddir, RoadType rt, StationID station_to_join, bool adjacent) +CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, uint8 length, RoadStopType stop_type, bool is_drive_through, + DiagDirection ddir, RoadType rt, RoadStopClassID spec_class, byte spec_index, StationID station_to_join, bool adjacent) { if (!ValParamRoadType(rt) || !IsValidDiagDirection(ddir) || stop_type >= ROADSTOP_END) return CMD_ERROR; bool reuse = (station_to_join != NEW_STATION); if (!reuse) station_to_join = INVALID_STATION; bool distant_join = (station_to_join != INVALID_STATION); + /* Check if the given station class is valid */ + if ((uint)spec_class >= RoadStopClass::GetClassCount() || spec_class == ROADSTOP_CLASS_WAYP) return CMD_ERROR; + if (spec_index >= RoadStopClass::Get(spec_class)->GetSpecCount()) return CMD_ERROR; + + const RoadStopSpec *roadstopspec = RoadStopClass::Get(spec_class)->GetSpec(spec_index); + if (roadstopspec != nullptr) { + if (stop_type == ROADSTOP_TRUCK && roadstopspec->stop_type != ROADSTOPTYPE_FREIGHT && roadstopspec->stop_type != ROADSTOPTYPE_ALL) return CMD_ERROR; + if (stop_type == ROADSTOP_BUS && roadstopspec->stop_type != ROADSTOPTYPE_PASSENGER && roadstopspec->stop_type != ROADSTOPTYPE_ALL) return CMD_ERROR; + if (!is_drive_through && HasBit(roadstopspec->flags, RSF_DRIVE_THROUGH_ONLY)) return CMD_ERROR; + } + /* Check if the requested road stop is too big */ if (width > _settings_game.station.station_spread || length > _settings_game.station.station_spread) return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT); /* Check for incorrect width / length. */ @@ -1853,22 +1966,40 @@ CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, u bool is_truck_stop = stop_type != ROADSTOP_BUS; /* Total road stop cost. */ - CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * _price[is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]); + Money unit_cost; + if (roadstopspec != nullptr) { + unit_cost = roadstopspec->GetBuildCost(is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS); + } else { + unit_cost = _price[is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]; + } StationID est = INVALID_STATION; - ret = CheckFlatLandRoadStop(roadstop_area, flags, is_drive_through ? 5 << axis : 1 << ddir, is_drive_through, is_truck_stop, axis, &est, rt); - if (ret.Failed()) return ret; - cost.AddCost(ret); + CommandCost cost = CalculateRoadStopCost(roadstop_area, flags, is_drive_through, is_truck_stop, axis, ddir, &est, rt, unit_cost); + if (cost.Failed()) return cost; Station *st = nullptr; ret = FindJoiningRoadStop(est, station_to_join, adjacent, roadstop_area, &st); if (ret.Failed()) return ret; /* Check if this number of road stops can be allocated. */ - if (!RoadStop::CanAllocateItem(roadstop_area.w * roadstop_area.h)) return_cmd_error(is_truck_stop ? STR_ERROR_TOO_MANY_TRUCK_STOPS : STR_ERROR_TOO_MANY_BUS_STOPS); + if (!RoadStop::CanAllocateItem(static_cast(roadstop_area.w) * roadstop_area.h)) return_cmd_error(is_truck_stop ? STR_ERROR_TOO_MANY_TRUCK_STOPS : STR_ERROR_TOO_MANY_BUS_STOPS); ret = BuildStationPart(&st, flags, reuse, roadstop_area, STATIONNAMING_ROAD); if (ret.Failed()) return ret; + /* Check if we can allocate a custom stationspec to this station */ + int specindex = AllocateSpecToRoadStop(roadstopspec, st, (flags & DC_EXEC) != 0); + if (specindex == -1) return_cmd_error(STR_ERROR_TOO_MANY_STATION_SPECS); + + if (roadstopspec != nullptr) { + /* Perform NewGRF checks */ + + /* Check if the road stop is buildable */ + if (HasBit(roadstopspec->callback_mask, CBM_ROAD_STOP_AVAIL)) { + uint16 cb_res = GetRoadStopCallback(CBID_STATION_AVAILABILITY, 0, 0, roadstopspec, nullptr, INVALID_TILE, rt, is_truck_stop ? STATION_TRUCK : STATION_BUS, 0); + if (cb_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(roadstopspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res)) return CMD_ERROR; + } + } + if (flags & DC_EXEC) { /* Check every tile in the area. */ for (TileIndex cur_tile : roadstop_area) { @@ -1879,7 +2010,13 @@ CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, u Owner tram_owner = tram_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_TRAM) : _current_company; if (IsTileType(cur_tile, MP_STATION) && IsRoadStop(cur_tile)) { - RemoveRoadStop(cur_tile, flags); + RemoveRoadStop(cur_tile, flags, specindex); + } + + if (roadstopspec != nullptr) { + /* Include this road stop spec's animation trigger bitmask + * in the station's cached copy. */ + st->cached_roadstop_anim_triggers |= roadstopspec->animation.triggers; } RoadStop *road_stop = new RoadStop(cur_tile); @@ -1910,20 +2047,23 @@ CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, u if (road_rt == INVALID_ROADTYPE && RoadTypeIsRoad(rt)) road_rt = rt; if (tram_rt == INVALID_ROADTYPE && RoadTypeIsTram(rt)) tram_rt = rt; - UpdateCompanyRoadInfrastructure(road_rt, road_owner, ROAD_STOP_TRACKBIT_FACTOR); - UpdateCompanyRoadInfrastructure(tram_rt, tram_owner, ROAD_STOP_TRACKBIT_FACTOR); - MakeDriveThroughRoadStop(cur_tile, st->owner, road_owner, tram_owner, st->index, rs_type, road_rt, tram_rt, axis); road_stop->MakeDriveThrough(); } else { if (road_rt == INVALID_ROADTYPE && RoadTypeIsRoad(rt)) road_rt = rt; if (tram_rt == INVALID_ROADTYPE && RoadTypeIsTram(rt)) tram_rt = rt; - /* Non-drive-through stop never overbuild and always count as two road bits. */ - Company::Get(st->owner)->infrastructure.road[rt] += ROAD_STOP_TRACKBIT_FACTOR; MakeRoadStop(cur_tile, st->owner, st->index, rs_type, road_rt, tram_rt, ddir); } + UpdateCompanyRoadInfrastructure(road_rt, road_owner, ROAD_STOP_TRACKBIT_FACTOR); + UpdateCompanyRoadInfrastructure(tram_rt, tram_owner, ROAD_STOP_TRACKBIT_FACTOR); Company::Get(st->owner)->infrastructure.station++; + SetCustomRoadStopSpecIndex(cur_tile, specindex); + if (roadstopspec != nullptr) { + st->SetRoadStopRandomBits(cur_tile, GB(Random(), 0, 8)); + TriggerRoadStopAnimation(st, cur_tile, SAT_BUILT); + } + MarkTileDirtyByTile(cur_tile); } @@ -1956,9 +2096,10 @@ static Vehicle *ClearRoadStopStatusEnum(Vehicle *v, void *) * Remove a bus station/truck stop * @param tile TileIndex been queried * @param flags operation to perform + * @param replacement_spec_index replacement spec index to avoid deallocating, if < 0, tile is not being replaced * @return cost or failure of operation */ -static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) +static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags, int replacement_spec_index) { Station *st = Station::GetByTile(tile); @@ -1990,6 +2131,8 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) if (ret.Failed()) return ret; } + const RoadStopSpec *spec = GetRoadStopSpec(tile); + if (flags & DC_EXEC) { if (*primary_stop == cur_stop) { /* removed the first stop in the list */ @@ -2014,6 +2157,12 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) Company::Get(st->owner)->infrastructure.station--; DirtyCompanyInfrastructureWindows(st->owner); + DeleteAnimatedTile(tile); + + uint specindex = GetCustomRoadStopSpecIndex(tile); + + DeleteNewGRFInspectWindow(GSF_ROADSTOPS, tile); + if (IsDriveThroughStopTile(tile)) { /* Clears the tile for us */ cur_stop->ClearDriveThrough(); @@ -2033,7 +2182,10 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) st->rect.AfterRemoveTile(st, tile); - st->AfterStationTileSetChange(false, is_truck ? STATION_TRUCK: STATION_BUS); + if (replacement_spec_index < 0) st->AfterStationTileSetChange(false, is_truck ? STATION_TRUCK: STATION_BUS); + + st->RemoveRoadStopTileData(tile); + if ((int)specindex != replacement_spec_index) DeallocateSpecFromRoadStop(st, specindex); /* Update the tile area of the truck/bus stop */ if (is_truck) { @@ -2045,7 +2197,8 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) } } - return CommandCost(EXPENSES_CONSTRUCTION, _price[is_truck ? PR_CLEAR_STATION_TRUCK : PR_CLEAR_STATION_BUS]); + Price category = is_truck ? PR_CLEAR_STATION_TRUCK : PR_CLEAR_STATION_BUS; + return CommandCost(EXPENSES_CONSTRUCTION, spec != nullptr ? spec->GetClearCost(category) : _price[category]); } /** @@ -2239,13 +2392,13 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_ty return_cmd_error(STR_ERROR_STATION_TOO_SPREAD_OUT); } - AirportTileTableIterator iter(as->table[layout], tile); - CommandCost cost = CheckFlatLandAirport(iter, flags); + AirportTileTableIterator tile_iter(as->table[layout], tile); + CommandCost cost = CheckFlatLandAirport(tile_iter, flags); if (cost.Failed()) return cost; /* The noise level is the noise from the airport and reduce it to account for the distance to the town center. */ uint dist; - Town *nearest = AirportGetNearestTown(as, iter, dist); + Town *nearest = AirportGetNearestTown(as, tile_iter, dist); uint newnoise_level = GetAirportNoiseLevelForDistance(as, dist); /* Check if local auth would allow a new airport */ @@ -2306,11 +2459,12 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_ty st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY); for (AirportTileTableIterator iter(as->table[layout], tile); iter != INVALID_TILE; ++iter) { - MakeAirport(iter, st->owner, st->index, iter.GetStationGfx(), WATER_CLASS_INVALID); - SetStationTileRandomBits(iter, GB(Random(), 0, 4)); + Tile t(iter); + MakeAirport(t, st->owner, st->index, iter.GetStationGfx(), WATER_CLASS_INVALID); + SetStationTileRandomBits(t, GB(Random(), 0, 4)); st->airport.Add(iter); - if (AirportTileSpec::Get(GetTranslatedAirportTileID(iter.GetStationGfx()))->animation.status != ANIM_STATUS_NO_ANIMATION) AddAnimatedTile(iter); + if (AirportTileSpec::Get(GetTranslatedAirportTileID(iter.GetStationGfx()))->animation.status != ANIM_STATUS_NO_ANIMATION) AddAnimatedTile(t); } /* Only call the animation trigger after all tiles have been built */ @@ -2503,7 +2657,7 @@ CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, StationID station_ TileIndex tile_cur = tile + TileOffsByDiagDir(direction); - if (!IsTileType(tile_cur, MP_WATER) || !IsTileFlat(tile_cur)) { + if (!HasTileWaterGround(tile_cur) || !IsTileFlat(tile_cur)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); } @@ -2512,8 +2666,10 @@ CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, StationID station_ /* Get the water class of the water tile before it is cleared.*/ WaterClass wc = GetWaterClass(tile_cur); + bool add_cost = !IsWaterTile(tile_cur); ret = Command::Do(flags, tile_cur); if (ret.Failed()) return ret; + if (add_cost) cost.AddCost(ret); tile_cur += TileOffsByDiagDir(direction); if (!IsTileType(tile_cur, MP_WATER) || !IsTileFlat(tile_cur)) { @@ -2536,14 +2692,17 @@ CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, StationID station_ if (flags & DC_EXEC) { st->ship_station.Add(tile); - st->ship_station.Add(tile + TileOffsByDiagDir(direction)); + TileIndex flat_tile = tile + TileOffsByDiagDir(direction); + st->ship_station.Add(flat_tile); st->AddFacility(FACIL_DOCK, tile); st->rect.BeforeAddRect(dock_area.tile, dock_area.w, dock_area.h, StationRect::ADD_TRY); /* If the water part of the dock is on a canal, update infrastructure counts. - * This is needed as we've unconditionally cleared that tile before. */ - if (wc == WATER_CLASS_CANAL) { + * This is needed as we've cleared that tile before. + * Clearing object tiles may result in water tiles which are already accounted for in the water infrastructure total. + * See: MakeWaterKeepingClass() */ + if (wc == WATER_CLASS_CANAL && !(HasTileWaterClass(flat_tile) && GetWaterClass(flat_tile) == WATER_CLASS_CANAL && IsTileOwner(flat_tile, _current_company))) { Company::Get(st->owner)->infrastructure.water++; } Company::Get(st->owner)->infrastructure.station += 2; @@ -2922,7 +3081,7 @@ static void DrawTile_Station(TileInfo *ti) EndSpriteCombine(); } - OffsetGroundSprite(31, 1); + OffsetGroundSprite(0, -8); ti->z += ApplyPixelFoundationToSlope(FOUNDATION_LEVELED, &ti->tileh); } else { draw_default_foundation: @@ -2930,6 +3089,8 @@ static void DrawTile_Station(TileInfo *ti) } } + bool draw_ground = false; + if (IsBuoy(ti->tile)) { DrawWaterClassGround(ti); SpriteID sprite = GetCanalSprite(CF_BUOY, ti->tile); @@ -2968,6 +3129,10 @@ static void DrawTile_Station(TileInfo *ti) ground_relocation += rti->fallback_railtype; } + draw_ground = true; + } + + if (draw_ground && !IsRoadStop(ti->tile)) { SpriteID image = t->ground.sprite; PaletteID pal = t->ground.pal; RailTrackOffset overlay_offset; @@ -2987,7 +3152,6 @@ static void DrawTile_Station(TileInfo *ti) /* PBS debugging, draw reserved tracks darker */ if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasStationRail(ti->tile) && HasStationReservation(ti->tile)) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); DrawGroundSprite(GetRailStationAxis(ti->tile) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH); } } @@ -3001,8 +3165,32 @@ static void DrawTile_Station(TileInfo *ti) const RoadTypeInfo* road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt); const RoadTypeInfo* tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt); + Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y; + DiagDirection dir = GetRoadStopDir(ti->tile); + StationType type = GetStationType(ti->tile); + + const RoadStopSpec *stopspec = GetRoadStopSpec(ti->tile); + if (stopspec != nullptr) { + int view = dir; + if (IsDriveThroughStopTile(ti->tile)) view += 4; + st = BaseStation::GetByTile(ti->tile); + RoadStopResolverObject object(stopspec, st, ti->tile, INVALID_ROADTYPE, type, view); + const SpriteGroup *group = object.Resolve(); + if (group != nullptr && group->type == SGT_TILELAYOUT) { + t = ((const TileLayoutSpriteGroup *)group)->ProcessRegisters(nullptr); + } + } + + /* Draw ground sprite */ + if (draw_ground) { + SpriteID image = t->ground.sprite; + PaletteID pal = t->ground.pal; + image += HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE) ? ground_relocation : total_offset; + if (HasBit(pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) pal += ground_relocation; + DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette)); + } + if (IsDriveThroughStopTile(ti->tile)) { - Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y; uint sprite_offset = axis == AXIS_X ? 1 : 0; DrawRoadOverlays(ti, PAL_NONE, road_rti, tram_rti, sprite_offset, sprite_offset); @@ -3010,15 +3198,16 @@ static void DrawTile_Station(TileInfo *ti) /* Non-drivethrough road stops are only valid for roads. */ assert(road_rt != INVALID_ROADTYPE && tram_rt == INVALID_ROADTYPE); - if (road_rti->UsesOverlay()) { - DiagDirection dir = GetRoadStopDir(ti->tile); + if ((stopspec == nullptr || (stopspec->draw_mode & ROADSTOP_DRAW_MODE_ROAD) != 0) && road_rti->UsesOverlay()) { SpriteID ground = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_ROADSTOP); DrawGroundSprite(ground + dir, PAL_NONE); } } - /* Draw road, tram catenary */ - DrawRoadCatenary(ti); + if (stopspec == nullptr || !HasBit(stopspec->flags, RSF_NO_CATENARY)) { + /* Draw road, tram catenary */ + DrawRoadCatenary(ti); + } } if (IsRailWaypoint(ti->tile)) { @@ -3034,17 +3223,17 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro int32 total_offset = 0; PaletteID pal = COMPANY_SPRITE_COLOUR(_local_company); const DrawTileSprites *t = GetStationTileLayout(st, image); - const RailtypeInfo *rti = nullptr; + const RailtypeInfo *railtype_info = nullptr; if (railtype != INVALID_RAILTYPE) { - rti = GetRailTypeInfo(railtype); - total_offset = rti->GetRailtypeSpriteOffset(); + railtype_info = GetRailTypeInfo(railtype); + total_offset = railtype_info->GetRailtypeSpriteOffset(); } SpriteID img = t->ground.sprite; RailTrackOffset overlay_offset; - if (rti != nullptr && rti->UsesOverlay() && SplitGroundSpriteForOverlay(nullptr, &img, &overlay_offset)) { - SpriteID ground = GetCustomRailSprite(rti, INVALID_TILE, RTSG_GROUND); + if (railtype_info != nullptr && railtype_info->UsesOverlay() && SplitGroundSpriteForOverlay(nullptr, &img, &overlay_offset)) { + SpriteID ground = GetCustomRailSprite(railtype_info, INVALID_TILE, RTSG_GROUND); DrawSprite(img, PAL_NONE, x, y); DrawSprite(ground + overlay_offset, PAL_NONE, x, y); } else { @@ -3052,25 +3241,25 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro } if (roadtype != INVALID_ROADTYPE) { - const RoadTypeInfo* rti = GetRoadTypeInfo(roadtype); + const RoadTypeInfo *roadtype_info = GetRoadTypeInfo(roadtype); if (image >= 4) { /* Drive-through stop */ uint sprite_offset = 5 - image; /* Road underlay takes precedence over tram */ - if (rti->UsesOverlay()) { - SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_GROUND); + if (roadtype_info->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(roadtype_info, INVALID_TILE, ROTSG_GROUND); DrawSprite(ground + sprite_offset, PAL_NONE, x, y); - SpriteID overlay = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_OVERLAY); + SpriteID overlay = GetCustomRoadSprite(roadtype_info, INVALID_TILE, ROTSG_OVERLAY); if (overlay) DrawSprite(overlay + sprite_offset, PAL_NONE, x, y); } else if (RoadTypeIsTram(roadtype)) { DrawSprite(SPR_TRAMWAY_TRAM + sprite_offset, PAL_NONE, x, y); } } else { /* Drive-in stop */ - if (RoadTypeIsRoad(roadtype) && rti->UsesOverlay()) { - SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_ROADSTOP); + if (RoadTypeIsRoad(roadtype) && roadtype_info->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(roadtype_info, INVALID_TILE, ROTSG_ROADSTOP); DrawSprite(ground + image, PAL_NONE, x, y); } } @@ -3090,83 +3279,89 @@ static Foundation GetFoundation_Station(TileIndex tile, Slope tileh) return FlatteningFoundation(tileh); } -static void GetTileDesc_Station(TileIndex tile, TileDesc *td) +static void FillTileDescRoadStop(TileIndex tile, TileDesc *td) { - td->owner[0] = GetTileOwner(tile); - - if (IsRoadStopTile(tile)) { - RoadType road_rt = GetRoadTypeRoad(tile); - RoadType tram_rt = GetRoadTypeTram(tile); - Owner road_owner = INVALID_OWNER; - Owner tram_owner = INVALID_OWNER; - if (road_rt != INVALID_ROADTYPE) { - const RoadTypeInfo *rti = GetRoadTypeInfo(road_rt); - td->roadtype = rti->strings.name; - td->road_speed = rti->max_speed / 2; - road_owner = GetRoadOwner(tile, RTT_ROAD); - } - - if (tram_rt != INVALID_ROADTYPE) { - const RoadTypeInfo *rti = GetRoadTypeInfo(tram_rt); - td->tramtype = rti->strings.name; - td->tram_speed = rti->max_speed / 2; - tram_owner = GetRoadOwner(tile, RTT_TRAM); - } - - if (IsDriveThroughStopTile(tile)) { - /* Is there a mix of owners? */ - if ((tram_owner != INVALID_OWNER && tram_owner != td->owner[0]) || - (road_owner != INVALID_OWNER && road_owner != td->owner[0])) { - uint i = 1; - if (road_owner != INVALID_OWNER) { - td->owner_type[i] = STR_LAND_AREA_INFORMATION_ROAD_OWNER; - td->owner[i] = road_owner; - i++; - } - if (tram_owner != INVALID_OWNER) { - td->owner_type[i] = STR_LAND_AREA_INFORMATION_TRAM_OWNER; - td->owner[i] = tram_owner; - } + RoadType road_rt = GetRoadTypeRoad(tile); + RoadType tram_rt = GetRoadTypeTram(tile); + Owner road_owner = INVALID_OWNER; + Owner tram_owner = INVALID_OWNER; + if (road_rt != INVALID_ROADTYPE) { + const RoadTypeInfo *rti = GetRoadTypeInfo(road_rt); + td->roadtype = rti->strings.name; + td->road_speed = rti->max_speed / 2; + road_owner = GetRoadOwner(tile, RTT_ROAD); + } + + if (tram_rt != INVALID_ROADTYPE) { + const RoadTypeInfo *rti = GetRoadTypeInfo(tram_rt); + td->tramtype = rti->strings.name; + td->tram_speed = rti->max_speed / 2; + tram_owner = GetRoadOwner(tile, RTT_TRAM); + } + + if (IsDriveThroughStopTile(tile)) { + /* Is there a mix of owners? */ + if ((tram_owner != INVALID_OWNER && tram_owner != td->owner[0]) || + (road_owner != INVALID_OWNER && road_owner != td->owner[0])) { + uint i = 1; + if (road_owner != INVALID_OWNER) { + td->owner_type[i] = STR_LAND_AREA_INFORMATION_ROAD_OWNER; + td->owner[i] = road_owner; + i++; + } + if (tram_owner != INVALID_OWNER) { + td->owner_type[i] = STR_LAND_AREA_INFORMATION_TRAM_OWNER; + td->owner[i] = tram_owner; } } } +} - td->build_date = BaseStation::GetByTile(tile)->build_date; - - if (HasStationTileRail(tile)) { - const StationSpec *spec = GetStationSpec(tile); +void FillTileDescRailStation(TileIndex tile, TileDesc *td) +{ + const StationSpec *spec = GetStationSpec(tile); - if (spec != nullptr) { - td->station_class = StationClass::Get(spec->cls_id)->name; - td->station_name = spec->name; + if (spec != nullptr) { + td->station_class = StationClass::Get(spec->cls_id)->name; + td->station_name = spec->name; - if (spec->grf_prop.grffile != nullptr) { - const GRFConfig *gc = GetGRFConfig(spec->grf_prop.grffile->grfid); - td->grf = gc->GetName(); - } + if (spec->grf_prop.grffile != nullptr) { + const GRFConfig *gc = GetGRFConfig(spec->grf_prop.grffile->grfid); + td->grf = gc->GetName(); } - - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); - td->rail_speed = rti->max_speed; - td->railtype = rti->strings.name; } - if (IsAirport(tile)) { - const AirportSpec *as = Station::GetByTile(tile)->airport.GetSpec(); - td->airport_class = AirportClass::Get(as->cls_id)->name; - td->airport_name = as->name; + const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); + td->rail_speed = rti->max_speed; + td->railtype = rti->strings.name; +} - const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile); - td->airport_tile_name = ats->name; +void FillTileDescAirport(TileIndex tile, TileDesc *td) +{ + const AirportSpec *as = Station::GetByTile(tile)->airport.GetSpec(); + td->airport_class = AirportClass::Get(as->cls_id)->name; + td->airport_name = as->name; - if (as->grf_prop.grffile != nullptr) { - const GRFConfig *gc = GetGRFConfig(as->grf_prop.grffile->grfid); - td->grf = gc->GetName(); - } else if (ats->grf_prop.grffile != nullptr) { - const GRFConfig *gc = GetGRFConfig(ats->grf_prop.grffile->grfid); - td->grf = gc->GetName(); - } + const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile); + td->airport_tile_name = ats->name; + + if (as->grf_prop.grffile != nullptr) { + const GRFConfig *gc = GetGRFConfig(as->grf_prop.grffile->grfid); + td->grf = gc->GetName(); + } else if (ats->grf_prop.grffile != nullptr) { + const GRFConfig *gc = GetGRFConfig(ats->grf_prop.grffile->grfid); + td->grf = gc->GetName(); } +} + +static void GetTileDesc_Station(TileIndex tile, TileDesc *td) +{ + td->owner[0] = GetTileOwner(tile); + td->build_date = BaseStation::GetByTile(tile)->build_date; + + if (IsRoadStop(tile)) FillTileDescRoadStop(tile, td); + if (HasStationRail(tile)) FillTileDescRailStation(tile, td); + if (IsAirport(tile)) FillTileDescAirport(tile, td); StringID str; switch (GetStationType(tile)) { @@ -3271,6 +3466,12 @@ static void AnimateTile_Station(TileIndex tile) if (IsAirport(tile)) { AnimateAirportTile(tile); + return; + } + + if (IsRoadStopTile(tile)) { + AnimateRoadStopTile(tile); + return; } } @@ -3612,12 +3813,10 @@ void DeleteStaleLinks(Station *from) GoodsEntry &ge = from->goods[c]; LinkGraph *lg = LinkGraph::GetIfValid(ge.link_graph); if (lg == nullptr) continue; - Node node = (*lg)[ge.node]; - for (EdgeIterator it(node.Begin()); it != node.End();) { - Edge edge = it->second; - Station *to = Station::Get((*lg)[it->first].Station()); - assert(to->goods[c].node == it->first); - ++it; // Do that before removing the edge. Anything else may crash. + std::vector to_remove{}; + for (Edge &edge : (*lg)[ge.node].edges) { + Station *to = Station::Get((*lg)[edge.dest_node].station); + assert(to->goods[c].node == edge.dest_node); assert(_date >= edge.LastUpdate()); uint timeout = LinkGraph::MIN_TIMEOUT_DISTANCE + (DistanceManhattan(from->xy, to->xy) >> 3); if ((uint)(_date - edge.LastUpdate()) > timeout) { @@ -3672,18 +3871,21 @@ void DeleteStaleLinks(Station *from) if (!updated) { /* If it's still considered dead remove it. */ - node.RemoveEdge(to->goods[c].node); + to_remove.emplace_back(to->goods[c].node); ge.flows.DeleteFlows(to->index); RerouteCargo(from, c, to->index, from->index); } - } else if (edge.LastUnrestrictedUpdate() != INVALID_DATE && (uint)(_date - edge.LastUnrestrictedUpdate()) > timeout) { + } else if (edge.last_unrestricted_update != INVALID_DATE && (uint)(_date - edge.last_unrestricted_update) > timeout) { edge.Restrict(); ge.flows.RestrictFlows(to->index); RerouteCargo(from, c, to->index, from->index); - } else if (edge.LastRestrictedUpdate() != INVALID_DATE && (uint)(_date - edge.LastRestrictedUpdate()) > timeout) { + } else if (edge.last_restricted_update != INVALID_DATE && (uint)(_date - edge.last_restricted_update) > timeout) { edge.Release(); } } + /* Remove dead edges. */ + for (NodeID r : to_remove) (*lg)[ge.node].RemoveEdge(r); + assert(_date >= lg->LastCompression()); if ((uint)(_date - lg->LastCompression()) > LinkGraph::COMPRESSION_INTERVAL) { lg->Compress(); @@ -3799,6 +4001,7 @@ void OnTick_Station() /* Stop processing this station if it was deleted */ if (!StationHandleBigTick(st)) continue; TriggerStationAnimation(st, st->xy, SAT_250_TICKS); + TriggerRoadStopAnimation(st, st->xy, SAT_250_TICKS); if (Station::IsExpected(st)) AirportAnimationTrigger(Station::From(st), AAT_STATION_250_TICKS); } } @@ -3871,6 +4074,9 @@ static uint UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceT TriggerStationRandomisation(st, st->xy, SRT_NEW_CARGO, type); TriggerStationAnimation(st, st->xy, SAT_NEW_CARGO, type); AirportAnimationTrigger(st, AAT_STATION_NEW_CARGO, type); + TriggerRoadStopRandomisation(st, st->xy, RSRT_NEW_CARGO, type); + TriggerRoadStopAnimation(st, st->xy, SAT_NEW_CARGO, type); + SetWindowDirty(WC_STATION_VIEW, st->index); st->MarkTilesDirty(true); @@ -4073,10 +4279,10 @@ void UpdateStationDockingTiles(Station *st) /* Expand the area by a tile on each side while * making sure that we remain inside the map. */ - int x2 = std::min(x + area->w + 1, MapSizeX()); + int x2 = std::min(x + area->w + 1, Map::SizeX()); int x1 = std::max(x - 1, 0); - int y2 = std::min(y + area->h + 1, MapSizeY()); + int y2 = std::min(y + area->h + 1, Map::SizeY()); int y1 = std::max(y - 1, 0); TileArea ta(TileXY(x1, y1), TileXY(x2 - 1, y2 - 1)); diff --git a/src/station_cmd.h b/src/station_cmd.h index 7dc23c68dc180..50a08bbd24762 100644 --- a/src/station_cmd.h +++ b/src/station_cmd.h @@ -14,12 +14,16 @@ #include "station_type.h" enum StationClassID : byte; +enum RoadStopClassID : byte; + +extern Town *AirportGetNearestTown(const struct AirportSpec *as, const TileIterator &it, uint &mindist); +extern uint8 GetAirportNoiseLevelForDistance(const struct AirportSpec *as, uint distance); CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_type, byte layout, StationID station_to_join, bool allow_adjacent); CommandCost CmdBuildDock(DoCommandFlag flags, TileIndex tile, StationID station_to_join, bool adjacent); CommandCost CmdBuildRailStation(DoCommandFlag flags, TileIndex tile_org, RailType rt, Axis axis, byte numtracks, byte plat_len, StationClassID spec_class, byte spec_index, StationID station_to_join, bool adjacent); CommandCost CmdRemoveFromRailStation(DoCommandFlag flags, TileIndex start, TileIndex end, bool keep_rail); -CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, uint8 length, RoadStopType stop_type, bool is_drive_through, DiagDirection ddir, RoadType rt, StationID station_to_join, bool adjacent); +CommandCost CmdBuildRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, uint8 length, RoadStopType stop_type, bool is_drive_through, DiagDirection ddir, RoadType rt, RoadStopClassID spec_class, byte spec_index, StationID station_to_join, bool adjacent); CommandCost CmdRemoveRoadStop(DoCommandFlag flags, TileIndex tile, uint8 width, uint8 height, RoadStopType stop_type, bool remove_road); CommandCost CmdRenameStation(DoCommandFlag flags, StationID station_id, const std::string &text); CommandCost CmdOpenCloseAirport(DoCommandFlag flags, StationID station_id); diff --git a/src/station_gui.cpp b/src/station_gui.cpp index 9233878212867..99a55e48f8588 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -56,7 +56,7 @@ int DrawStationCoverageAreaText(int left, int right, int top, StationCoverageTyp { TileIndex tile = TileVirtXY(_thd.pos.x, _thd.pos.y); CargoTypes cargo_mask = 0; - if (_thd.drawstyle == HT_RECT && tile < MapSize()) { + if (_thd.drawstyle == HT_RECT && tile < Map::Size()) { CargoArray cargoes; if (supplies) { cargoes = GetProductionAroundTiles(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE, rad); @@ -99,7 +99,7 @@ static void FindStationsAroundSelection() uint y = TileY(location.tile); int max_c = 1; - TileArea ta(TileXY(std::max(0, x - max_c), std::max(0, y - max_c)), TileXY(std::min(MapMaxX(), x + location.w + max_c), std::min(MapMaxY(), y + location.h + max_c))); + TileArea ta(TileXY(std::max(0, x - max_c), std::max(0, y - max_c)), TileXY(std::min(Map::MaxX(), x + location.w + max_c), std::min(Map::MaxY(), y + location.h + max_c))); Station *adjacent = nullptr; @@ -163,7 +163,7 @@ static void StationsWndShowStationRating(int left, int right, int y, CargoID typ const CargoSpec *cs = CargoSpec::Get(type); if (!cs->IsValid()) return; - int padding = ScaleFontTrad(1); + int padding = ScaleGUITrad(1); int width = right - left; int colour = cs->rating_colour; TextColour tc = GetContrastColour(colour); @@ -177,7 +177,7 @@ static void StationsWndShowStationRating(int left, int right, int y, CargoID typ } else { /* Draw a (scaled) one pixel-wide bar of additional cargo meter, useful * for stations with only a small amount (<=30) */ - uint rest = ScaleFontTrad(amount) / 5; + uint rest = ScaleGUITrad(amount) / 5; if (rest != 0) { GfxFillRect(left, y + height - rest, left + padding - 1, y + height, colour); } @@ -391,8 +391,8 @@ class CompanyStationsWindow : public Window } case WID_STL_LIST: - resize->height = std::max(FONT_HEIGHT_NORMAL, FONT_HEIGHT_SMALL + ScaleFontTrad(3)); - size->height = WD_FRAMERECT_TOP + 5 * resize->height + WD_FRAMERECT_BOTTOM; + resize->height = std::max(FONT_HEIGHT_NORMAL, FONT_HEIGHT_SMALL + ScaleGUITrad(3)); + size->height = padding.height + 5 * resize->height; /* Determine appropriate width for mini station rating graph */ this->rating_width = 0; @@ -403,16 +403,6 @@ class CompanyStationsWindow : public Window this->rating_width = this->rating_width * 16 / 10; break; - case WID_STL_CARGOALL: - case WID_STL_FACILALL: - case WID_STL_NOCARGOWAITING: { - Dimension d = GetStringBoundingBox(widget == WID_STL_NOCARGOWAITING ? STR_ABBREV_NONE : STR_ABBREV_ALL); - d.width += padding.width + 2; - d.height += padding.height; - *size = maxdim(*size, d); - break; - } - default: if (widget >= WID_STL_CARGOSTART) { Dimension d = GetStringBoundingBox(_sorted_cargo_specs[widget - WID_STL_CARGOSTART]->abbrev); @@ -443,12 +433,12 @@ class CompanyStationsWindow : public Window case WID_STL_LIST: { bool rtl = _current_text_dir == TD_RTL; int max = std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->stations.size()); - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); uint line_height = this->GetWidget(widget)->resize_y; /* Spacing between station name and first rating graph. */ - int text_spacing = ScaleFontTrad(5); + int text_spacing = WidgetDimensions::scaled.hsep_wide; /* Spacing between additional rating graphs. */ - int rating_spacing = ScaleFontTrad(4); + int rating_spacing = WidgetDimensions::scaled.hsep_normal; for (int i = this->vscroll->GetPosition(); i < max; ++i) { // do until max number of stations of owner const Station *st = this->stations[i]; @@ -460,7 +450,7 @@ class CompanyStationsWindow : public Window SetDParam(0, st->index); SetDParam(1, st->facilities); - int x = DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y + (line_height - FONT_HEIGHT_NORMAL) / 2, STR_STATION_LIST_STATION); + int x = DrawString(tr.left, tr.right, tr.top + (line_height - FONT_HEIGHT_NORMAL) / 2, STR_STATION_LIST_STATION); x += rtl ? -text_spacing : text_spacing; /* show cargo waiting and station ratings */ @@ -473,50 +463,34 @@ class CompanyStationsWindow : public Window * the space. */ if (rtl) { x -= rating_width + rating_spacing; - if (x < r.left + WD_FRAMERECT_LEFT) break; + if (x < tr.left) break; } - StationsWndShowStationRating(x, x + rating_width, y, cid, st->goods[cid].cargo.TotalCount(), st->goods[cid].rating); + StationsWndShowStationRating(x, x + rating_width, tr.top, cid, st->goods[cid].cargo.TotalCount(), st->goods[cid].rating); if (!rtl) { x += rating_width + rating_spacing; - if (x > r.right - WD_FRAMERECT_RIGHT) break; + if (x > tr.right) break; } } } - y += line_height; + tr.top += line_height; } if (this->vscroll->GetCount() == 0) { // company has no stations - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_LIST_NONE); + DrawString(tr.left, tr.right, tr.top + (line_height - FONT_HEIGHT_NORMAL) / 2, STR_STATION_LIST_NONE); return; } break; } - case WID_STL_NOCARGOWAITING: { - int cg_ofst = this->IsWidgetLowered(widget) ? 1 : 0; - DrawString(r.left + cg_ofst, r.right + cg_ofst, r.top + (r.bottom - r.top - FONT_HEIGHT_SMALL) / 2 + cg_ofst, STR_ABBREV_NONE, TC_BLACK, SA_HOR_CENTER); - break; - } - - case WID_STL_CARGOALL: { - int cg_ofst = this->IsWidgetLowered(widget) ? 1 : 0; - DrawString(r.left + cg_ofst, r.right + cg_ofst, r.top + (r.bottom - r.top - FONT_HEIGHT_SMALL) / 2 + cg_ofst, STR_ABBREV_ALL, TC_BLACK, SA_HOR_CENTER); - break; - } - - case WID_STL_FACILALL: { - int cg_ofst = this->IsWidgetLowered(widget) ? 1 : 0; - DrawString(r.left + cg_ofst, r.right + cg_ofst, r.top + (r.bottom - r.top - FONT_HEIGHT_SMALL) / 2 + cg_ofst, STR_ABBREV_ALL, TC_BLACK, SA_HOR_CENTER); - break; - } - default: if (widget >= WID_STL_CARGOSTART) { + Rect br = r.Shrink(WidgetDimensions::scaled.bevel); const CargoSpec *cs = _sorted_cargo_specs[widget - WID_STL_CARGOSTART]; - int cg_ofst = HasBit(this->cargo_filter, cs->Index()) ? 1 : 0; - GfxFillRect(r.left + cg_ofst + 1, r.top + cg_ofst + 1, r.right - 1 + cg_ofst, r.bottom - 1 + cg_ofst, cs->rating_colour); + int cg_ofst = HasBit(this->cargo_filter, cs->Index()) ? WidgetDimensions::scaled.pressed : 0; + br = br.Translate(cg_ofst, cg_ofst); + GfxFillRect(br, cs->rating_colour); TextColour tc = GetContrastColour(cs->rating_colour); - DrawString(r.left + cg_ofst, r.right + cg_ofst, r.top + (r.bottom - r.top - FONT_HEIGHT_SMALL) / 2 + cg_ofst, cs->abbrev, tc, SA_HOR_CENTER); + DrawString(br.left, br.right, CenterBounds(br.top, br.bottom, FONT_HEIGHT_SMALL), cs->abbrev, tc, SA_HOR_CENTER); } break; } @@ -667,7 +641,7 @@ class CompanyStationsWindow : public Window void OnResize() override { - this->vscroll->SetCapacityFromWidget(this, WID_STL_LIST, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + this->vscroll->SetCapacityFromWidget(this, WID_STL_LIST, WidgetDimensions::scaled.framerect.Vertical()); } /** @@ -749,17 +723,17 @@ static const NWidgetPart _nested_company_stations_widgets[] = { NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_BUS), SetMinimalSize(14, 0), SetMinimalTextLines(1, 0), SetDataTip(STR_BUS, STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE), SetFill(0, 1), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_SHIP), SetMinimalSize(14, 0), SetMinimalTextLines(1, 0), SetDataTip(STR_SHIP, STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE), SetFill(0, 1), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_AIRPLANE), SetMinimalSize(14, 0), SetMinimalTextLines(1, 0), SetDataTip(STR_PLANE, STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE), SetFill(0, 1), - NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_STL_FACILALL), SetMinimalSize(14, 0), SetMinimalTextLines(1, 0), SetDataTip(0x0, STR_STATION_LIST_SELECT_ALL_FACILITIES), SetFill(0, 1), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_STL_FACILALL), SetMinimalSize(14, 0), SetMinimalTextLines(1, 0), SetDataTip(STR_ABBREV_ALL, STR_STATION_LIST_SELECT_ALL_FACILITIES), SetFill(0, 1), NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(5, 0), SetFill(0, 1), EndContainer(), NWidgetFunction(CargoWidgets), - NWidget(WWT_PANEL, COLOUR_GREY, WID_STL_NOCARGOWAITING), SetMinimalSize(14, 0), SetMinimalTextLines(1, 0), SetDataTip(0x0, STR_STATION_LIST_NO_WAITING_CARGO), SetFill(0, 1), EndContainer(), - NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_STL_CARGOALL), SetMinimalSize(14, 0), SetMinimalTextLines(1, 0), SetDataTip(0x0, STR_STATION_LIST_SELECT_ALL_TYPES), SetFill(0, 1), - NWidget(WWT_PANEL, COLOUR_GREY), SetDataTip(0x0, STR_NULL), SetResize(1, 0), SetFill(1, 1), EndContainer(), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_STL_NOCARGOWAITING), SetMinimalSize(14, 0), SetMinimalTextLines(1, 0), SetDataTip(STR_ABBREV_NONE, STR_STATION_LIST_NO_WAITING_CARGO), SetFill(0, 1), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_STL_CARGOALL), SetMinimalSize(14, 0), SetMinimalTextLines(1, 0), SetDataTip(STR_ABBREV_ALL, STR_STATION_LIST_SELECT_ALL_TYPES), SetFill(0, 1), + NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_STL_SORTBY), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_STL_SORTDROPBTN), SetMinimalSize(163, 12), SetDataTip(STR_SORT_BY_NAME, STR_TOOLTIP_SORT_CRITERIA), // widget_data gets overwritten. - NWidget(WWT_PANEL, COLOUR_GREY), SetDataTip(0x0, STR_NULL), SetResize(1, 0), SetFill(1, 1), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_GREY, WID_STL_LIST), SetMinimalSize(346, 125), SetResize(1, 10), SetDataTip(0x0, STR_STATION_LIST_TOOLTIP), SetScrollbar(WID_STL_SCROLLBAR), EndContainer(), @@ -837,7 +811,7 @@ static const NWidgetPart _nested_station_view_widgets[] = { */ static void DrawCargoIcons(CargoID i, uint waiting, int left, int right, int y) { - int width = ScaleGUITrad(10); + int width = ScaleSpriteTrad(10); uint num = std::min((waiting + (width / 2)) / width, (right - left) / width); // maximum is width / 10 icons so it won't overflow if (num == 0) return; @@ -1394,12 +1368,12 @@ struct StationViewWindow : public Window { switch (widget) { case WID_SV_WAITING: resize->height = FONT_HEIGHT_NORMAL; - size->height = WD_FRAMERECT_TOP + 4 * resize->height + WD_FRAMERECT_BOTTOM; - this->expand_shrink_width = std::max(GetStringBoundingBox("-").width, GetStringBoundingBox("+").width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + size->height = 4 * resize->height + padding.height; + this->expand_shrink_width = std::max(GetStringBoundingBox("-").width, GetStringBoundingBox("+").width); break; case WID_SV_ACCEPT_RATING_LIST: - size->height = WD_FRAMERECT_TOP + ((this->GetWidget(WID_SV_ACCEPTS_RATINGS)->widget_data == STR_STATION_VIEW_RATINGS_BUTTON) ? this->accepts_lines : this->rating_lines) * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM; + size->height = ((this->GetWidget(WID_SV_ACCEPTS_RATINGS)->widget_data == STR_STATION_VIEW_RATINGS_BUTTON) ? this->accepts_lines : this->rating_lines) * FONT_HEIGHT_NORMAL + padding.height; break; case WID_SV_CLOSE_AIRPORT: @@ -1467,7 +1441,7 @@ struct StationViewWindow : public Window { /* Draw waiting cargo. */ NWidgetBase *nwi = this->GetWidget(WID_SV_WAITING); - Rect waiting_rect = nwi->GetCurrentRect(); + Rect waiting_rect = nwi->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); this->DrawEntries(&cargo, waiting_rect, pos, maxrows, 0); scroll_to_row = INT_MAX; } @@ -1739,7 +1713,7 @@ struct StationViewWindow : public Window { * @param cargo Current cargo being drawn (if cargo column has been passed). * @return row (in "pos" counting) after the one we have last drawn to. */ - int DrawEntries(CargoDataEntry *entry, Rect &r, int pos, int maxrows, int column, CargoID cargo = CT_INVALID) + int DrawEntries(CargoDataEntry *entry, const Rect &r, int pos, int maxrows, int column, CargoID cargo = CT_INVALID) { if (this->sortings[column] == ST_AS_GROUPING) { if (this->groupings[column] != GR_CARGO) { @@ -1757,13 +1731,13 @@ struct StationViewWindow : public Window { if (pos > -maxrows && pos <= 0) { StringID str = STR_EMPTY; - int y = r.top + WD_FRAMERECT_TOP - pos * FONT_HEIGHT_NORMAL; + int y = r.top - pos * FONT_HEIGHT_NORMAL; SetDParam(0, cargo); SetDParam(1, cd->GetCount()); if (this->groupings[column] == GR_CARGO) { str = STR_STATION_VIEW_WAITING_CARGO; - DrawCargoIcons(cd->GetCargo(), cd->GetCount(), r.left + WD_FRAMERECT_LEFT + this->expand_shrink_width, r.right - WD_FRAMERECT_RIGHT - this->expand_shrink_width, y); + DrawCargoIcons(cd->GetCargo(), cd->GetCount(), r.left + this->expand_shrink_width, r.right - this->expand_shrink_width, y); } else { if (!auto_distributed) grouping = GR_SOURCE; StationID station = cd->GetStation(); @@ -1788,12 +1762,10 @@ struct StationViewWindow : public Window { } bool rtl = _current_text_dir == TD_RTL; - int text_left = rtl ? r.left + this->expand_shrink_width : r.left + WD_FRAMERECT_LEFT + column * this->expand_shrink_width; - int text_right = rtl ? r.right - WD_FRAMERECT_LEFT - column * this->expand_shrink_width : r.right - this->expand_shrink_width; - int shrink_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.right - this->expand_shrink_width + WD_FRAMERECT_LEFT; - int shrink_right = rtl ? r.left + this->expand_shrink_width - WD_FRAMERECT_RIGHT : r.right - WD_FRAMERECT_RIGHT; + Rect text = r.Indent(column * WidgetDimensions::scaled.hsep_indent, rtl).Indent(this->expand_shrink_width, !rtl); + Rect shrink = r.WithWidth(this->expand_shrink_width, !rtl); - DrawString(text_left, text_right, y, str); + DrawString(text.left, text.right, y, str); if (column < NUM_COLUMNS - 1) { const char *sym = nullptr; @@ -1808,7 +1780,7 @@ struct StationViewWindow : public Window { sym = "+"; } } - if (sym) DrawString(shrink_left, shrink_right, y, sym, TC_YELLOW); + if (sym != nullptr) DrawString(shrink.left, shrink.right, y, sym, TC_YELLOW); } this->SetDisplayedRow(cd); } @@ -1828,14 +1800,15 @@ struct StationViewWindow : public Window { int DrawAcceptedCargo(const Rect &r) const { const Station *st = Station::Get(this->window_number); + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); CargoTypes cargo_mask = 0; for (CargoID i = 0; i < NUM_CARGO; i++) { if (HasBit(st->goods[i].status, GoodsEntry::GES_ACCEPTANCE)) SetBit(cargo_mask, i); } SetDParam(0, cargo_mask); - int bottom = DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, INT32_MAX, STR_STATION_VIEW_ACCEPTS_CARGO); - return CeilDiv(bottom - r.top - WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); + int bottom = DrawStringMultiLine(tr.left, tr.right, tr.top, INT32_MAX, STR_STATION_VIEW_ACCEPTS_CARGO); + return CeilDiv(bottom - r.top - WidgetDimensions::scaled.framerect.top, FONT_HEIGHT_NORMAL); } /** @@ -1846,16 +1819,17 @@ struct StationViewWindow : public Window { int DrawCargoRatings(const Rect &r) const { const Station *st = Station::Get(this->window_number); - int y = r.top + WD_FRAMERECT_TOP; + bool rtl = _current_text_dir == TD_RTL; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); if (st->town->exclusive_counter > 0) { SetDParam(0, st->town->exclusivity); - y = DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, r.bottom, st->town->exclusivity == st->owner ? STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF : STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY); - y += WD_PAR_VSEP_WIDE; + tr.top = DrawStringMultiLine(tr, st->town->exclusivity == st->owner ? STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF : STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY); + tr.top += WidgetDimensions::scaled.vsep_wide; } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_STATION_VIEW_SUPPLY_RATINGS_TITLE); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_STATION_VIEW_SUPPLY_RATINGS_TITLE); + tr.top += FONT_HEIGHT_NORMAL; for (const CargoSpec *cs : _sorted_standard_cargo_specs) { const GoodsEntry *ge = &st->goods[cs->Index()]; @@ -1863,13 +1837,13 @@ struct StationViewWindow : public Window { const LinkGraph *lg = LinkGraph::GetIfValid(ge->link_graph); SetDParam(0, cs->name); - SetDParam(1, lg != nullptr ? lg->Monthly((*lg)[ge->node].Supply()) : 0); + SetDParam(1, lg != nullptr ? lg->Monthly((*lg)[ge->node].supply) : 0); SetDParam(2, STR_CARGO_RATING_APPALLING + (ge->rating >> 5)); SetDParam(3, ToPercent8(ge->rating)); - DrawString(r.left + WD_FRAMERECT_LEFT + 6, r.right - WD_FRAMERECT_RIGHT - 6, y, STR_STATION_VIEW_CARGO_SUPPLY_RATING); - y += FONT_HEIGHT_NORMAL; + DrawString(tr.Indent(WidgetDimensions::scaled.hsep_indent, rtl), STR_STATION_VIEW_CARGO_SUPPLY_RATING); + tr.top += FONT_HEIGHT_NORMAL; } - return CeilDiv(y - r.top - WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); + return CeilDiv(tr.top - r.top - WidgetDimensions::scaled.framerect.top, FONT_HEIGHT_NORMAL); } /** @@ -1911,7 +1885,7 @@ struct StationViewWindow : public Window { { switch (widget) { case WID_SV_WAITING: - this->HandleCargoWaitingClick(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SV_WAITING, WD_FRAMERECT_TOP) - this->vscroll->GetPosition()); + this->HandleCargoWaitingClick(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SV_WAITING, WidgetDimensions::scaled.framerect.top) - this->vscroll->GetPosition()); break; case WID_SV_CATCHMENT: @@ -2090,7 +2064,7 @@ struct StationViewWindow : public Window { void OnResize() override { - this->vscroll->SetCapacityFromWidget(this, WID_SV_WAITING, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + this->vscroll->SetCapacityFromWidget(this, WID_SV_WAITING, WidgetDimensions::scaled.framerect.Vertical()); } /** @@ -2213,7 +2187,7 @@ static const T *FindStationsNearby(TileArea ta, bool distant_join) /* Check the inside, to return, if we sit on another station */ for (TileIndex t : ta) { - if (t < MapSize() && IsTileType(t, MP_STATION) && T::IsValidID(GetStationIndex(t))) return T::GetByTile(t); + if (t < Map::Size() && IsTileType(t, MP_STATION) && T::IsValidID(GetStationIndex(t))) return T::GetByTile(t); } /* Look for deleted stations */ @@ -2306,8 +2280,8 @@ struct SelectStationWindow : Window { resize->height = d.height; d.height *= 5; - d.width += WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT; - d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += padding.width; + d.height += padding.height; *size = d; } @@ -2315,20 +2289,20 @@ struct SelectStationWindow : Window { { if (widget != WID_JS_PANEL) return; - uint y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); if (this->vscroll->GetPosition() == 0) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT : STR_JOIN_STATION_CREATE_SPLITTED_STATION); - y += this->resize.step_height; + DrawString(tr, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT : STR_JOIN_STATION_CREATE_SPLITTED_STATION); + tr.top += this->resize.step_height; } - for (uint i = std::max(1, this->vscroll->GetPosition()); i <= _stations_nearby_list.size(); ++i, y += this->resize.step_height) { + for (uint i = std::max(1, this->vscroll->GetPosition()); i <= _stations_nearby_list.size(); ++i, tr.top += this->resize.step_height) { /* Don't draw anything if it extends past the end of the window. */ if (i - this->vscroll->GetPosition() >= this->vscroll->GetCapacity()) break; const T *st = T::Get(_stations_nearby_list[i - 1]); SetDParam(0, st->index); SetDParam(1, st->facilities); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_STATION_LIST_WAYPOINT : STR_STATION_LIST_STATION); + DrawString(tr, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_STATION_LIST_WAYPOINT : STR_STATION_LIST_STATION); } } @@ -2336,7 +2310,7 @@ struct SelectStationWindow : Window { { if (widget != WID_JS_PANEL) return; - uint st_index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_JS_PANEL, WD_FRAMERECT_TOP); + uint st_index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_JS_PANEL, WidgetDimensions::scaled.framerect.top); bool distant_join = (st_index > 0); if (distant_join) st_index--; @@ -2359,7 +2333,7 @@ struct SelectStationWindow : Window { void OnResize() override { - this->vscroll->SetCapacityFromWidget(this, WID_JS_PANEL, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + this->vscroll->SetCapacityFromWidget(this, WID_JS_PANEL, WidgetDimensions::scaled.framerect.Vertical()); } /** @@ -2383,7 +2357,7 @@ struct SelectStationWindow : Window { } /* Show coverage area of station under cursor */ - uint st_index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_JS_PANEL, WD_FRAMERECT_TOP); + uint st_index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_JS_PANEL, WidgetDimensions::scaled.framerect.top); if (st_index == 0 || st_index > _stations_nearby_list.size()) { SetViewportCatchmentStation(nullptr, true); } else { diff --git a/src/station_kdtree.h b/src/station_kdtree.h index 1c91ed3d2c097..63d7c393ec0d6 100644 --- a/src/station_kdtree.h +++ b/src/station_kdtree.h @@ -30,9 +30,9 @@ void ForAllStationsRadius(TileIndex center, uint radius, Func func) { uint16 x1, y1, x2, y2; x1 = (uint16)std::max(0, TileX(center) - radius); - x2 = (uint16)std::min(TileX(center) + radius + 1, MapSizeX()); + x2 = (uint16)std::min(TileX(center) + radius + 1, Map::SizeX()); y1 = (uint16)std::max(0, TileY(center) - radius); - y2 = (uint16)std::min(TileY(center) + radius + 1, MapSizeY()); + y2 = (uint16)std::min(TileY(center) + radius + 1, Map::SizeY()); _station_kdtree.FindContained(x1, y1, x2, y2, [&](StationID id) { func(Station::Get(id)); diff --git a/src/station_map.h b/src/station_map.h index dbb00ef2f5e93..f525cb48ba913 100644 --- a/src/station_map.h +++ b/src/station_map.h @@ -25,10 +25,10 @@ typedef byte StationGfx; ///< Index of station graphics. @see _station_display_d * @pre IsTileType(t, MP_STATION) * @return Station ID of the station at \a t */ -static inline StationID GetStationIndex(TileIndex t) +static inline StationID GetStationIndex(Tile t) { assert(IsTileType(t, MP_STATION)); - return (StationID)_m[t].m2; + return (StationID)t.m2(); } @@ -41,10 +41,10 @@ static const int GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET = 4; ///< The offset for the * @pre IsTileType(t, MP_STATION) * @return the station type */ -static inline StationType GetStationType(TileIndex t) +static inline StationType GetStationType(Tile t) { assert(IsTileType(t, MP_STATION)); - return (StationType)GB(_me[t].m6, 3, 3); + return (StationType)GB(t.m6(), 3, 3); } /** @@ -53,7 +53,7 @@ static inline StationType GetStationType(TileIndex t) * @pre GetStationType(t) == STATION_TRUCK || GetStationType(t) == STATION_BUS * @return the road stop type */ -static inline RoadStopType GetRoadStopType(TileIndex t) +static inline RoadStopType GetRoadStopType(Tile t) { assert(GetStationType(t) == STATION_TRUCK || GetStationType(t) == STATION_BUS); return GetStationType(t) == STATION_TRUCK ? ROADSTOP_TRUCK : ROADSTOP_BUS; @@ -65,10 +65,10 @@ static inline RoadStopType GetRoadStopType(TileIndex t) * @pre IsTileType(t, MP_STATION) * @return the station graphics */ -static inline StationGfx GetStationGfx(TileIndex t) +static inline StationGfx GetStationGfx(Tile t) { assert(IsTileType(t, MP_STATION)); - return _m[t].m5; + return t.m5(); } /** @@ -77,10 +77,10 @@ static inline StationGfx GetStationGfx(TileIndex t) * @param gfx the new graphics * @pre IsTileType(t, MP_STATION) */ -static inline void SetStationGfx(TileIndex t, StationGfx gfx) +static inline void SetStationGfx(Tile t, StationGfx gfx) { assert(IsTileType(t, MP_STATION)); - _m[t].m5 = gfx; + t.m5() = gfx; } /** @@ -89,7 +89,7 @@ static inline void SetStationGfx(TileIndex t, StationGfx gfx) * @pre IsTileType(t, MP_STATION) * @return true if and only if the tile is a rail station */ -static inline bool IsRailStation(TileIndex t) +static inline bool IsRailStation(Tile t) { return GetStationType(t) == STATION_RAIL; } @@ -99,7 +99,7 @@ static inline bool IsRailStation(TileIndex t) * @param t the tile to get the information from * @return true if and only if the tile is a rail station */ -static inline bool IsRailStationTile(TileIndex t) +static inline bool IsRailStationTile(Tile t) { return IsTileType(t, MP_STATION) && IsRailStation(t); } @@ -110,7 +110,7 @@ static inline bool IsRailStationTile(TileIndex t) * @pre IsTileType(t, MP_STATION) * @return true if and only if the tile is a rail waypoint */ -static inline bool IsRailWaypoint(TileIndex t) +static inline bool IsRailWaypoint(Tile t) { return GetStationType(t) == STATION_WAYPOINT; } @@ -120,7 +120,7 @@ static inline bool IsRailWaypoint(TileIndex t) * @param t the tile to get the information from * @return true if and only if the tile is a rail waypoint */ -static inline bool IsRailWaypointTile(TileIndex t) +static inline bool IsRailWaypointTile(Tile t) { return IsTileType(t, MP_STATION) && IsRailWaypoint(t); } @@ -132,7 +132,7 @@ static inline bool IsRailWaypointTile(TileIndex t) * @pre IsTileType(t, MP_STATION) * @return true if and only if the tile has rail */ -static inline bool HasStationRail(TileIndex t) +static inline bool HasStationRail(Tile t) { return IsRailStation(t) || IsRailWaypoint(t); } @@ -143,7 +143,7 @@ static inline bool HasStationRail(TileIndex t) * @param t the tile to check * @return true if and only if the tile is a station tile and has rail */ -static inline bool HasStationTileRail(TileIndex t) +static inline bool HasStationTileRail(Tile t) { return IsTileType(t, MP_STATION) && HasStationRail(t); } @@ -154,7 +154,7 @@ static inline bool HasStationTileRail(TileIndex t) * @pre IsTileType(t, MP_STATION) * @return true if and only if the tile is an airport */ -static inline bool IsAirport(TileIndex t) +static inline bool IsAirport(Tile t) { return GetStationType(t) == STATION_AIRPORT; } @@ -164,12 +164,12 @@ static inline bool IsAirport(TileIndex t) * @param t the tile to get the information from * @return true if and only if the tile is an airport */ -static inline bool IsAirportTile(TileIndex t) +static inline bool IsAirportTile(Tile t) { return IsTileType(t, MP_STATION) && IsAirport(t); } -bool IsHangar(TileIndex t); +bool IsHangar(Tile t); /** * Is the station at \a t a truck stop? @@ -177,7 +177,7 @@ bool IsHangar(TileIndex t); * @pre IsTileType(t, MP_STATION) * @return \c true if station is a truck stop, \c false otherwise */ -static inline bool IsTruckStop(TileIndex t) +static inline bool IsTruckStop(Tile t) { return GetStationType(t) == STATION_TRUCK; } @@ -188,7 +188,7 @@ static inline bool IsTruckStop(TileIndex t) * @pre IsTileType(t, MP_STATION) * @return \c true if station is a bus stop, \c false otherwise */ -static inline bool IsBusStop(TileIndex t) +static inline bool IsBusStop(Tile t) { return GetStationType(t) == STATION_BUS; } @@ -199,7 +199,7 @@ static inline bool IsBusStop(TileIndex t) * @pre IsTileType(t, MP_STATION) * @return \c true if station at the tile is a bus top or a truck stop, \c false otherwise */ -static inline bool IsRoadStop(TileIndex t) +static inline bool IsRoadStop(Tile t) { assert(IsTileType(t, MP_STATION)); return IsTruckStop(t) || IsBusStop(t); @@ -210,7 +210,7 @@ static inline bool IsRoadStop(TileIndex t) * @param t Tile to check * @return \c true if the tile is a station tile and a road stop */ -static inline bool IsRoadStopTile(TileIndex t) +static inline bool IsRoadStopTile(Tile t) { return IsTileType(t, MP_STATION) && IsRoadStop(t); } @@ -220,7 +220,7 @@ static inline bool IsRoadStopTile(TileIndex t) * @param t Tile to check * @return \c true if the tile is a station tile and a standard road stop */ -static inline bool IsStandardRoadStopTile(TileIndex t) +static inline bool IsStandardRoadStopTile(Tile t) { return IsRoadStopTile(t) && GetStationGfx(t) < GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET; } @@ -230,21 +230,22 @@ static inline bool IsStandardRoadStopTile(TileIndex t) * @param t Tile to check * @return \c true if the tile is a station tile and a drive through road stop */ -static inline bool IsDriveThroughStopTile(TileIndex t) +static inline bool IsDriveThroughStopTile(Tile t) { return IsRoadStopTile(t) && GetStationGfx(t) >= GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET; } +StationGfx GetTranslatedAirportTileID(StationGfx gfx); + /** * Get the station graphics of this airport tile * @param t the tile to query * @pre IsAirport(t) * @return the station graphics */ -static inline StationGfx GetAirportGfx(TileIndex t) +static inline StationGfx GetAirportGfx(Tile t) { assert(IsAirport(t)); - extern StationGfx GetTranslatedAirportTileID(StationGfx gfx); return GetTranslatedAirportTileID(GetStationGfx(t)); } @@ -254,7 +255,7 @@ static inline StationGfx GetAirportGfx(TileIndex t) * @pre IsRoadStopTile(t) * @return the direction of the entrance */ -static inline DiagDirection GetRoadStopDir(TileIndex t) +static inline DiagDirection GetRoadStopDir(Tile t) { StationGfx gfx = GetStationGfx(t); assert(IsRoadStopTile(t)); @@ -271,7 +272,7 @@ static inline DiagDirection GetRoadStopDir(TileIndex t) * @pre IsTileType(t, MP_STATION) * @return \c true if the tile is an oilrig tile */ -static inline bool IsOilRig(TileIndex t) +static inline bool IsOilRig(Tile t) { return GetStationType(t) == STATION_OILRIG; } @@ -282,7 +283,7 @@ static inline bool IsOilRig(TileIndex t) * @pre IsTileType(t, MP_STATION) * @return \c true if the tile is a dock */ -static inline bool IsDock(TileIndex t) +static inline bool IsDock(Tile t) { return GetStationType(t) == STATION_DOCK; } @@ -292,7 +293,7 @@ static inline bool IsDock(TileIndex t) * @param t Tile to check * @return \c true if the tile is a dock */ -static inline bool IsDockTile(TileIndex t) +static inline bool IsDockTile(Tile t) { return IsTileType(t, MP_STATION) && GetStationType(t) == STATION_DOCK; } @@ -303,7 +304,7 @@ static inline bool IsDockTile(TileIndex t) * @pre IsTileType(t, MP_STATION) * @return \c true if the tile is a buoy */ -static inline bool IsBuoy(TileIndex t) +static inline bool IsBuoy(Tile t) { return GetStationType(t) == STATION_BUOY; } @@ -313,7 +314,7 @@ static inline bool IsBuoy(TileIndex t) * @param t Tile to check * @return \c true if the tile is a buoy */ -static inline bool IsBuoyTile(TileIndex t) +static inline bool IsBuoyTile(Tile t) { return IsTileType(t, MP_STATION) && IsBuoy(t); } @@ -323,7 +324,7 @@ static inline bool IsBuoyTile(TileIndex t) * @param t Tile to check * @return \c true if the tile is an hangar */ -static inline bool IsHangarTile(TileIndex t) +static inline bool IsHangarTile(Tile t) { return IsTileType(t, MP_STATION) && IsHangar(t); } @@ -334,7 +335,7 @@ static inline bool IsHangarTile(TileIndex t) * @pre HasStationRail(t) * @return The direction of the rails on tile \a t. */ -static inline Axis GetRailStationAxis(TileIndex t) +static inline Axis GetRailStationAxis(Tile t) { assert(HasStationRail(t)); return HasBit(GetStationGfx(t), 0) ? AXIS_Y : AXIS_X; @@ -346,7 +347,7 @@ static inline Axis GetRailStationAxis(TileIndex t) * @pre HasStationRail(t) * @return The rail track of the rails on tile \a t. */ -static inline Track GetRailStationTrack(TileIndex t) +static inline Track GetRailStationTrack(Tile t) { return AxisToTrack(GetRailStationAxis(t)); } @@ -357,7 +358,7 @@ static inline Track GetRailStationTrack(TileIndex t) * @pre HasStationRail(t) * @return The trackbits of the rails on tile \a t. */ -static inline TrackBits GetRailStationTrackBits(TileIndex t) +static inline TrackBits GetRailStationTrackBits(Tile t) { return AxisToTrackBits(GetRailStationAxis(t)); } @@ -375,7 +376,7 @@ static inline TrackBits GetRailStationTrackBits(TileIndex t) * @pre IsRailStationTile(station_tile) * @return true if the two tiles are compatible */ -static inline bool IsCompatibleTrainStationTile(TileIndex test_tile, TileIndex station_tile) +static inline bool IsCompatibleTrainStationTile(Tile test_tile, Tile station_tile) { assert(IsRailStationTile(station_tile)); return IsRailStationTile(test_tile) && IsCompatibleRail(GetRailType(test_tile), GetRailType(station_tile)) && @@ -390,10 +391,10 @@ static inline bool IsCompatibleTrainStationTile(TileIndex test_tile, TileIndex s * @param t the station tile * @return reservation state */ -static inline bool HasStationReservation(TileIndex t) +static inline bool HasStationReservation(Tile t) { assert(HasStationRail(t)); - return HasBit(_me[t].m6, 2); + return HasBit(t.m6(), 2); } /** @@ -402,10 +403,10 @@ static inline bool HasStationReservation(TileIndex t) * @param t the station tile * @param b the reservation state */ -static inline void SetRailStationReservation(TileIndex t, bool b) +static inline void SetRailStationReservation(Tile t, bool b) { assert(HasStationRail(t)); - SB(_me[t].m6, 2, 1, b ? 1 : 0); + SB(t.m6(), 2, 1, b ? 1 : 0); } /** @@ -414,7 +415,7 @@ static inline void SetRailStationReservation(TileIndex t, bool b) * @param t the tile * @return reserved track bits */ -static inline TrackBits GetStationReservationTrackBits(TileIndex t) +static inline TrackBits GetStationReservationTrackBits(Tile t) { return HasStationReservation(t) ? GetRailStationTrackBits(t) : TRACK_BIT_NONE; } @@ -426,7 +427,7 @@ static inline TrackBits GetStationReservationTrackBits(TileIndex t) * @pre \a t is the land part of the dock * @return The direction of the dock on tile \a t. */ -static inline DiagDirection GetDockDirection(TileIndex t) +static inline DiagDirection GetDockDirection(Tile t) { StationGfx gfx = GetStationGfx(t); assert(IsDock(t) && gfx < GFX_DOCK_BASE_WATER_PART); @@ -440,7 +441,7 @@ static inline DiagDirection GetDockDirection(TileIndex t) * @pre IsBuoy(t) || IsOilRig(t) || IsDock(t) * @return The offset from this tile that should be used as destination for ships. */ -static inline TileIndexDiffC GetDockOffset(TileIndex t) +static inline TileIndexDiffC GetDockOffset(Tile t) { static const TileIndexDiffC buoy_offset = {0, 0}; static const TileIndexDiffC oilrig_offset = {2, 0}; @@ -466,10 +467,10 @@ static inline TileIndexDiffC GetDockOffset(TileIndex t) * @pre HasStationTileRail(t) * @return True if this station is part of a newgrf station. */ -static inline bool IsCustomStationSpecIndex(TileIndex t) +static inline bool IsCustomStationSpecIndex(Tile t) { assert(HasStationTileRail(t)); - return _m[t].m4 != 0; + return t.m4() != 0; } /** @@ -478,10 +479,10 @@ static inline bool IsCustomStationSpecIndex(TileIndex t) * @param specindex The new spec. * @pre HasStationTileRail(t) */ -static inline void SetCustomStationSpecIndex(TileIndex t, byte specindex) +static inline void SetCustomStationSpecIndex(Tile t, byte specindex) { assert(HasStationTileRail(t)); - _m[t].m4 = specindex; + t.m4() = specindex; } /** @@ -490,10 +491,46 @@ static inline void SetCustomStationSpecIndex(TileIndex t, byte specindex) * @pre HasStationTileRail(t) * @return The custom station spec of this tile. */ -static inline uint GetCustomStationSpecIndex(TileIndex t) +static inline uint GetCustomStationSpecIndex(Tile t) { assert(HasStationTileRail(t)); - return _m[t].m4; + return t.m4(); +} + +/** + * Is there a custom road stop spec on this tile? + * @param t Tile to query + * @pre IsRoadStopTile(t) + * @return True if this station is part of a newgrf station. + */ +static inline bool IsCustomRoadStopSpecIndex(Tile t) +{ + assert(IsRoadStopTile(t)); + return GB(t.m8(), 0, 6) != 0; +} + +/** + * Set the custom road stop spec for this tile. + * @param t Tile to set the stationspec of. + * @param specindex The new spec. + * @pre IsRoadStopTile(t) + */ +static inline void SetCustomRoadStopSpecIndex(Tile t, byte specindex) +{ + assert(IsRoadStopTile(t)); + SB(t.m8(), 0, 6, specindex); +} + +/** + * Get the custom road stop spec for this tile. + * @param t Tile to query + * @pre IsRoadStopTile(t) + * @return The custom station spec of this tile. + */ +static inline uint GetCustomRoadStopSpecIndex(Tile t) +{ + assert(IsRoadStopTile(t)); + return GB(t.m8(), 0, 6); } /** @@ -502,10 +539,10 @@ static inline uint GetCustomStationSpecIndex(TileIndex t) * @param random_bits The random bits. * @pre IsTileType(t, MP_STATION) */ -static inline void SetStationTileRandomBits(TileIndex t, byte random_bits) +static inline void SetStationTileRandomBits(Tile t, byte random_bits) { assert(IsTileType(t, MP_STATION)); - SB(_m[t].m3, 4, 4, random_bits); + SB(t.m3(), 4, 4, random_bits); } /** @@ -514,10 +551,10 @@ static inline void SetStationTileRandomBits(TileIndex t, byte random_bits) * @pre IsTileType(t, MP_STATION) * @return The random bits for this station tile. */ -static inline byte GetStationTileRandomBits(TileIndex t) +static inline byte GetStationTileRandomBits(Tile t) { assert(IsTileType(t, MP_STATION)); - return GB(_m[t].m3, 4, 4); + return GB(t.m3(), 4, 4); } /** @@ -529,20 +566,20 @@ static inline byte GetStationTileRandomBits(TileIndex t) * @param section the StationGfx to be used for this tile * @param wc The water class of the station */ -static inline void MakeStation(TileIndex t, Owner o, StationID sid, StationType st, byte section, WaterClass wc = WATER_CLASS_INVALID) +static inline void MakeStation(Tile t, Owner o, StationID sid, StationType st, byte section, WaterClass wc = WATER_CLASS_INVALID) { SetTileType(t, MP_STATION); SetTileOwner(t, o); SetWaterClass(t, wc); SetDockingTile(t, false); - _m[t].m2 = sid; - _m[t].m3 = 0; - _m[t].m4 = 0; - _m[t].m5 = section; - SB(_me[t].m6, 2, 1, 0); - SB(_me[t].m6, 3, 3, st); - _me[t].m7 = 0; - _me[t].m8 = 0; + t.m2() = sid; + t.m3() = 0; + t.m4() = 0; + t.m5() = section; + SB(t.m6(), 2, 1, 0); + SB(t.m6(), 3, 3, st); + t.m7() = 0; + t.m8() = 0; } /** @@ -554,7 +591,7 @@ static inline void MakeStation(TileIndex t, Owner o, StationID sid, StationType * @param section the StationGfx to be used for this tile * @param rt the railtype of this tile */ -static inline void MakeRailStation(TileIndex t, Owner o, StationID sid, Axis a, byte section, RailType rt) +static inline void MakeRailStation(Tile t, Owner o, StationID sid, Axis a, byte section, RailType rt) { MakeStation(t, o, sid, STATION_RAIL, section + a); SetRailType(t, rt); @@ -570,7 +607,7 @@ static inline void MakeRailStation(TileIndex t, Owner o, StationID sid, Axis a, * @param section the StationGfx to be used for this tile * @param rt the railtype of this tile */ -static inline void MakeRailWaypoint(TileIndex t, Owner o, StationID sid, Axis a, byte section, RailType rt) +static inline void MakeRailWaypoint(Tile t, Owner o, StationID sid, Axis a, byte section, RailType rt) { MakeStation(t, o, sid, STATION_WAYPOINT, section + a); SetRailType(t, rt); @@ -587,7 +624,7 @@ static inline void MakeRailWaypoint(TileIndex t, Owner o, StationID sid, Axis a, * @param tram_rt the tram roadtype on this tile * @param d the direction of the roadstop */ -static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStopType rst, RoadType road_rt, RoadType tram_rt, DiagDirection d) +static inline void MakeRoadStop(Tile t, Owner o, StationID sid, RoadStopType rst, RoadType road_rt, RoadType tram_rt, DiagDirection d) { MakeStation(t, o, sid, (rst == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK), d); SetRoadTypes(t, road_rt, tram_rt); @@ -607,7 +644,7 @@ static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStopTyp * @param tram_rt the tram roadtype on this tile * @param a the direction of the roadstop */ -static inline void MakeDriveThroughRoadStop(TileIndex t, Owner station, Owner road, Owner tram, StationID sid, RoadStopType rst, RoadType road_rt, RoadType tram_rt, Axis a) +static inline void MakeDriveThroughRoadStop(Tile t, Owner station, Owner road, Owner tram, StationID sid, RoadStopType rst, RoadType road_rt, RoadType tram_rt, Axis a) { MakeStation(t, station, sid, (rst == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK), GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET + a); SetRoadTypes(t, road_rt, tram_rt); @@ -623,7 +660,7 @@ static inline void MakeDriveThroughRoadStop(TileIndex t, Owner station, Owner ro * @param section the StationGfx to be used for this tile * @param wc the type of water on this tile */ -static inline void MakeAirport(TileIndex t, Owner o, StationID sid, byte section, WaterClass wc) +static inline void MakeAirport(Tile t, Owner o, StationID sid, byte section, WaterClass wc) { MakeStation(t, o, sid, STATION_AIRPORT, section, wc); } @@ -634,7 +671,7 @@ static inline void MakeAirport(TileIndex t, Owner o, StationID sid, byte section * @param sid the station to which this tile belongs * @param wc the type of water on this tile */ -static inline void MakeBuoy(TileIndex t, StationID sid, WaterClass wc) +static inline void MakeBuoy(Tile t, StationID sid, WaterClass wc) { /* Make the owner of the buoy tile the same as the current owner of the * water tile. In this way, we can reset the owner of the water to its @@ -650,10 +687,10 @@ static inline void MakeBuoy(TileIndex t, StationID sid, WaterClass wc) * @param d the direction of the dock * @param wc the type of water on this tile */ -static inline void MakeDock(TileIndex t, Owner o, StationID sid, DiagDirection d, WaterClass wc) +static inline void MakeDock(Tile t, Owner o, StationID sid, DiagDirection d, WaterClass wc) { MakeStation(t, o, sid, STATION_DOCK, d); - MakeStation(t + TileOffsByDiagDir(d), o, sid, STATION_DOCK, GFX_DOCK_BASE_WATER_PART + DiagDirToAxis(d), wc); + MakeStation(TileIndex(t) + TileOffsByDiagDir(d), o, sid, STATION_DOCK, GFX_DOCK_BASE_WATER_PART + DiagDirToAxis(d), wc); } /** @@ -662,7 +699,7 @@ static inline void MakeDock(TileIndex t, Owner o, StationID sid, DiagDirection d * @param sid the station to which this tile belongs * @param wc the type of water on this tile */ -static inline void MakeOilrig(TileIndex t, StationID sid, WaterClass wc) +static inline void MakeOilrig(Tile t, StationID sid, WaterClass wc) { MakeStation(t, OWNER_NONE, sid, STATION_OILRIG, 0, wc); } diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 5057f1a9de9b8..1b06a739fff6f 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -8,6 +8,7 @@ /** @file statusbar_gui.cpp The GUI for the bottom status bar. */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "date_func.h" #include "gfx_func.h" #include "news_func.h" @@ -68,10 +69,8 @@ static bool DrawScrollingStatusText(const NewsItem *ni, int scroll_pos, int left int width = GetStringBoundingBox(buffer).width; int pos = (_current_text_dir == TD_RTL) ? (scroll_pos - width) : (right - scroll_pos - left); - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); DrawString(pos, INT16_MAX, 0, buffer, TC_LIGHT_BLUE, SA_LEFT | SA_FORCE); - _cur_dpi = old_dpi; return (_current_text_dir == TD_RTL) ? (pos < right - left) : (pos + width > 0); } @@ -149,24 +148,24 @@ struct StatusBarWindow : Window { void DrawWidget(const Rect &r, int widget) const override { - int text_offset = std::max(0, ((int)(r.bottom - r.top + 1) - FONT_HEIGHT_NORMAL) / 2); // Offset for rendering the text vertically centered - int text_top = r.top + text_offset; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero); + tr.top = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL); switch (widget) { case WID_S_LEFT: /* Draw the date */ SetDateTimeParams(); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, GetWhiteDateTimeStringID(), TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, GetWhiteDateTimeStringID(), TC_FROMSTRING, SA_HOR_CENTER); break; case WID_S_RIGHT: { if (_local_company == COMPANY_SPECTATOR) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_STATUSBAR_SPECTATOR, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_STATUSBAR_SPECTATOR, TC_FROMSTRING, SA_HOR_CENTER); } else { /* Draw company money, if any */ const Company *c = Company::GetIfValid(_local_company); if (c != nullptr) { SetDParam(0, c->money); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_COMPANY_MONEY, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_COMPANY_MONEY, TC_FROMSTRING, SA_HOR_CENTER); } } break; @@ -175,33 +174,33 @@ struct StatusBarWindow : Window { case WID_S_MIDDLE: /* Draw status bar */ if (this->saving) { // true when saving is active - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_STATUSBAR_SAVING_GAME, TC_FROMSTRING, SA_HOR_CENTER | SA_VERT_CENTER); + DrawString(tr, STR_STATUSBAR_SAVING_GAME, TC_FROMSTRING, SA_HOR_CENTER | SA_VERT_CENTER); } else if (_do_autosave) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_STATUSBAR_AUTOSAVE, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_STATUSBAR_AUTOSAVE, TC_FROMSTRING, SA_HOR_CENTER); } else if (_pause_mode != PM_UNPAUSED) { StringID msg = (_pause_mode & PM_PAUSED_LINK_GRAPH) ? STR_STATUSBAR_PAUSED_LINK_GRAPH : STR_STATUSBAR_PAUSED; - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, msg, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, msg, TC_FROMSTRING, SA_HOR_CENTER); } else if (this->ticker_scroll < TICKER_STOP && _statusbar_news_item != nullptr && _statusbar_news_item->string_id != 0) { /* Draw the scrolling news text */ - if (!DrawScrollingStatusText(_statusbar_news_item, ScaleGUITrad(this->ticker_scroll), r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom)) { + if (!DrawScrollingStatusText(_statusbar_news_item, ScaleGUITrad(this->ticker_scroll), tr.left, tr.right, tr.top, tr.bottom)) { InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED); if (Company::IsValidID(_local_company)) { /* This is the default text */ SetDParam(0, _local_company); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER); } } } else { if (Company::IsValidID(_local_company)) { /* This is the default text */ SetDParam(0, _local_company); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, text_top, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(tr, STR_STATUSBAR_COMPANY_NAME, TC_FROMSTRING, SA_HOR_CENTER); } } if (!this->reminder_timeout.HasElapsed()) { Dimension icon_size = GetSpriteSize(SPR_UNREAD_NEWS); - DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, r.right - WD_FRAMERECT_RIGHT - icon_size.width, r.top + std::max(0, ((int)(r.bottom - r.top + 1) - (int)icon_size.height) / 2)); + DrawSprite(SPR_UNREAD_NEWS, PAL_NONE, tr.right - icon_size.width, CenterBounds(r.top, r.bottom, icon_size.height)); } break; } diff --git a/src/stdafx.h b/src/stdafx.h index effd57caea2a2..f62a83e83ca19 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -303,18 +303,71 @@ #define PACK(type_dec) PACK_N(type_dec, 1) /* MSVCRT of course has to have a different syntax for long long *sigh* */ -#if defined(_MSC_VER) || defined(__MINGW32__) +#if defined(_MSC_VER) +# define OTTD_PRINTF64 "%I64d" +# define OTTD_PRINTF64U "%I64u" +# define OTTD_PRINTFHEX64 "%I64x" +# define PRINTF_SIZE "%Iu" +# define PRINTF_SIZEX "%IX" +#elif defined(__MINGW32__) # define OTTD_PRINTF64 "%I64d" +# define OTTD_PRINTF64U "%I64llu" # define OTTD_PRINTFHEX64 "%I64x" # define PRINTF_SIZE "%Iu" # define PRINTF_SIZEX "%IX" #else # define OTTD_PRINTF64 "%lld" +# define OTTD_PRINTF64U "%llu" # define OTTD_PRINTFHEX64 "%llx" # define PRINTF_SIZE "%zu" # define PRINTF_SIZEX "%zX" #endif +/* + * When making a (pure) debug build, the compiler will by default disable + * inlining of functions. This has a detremental effect on the performance of + * debug builds, especially when more and more trivial (wrapper) functions get + * added to the code base. + * Take for example the savegame called "Wentbourne", when running this game + * for 100 ticks with the null video driver a number of fairly trivial + * functions show up on top. The most common one is the implicit conversion + * operator of TileIndex to unsigned int, which takes up over 5% of the total + * run time and functionally does absolutely nothing. The remaining functions + * for the top 5 are GB, GetTileType, Map::Size and IsTileType to a total of + * about 12.5% of the game's total run time. + * It is possible to still force inlining in the most commonly used compilers, + * but that is at the cost of some problems with debugging due to the forced + * inlining. However, the performance benefit can be enormous; when forcing + * inlining for the previously mentioned top 5, the debug build ran about 15% + * quicker. + * The following debug_inline annotation may be added to functions comply + * with the following preconditions: + * 1: the function takes more than 0.5% of a profiled debug runtime + * 2: the function does not modify the game state + * 3: the function does not contain selection or iteration statements, + * i.e. no if, switch, for, do, while, etcetera. + * 4: the function is one line of code, excluding assertions. + * 5: the function is defined in a header file. + * The debug_inline annotation must be placed in front of the function, i.e. + * before the optional static or constexpr modifier. + */ +#if !defined(_DEBUG) || defined(NO_DEBUG_INLINE) +/* + * Do not force inlining when not in debug. This way we do not work against + * any carefully designed compiler optimizations. + */ +#define debug_inline inline +#elif defined(__clang__) || defined(__GNUC__) +#define debug_inline [[gnu::always_inline]] inline +#else +/* + * MSVC explicitly disables inlining, even forced inlining, in debug builds + * so __forceinline makes no difference compared to inline. Other unknown + * compilers can also just fallback to a normal inline. + */ +#define debug_inline inline +#endif + typedef unsigned char byte; /* This is already defined in unix, but not in QNX Neutrino (6.x) or Cygwin. */ @@ -418,11 +471,13 @@ static_assert(SIZE_MAX >= UINT32_MAX); #endif /* __APPLE__ */ #if defined(__GNUC__) || defined(__clang__) -# define likely(x) __builtin_expect(!!(x), 1) -# define unlikely(x) __builtin_expect(!!(x), 0) +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +# define GNU_TARGET(x) [[gnu::target(x)]] #else -# define likely(x) (x) -# define unlikely(x) (x) +# define likely(x) (x) +# define unlikely(x) (x) +# define GNU_TARGET(x) #endif /* __GNUC__ || __clang__ */ /* For the FMT library we only want to use the headers, not link to some library. */ diff --git a/src/story_gui.cpp b/src/story_gui.cpp index b456b39e9a6fa..ac4ab8519f9a5 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.cpp @@ -278,7 +278,7 @@ struct StoryBookWindow : Window { */ uint GetAvailablePageContentWidth() const { - return this->GetWidget(WID_SB_PAGE_PANEL)->current_x - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT - 1; + return this->GetWidget(WID_SB_PAGE_PANEL)->current_x - WidgetDimensions::scaled.frametext.Horizontal() - 1; } /** @@ -346,7 +346,7 @@ struct StoryBookWindow : Window { case SPET_BUTTON_TILE: case SPET_BUTTON_VEHICLE: { Dimension dim = GetStringBoundingBox(pe.text, FS_NORMAL); - return dim.height + WD_BEVEL_TOP + WD_BEVEL_BOTTOM + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM; + return dim.height + WidgetDimensions::scaled.framerect.Vertical() + WidgetDimensions::scaled.frametext.Vertical(); } default: @@ -389,7 +389,7 @@ struct StoryBookWindow : Window { case SPET_BUTTON_TILE: case SPET_BUTTON_VEHICLE: { Dimension dim = GetStringBoundingBox(pe.text, FS_NORMAL); - return dim.width + WD_BEVEL_LEFT + WD_BEVEL_RIGHT + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT; + return dim.width + WidgetDimensions::scaled.framerect.Vertical() + WidgetDimensions::scaled.frametext.Vertical(); } default: @@ -533,7 +533,7 @@ struct StoryBookWindow : Window { uint text_top = y_offset + (element_height - line_height) / 2; DrawSprite(action_sprite, PAL_NONE, 0, sprite_top); - DrawString(sprite_dim.width + WD_FRAMETEXT_LEFT, width, text_top, string_id, TC_BLACK); + DrawString(sprite_dim.width + WidgetDimensions::scaled.frametext.left, width, text_top, string_id, TC_BLACK); y_offset += element_height; } @@ -692,19 +692,16 @@ struct StoryBookWindow : Window { StoryPage *page = this->GetSelPage(); if (page == nullptr) return; - const int x = r.left + WD_FRAMETEXT_LEFT; - const int y = r.top + WD_FRAMETEXT_TOP; - const int right = r.right - WD_FRAMETEXT_RIGHT; - const int bottom = r.bottom - WD_FRAMETEXT_BOTTOM; + Rect fr = r.Shrink(WidgetDimensions::scaled.frametext); /* Set up a clipping region for the panel. */ DrawPixelInfo tmp_dpi; - if (!FillDrawPixelInfo(&tmp_dpi, x, y, right - x + 1, bottom - y + 1)) return; + if (!FillDrawPixelInfo(&tmp_dpi, fr.left, fr.top, fr.Width(), fr.Height())) return; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); /* Draw content (now coordinates given to Draw** are local to the new clipping region). */ + fr = fr.Translate(-fr.left, -fr.top); int line_height = FONT_HEIGHT_NORMAL; const int scrollpos = this->vscroll->GetPosition(); int y_offset = -scrollpos; @@ -712,13 +709,13 @@ struct StoryBookWindow : Window { /* Date */ if (page->date != INVALID_DATE) { SetDParam(0, page->date); - DrawString(0, right - x, y_offset, STR_JUST_DATE_LONG, TC_BLACK); + DrawString(0, fr.right, y_offset, STR_JUST_DATE_LONG, TC_BLACK); } y_offset += line_height; /* Title */ SetDParamStr(0, page->title != nullptr ? page->title : this->selected_generic_title); - y_offset = DrawStringMultiLine(0, right - x, y_offset, bottom - y, STR_STORY_BOOK_TITLE, TC_BLACK, SA_TOP | SA_HOR_CENTER); + y_offset = DrawStringMultiLine(0, fr.right, y_offset, fr.bottom, STR_STORY_BOOK_TITLE, TC_BLACK, SA_TOP | SA_HOR_CENTER); /* Page elements */ this->EnsureStoryPageElementLayout(); @@ -746,23 +743,20 @@ struct StoryBookWindow : Window { case SPET_BUTTON_PUSH: case SPET_BUTTON_TILE: case SPET_BUTTON_VEHICLE: { - const int tmargin = WD_BEVEL_TOP + WD_FRAMETEXT_TOP; + const int tmargin = WidgetDimensions::scaled.bevel.top + WidgetDimensions::scaled.frametext.top; const FrameFlags frame = this->active_button_id == ce.pe->index ? FR_LOWERED : FR_NONE; const Colours bgcolour = StoryPageButtonData{ ce.pe->referenced_id }.GetColour(); DrawFrameRect(ce.bounds.left, ce.bounds.top - scrollpos, ce.bounds.right, ce.bounds.bottom - scrollpos - 1, bgcolour, frame); SetDParamStr(0, ce.pe->text); - DrawString(ce.bounds.left + WD_BEVEL_LEFT, ce.bounds.right - WD_BEVEL_RIGHT, ce.bounds.top + tmargin - scrollpos, STR_JUST_RAW_STRING, TC_WHITE, SA_CENTER); + DrawString(ce.bounds.left + WidgetDimensions::scaled.bevel.left, ce.bounds.right - WidgetDimensions::scaled.bevel.right, ce.bounds.top + tmargin - scrollpos, STR_JUST_RAW_STRING, TC_WHITE, SA_CENTER); break; } default: NOT_REACHED(); } } - - /* Restore clipping region. */ - _cur_dpi = old_dpi; } void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override @@ -800,7 +794,7 @@ struct StoryBookWindow : Window { case WID_SB_PAGE_PANEL: { d.height *= 5; - d.height += padding.height + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM; + d.height += padding.height + WidgetDimensions::scaled.frametext.Vertical(); *size = maxdim(*size, d); break; } @@ -811,7 +805,7 @@ struct StoryBookWindow : Window { void OnResize() override { this->InvalidateStoryPageElementLayout(); - this->vscroll->SetCapacityFromWidget(this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM); + this->vscroll->SetCapacityFromWidget(this, WID_SB_PAGE_PANEL, WidgetDimensions::scaled.frametext.Vertical()); this->vscroll->SetCount(this->GetContentHeight()); } @@ -843,7 +837,7 @@ struct StoryBookWindow : Window { break; case WID_SB_PAGE_PANEL: { - int clicked_y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP); + int clicked_y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SB_PAGE_PANEL, WidgetDimensions::scaled.frametext.top); this->EnsureStoryPageElementLayout(); for (const LayoutCacheElement &ce : this->layout_cache) { @@ -970,19 +964,15 @@ static const NWidgetPart _nested_story_book_widgets[] = { NWidget(WWT_STICKYBOX, COLOUR_BROWN), EndContainer(), NWidget(NWID_HORIZONTAL), SetFill(1, 1), - NWidget(NWID_VERTICAL), SetFill(1, 1), - NWidget(WWT_PANEL, COLOUR_BROWN, WID_SB_PAGE_PANEL), SetResize(1, 1), SetScrollbar(WID_SB_SCROLLBAR), EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SB_PREV_PAGE), SetMinimalSize(100, 0), SetFill(0, 0), SetDataTip(STR_STORY_BOOK_PREV_PAGE, STR_STORY_BOOK_PREV_PAGE_TOOLTIP), - NWidget(NWID_BUTTON_DROPDOWN, COLOUR_BROWN, WID_SB_SEL_PAGE), SetMinimalSize(93, 12), SetFill(1, 0), - SetDataTip(STR_BLACK_RAW_STRING, STR_STORY_BOOK_SEL_PAGE_TOOLTIP), SetResize(1, 0), - NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SB_NEXT_PAGE), SetMinimalSize(100, 0), SetFill(0, 0), SetDataTip(STR_STORY_BOOK_NEXT_PAGE, STR_STORY_BOOK_NEXT_PAGE_TOOLTIP), - EndContainer(), - EndContainer(), - NWidget(NWID_VERTICAL), SetFill(0, 1), - NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_SB_SCROLLBAR), - NWidget(WWT_RESIZEBOX, COLOUR_BROWN), - EndContainer(), + NWidget(WWT_PANEL, COLOUR_BROWN, WID_SB_PAGE_PANEL), SetResize(1, 1), SetScrollbar(WID_SB_SCROLLBAR), EndContainer(), + NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_SB_SCROLLBAR), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SB_PREV_PAGE), SetMinimalSize(100, 0), SetFill(0, 0), SetDataTip(STR_STORY_BOOK_PREV_PAGE, STR_STORY_BOOK_PREV_PAGE_TOOLTIP), + NWidget(NWID_BUTTON_DROPDOWN, COLOUR_BROWN, WID_SB_SEL_PAGE), SetMinimalSize(93, 12), SetFill(1, 0), + SetDataTip(STR_BLACK_RAW_STRING, STR_STORY_BOOK_SEL_PAGE_TOOLTIP), SetResize(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SB_NEXT_PAGE), SetMinimalSize(100, 0), SetFill(0, 0), SetDataTip(STR_STORY_BOOK_NEXT_PAGE, STR_STORY_BOOK_NEXT_PAGE_TOOLTIP), + NWidget(WWT_RESIZEBOX, COLOUR_BROWN), EndContainer(), }; diff --git a/src/strgen/strgen.cpp b/src/strgen/strgen.cpp index 025f9406df57b..b723aa656e635 100644 --- a/src/strgen/strgen.cpp +++ b/src/strgen/strgen.cpp @@ -472,9 +472,9 @@ int CDECL main(int argc, char *argv[]) case 'P': printf("name\tflags\tdefault\tdescription\n"); - for (size_t i = 0; i < lengthof(_pragmas); i++) { + for (size_t j = 0; j < lengthof(_pragmas); j++) { printf("\"%s\"\t%s\t\"%s\"\t\"%s\"\n", - _pragmas[i][0], _pragmas[i][1], _pragmas[i][2], _pragmas[i][3]); + _pragmas[j][0], _pragmas[j][1], _pragmas[j][2], _pragmas[j][3]); } return 0; diff --git a/src/strgen/strgen.h b/src/strgen/strgen.h index 2110d3087607f..809b4751439ad 100644 --- a/src/strgen/strgen.h +++ b/src/strgen/strgen.h @@ -136,6 +136,22 @@ struct LanguageWriter { virtual void WriteLang(const StringData &data); }; +struct CmdStruct; + +struct CmdPair { + const CmdStruct *a; + const char *v; +}; + +struct ParsedCommandStruct { + uint np; + CmdPair pairs[32]; + const CmdStruct *cmd[32]; // ordered by param # +}; + +const CmdStruct *TranslateCmdForCompare(const CmdStruct *a); +void ExtractCommandString(ParsedCommandStruct *p, const char *s, bool warnings); + void CDECL strgen_warning(const char *s, ...) WARN_FORMAT(1, 2); void CDECL strgen_error(const char *s, ...) WARN_FORMAT(1, 2); void NORETURN CDECL strgen_fatal(const char *s, ...) WARN_FORMAT(1, 2); diff --git a/src/strgen/strgen_base.cpp b/src/strgen/strgen_base.cpp index 078e0abbf2921..ccd043adfa7f7 100644 --- a/src/strgen/strgen_base.cpp +++ b/src/strgen/strgen_base.cpp @@ -217,17 +217,6 @@ uint StringData::CountInUse(uint tab) const static const char *_cur_ident; -struct CmdPair { - const CmdStruct *a; - const char *v; -}; - -struct ParsedCommandStruct { - uint np; - CmdPair pairs[32]; - const CmdStruct *cmd[32]; // ordered by param # -}; - /* Used when generating some advanced commands. */ static ParsedCommandStruct _cur_pcs; static int _cur_argidx; @@ -594,7 +583,7 @@ StringReader::~StringReader() free(file); } -static void ExtractCommandString(ParsedCommandStruct *p, const char *s, bool warnings) +void ExtractCommandString(ParsedCommandStruct *p, const char *s, bool warnings) { char param[MAX_COMMAND_PARAM_SIZE]; int argno; @@ -628,7 +617,7 @@ static void ExtractCommandString(ParsedCommandStruct *p, const char *s, bool war } -static const CmdStruct *TranslateCmdForCompare(const CmdStruct *a) +const CmdStruct *TranslateCmdForCompare(const CmdStruct *a) { if (a == nullptr) return nullptr; @@ -877,7 +866,7 @@ static int TranslateArgumentIdx(int argidx, int offset) } for (int i = sum = 0; i < argidx; i++) { - const CmdStruct *cs = _cur_pcs.cmd[i]; + cs = _cur_pcs.cmd[i]; sum += (cs != nullptr) ? cs->consumes : 1; } diff --git a/src/string.cpp b/src/string.cpp index aeac4fe84f736..0886f2805a15e 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -494,11 +494,12 @@ bool strtolower(std::string &str, std::string::size_type offs) bool IsValidChar(WChar key, CharSetFilter afilter) { switch (afilter) { - case CS_ALPHANUMERAL: return IsPrintable(key); - case CS_NUMERAL: return (key >= '0' && key <= '9'); - case CS_NUMERAL_SPACE: return (key >= '0' && key <= '9') || key == ' '; - case CS_ALPHA: return IsPrintable(key) && !(key >= '0' && key <= '9'); - case CS_HEXADECIMAL: return (key >= '0' && key <= '9') || (key >= 'a' && key <= 'f') || (key >= 'A' && key <= 'F'); + case CS_ALPHANUMERAL: return IsPrintable(key); + case CS_NUMERAL: return (key >= '0' && key <= '9'); + case CS_NUMERAL_SPACE: return (key >= '0' && key <= '9') || key == ' '; + case CS_NUMERAL_SIGNED: return (key >= '0' && key <= '9') || key == '-'; + case CS_ALPHA: return IsPrintable(key) && !(key >= '0' && key <= '9'); + case CS_HEXADECIMAL: return (key >= '0' && key <= '9') || (key >= 'a' && key <= 'f') || (key >= 'A' && key <= 'F'); default: NOT_REACHED(); } } @@ -617,7 +618,6 @@ size_t Utf8Decode(WChar *c, const char *s) } } - /* Debug(misc, 1, "[utf8] invalid UTF-8 sequence"); */ *c = '?'; return 1; } @@ -653,7 +653,6 @@ inline size_t Utf8Encode(T buf, WChar c) return 4; } - /* Debug(misc, 1, "[utf8] can't UTF-8 encode value 0x{:X}", c); */ *buf = '?'; return 1; } @@ -764,9 +763,9 @@ int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front) #ifdef WITH_UNISCRIBE -/* static */ StringIterator *StringIterator::Create() +/* static */ std::unique_ptr StringIterator::Create() { - return new UniscribeStringIterator(); + return std::make_unique(); } #elif defined(WITH_ICU_I18N) @@ -920,9 +919,9 @@ class IcuStringIterator : public StringIterator } }; -/* static */ StringIterator *StringIterator::Create() +/* static */ std::unique_ptr StringIterator::Create() { - return new IcuStringIterator(); + return std::make_unique(); } #else @@ -1031,17 +1030,17 @@ class DefaultStringIterator : public StringIterator }; #if defined(WITH_COCOA) && !defined(STRGEN) && !defined(SETTINGSGEN) -/* static */ StringIterator *StringIterator::Create() +/* static */ std::unique_ptr StringIterator::Create() { - StringIterator *i = OSXStringIterator::Create(); + std::unique_ptr i = OSXStringIterator::Create(); if (i != nullptr) return i; - return new DefaultStringIterator(); + return std::make_unique(); } #else -/* static */ StringIterator *StringIterator::Create() +/* static */ std::unique_ptr StringIterator::Create() { - return new DefaultStringIterator(); + return std::make_unique(); } #endif /* defined(WITH_COCOA) && !defined(STRGEN) && !defined(SETTINGSGEN) */ diff --git a/src/string_base.h b/src/string_base.h index a22be65713ed0..d7414c9156810 100644 --- a/src/string_base.h +++ b/src/string_base.h @@ -26,7 +26,7 @@ class StringIterator { * Create a new iterator instance. * @return New iterator instance. */ - static StringIterator *Create(); + static std::unique_ptr Create(); virtual ~StringIterator() {} diff --git a/src/string_type.h b/src/string_type.h index 25ea65598eab6..b8705e403f5d7 100644 --- a/src/string_type.h +++ b/src/string_type.h @@ -27,6 +27,7 @@ enum CharSetFilter { CS_ALPHANUMERAL, ///< Both numeric and alphabetic and spaces and stuff CS_NUMERAL, ///< Only numeric ones CS_NUMERAL_SPACE, ///< Only numbers and spaces + CS_NUMERAL_SIGNED, ///< Only numbers and '-' for negative values CS_ALPHA, ///< Only alphabetic values CS_HEXADECIMAL, ///< Only hexadecimal characters }; diff --git a/src/strings.cpp b/src/strings.cpp index 32efd953eeee9..6fbb189b3d5d7 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -34,6 +34,7 @@ #include "debug.h" #include "game/game_text.hpp" #include "network/network_content_gui.h" +#include "newgrf_engine.h" #include #include @@ -473,58 +474,6 @@ static char *FormatTinyTime(char *buff, DateFract date_fract, StringID str, cons return FormatString(buff, GetStringPtr(str), &tmp_params, last); } -/** - * Hide money scaling for user. Internally we will - * operate with amounts multiplied on PACE_FACTOR. For user though we want to show - * regular amounts. - * - * * for pace factor in range (1-10] we will show currencies with 1 digit after decimal point. - * * for pace factor in range (10-100] - with 2 digits after decimal point. - * * for higher pace factors with 3 digits after decimal point. - * - * @param number - money amount to be normalized - * @param need_fractional_part - whether we want to keep fractional part - * @return pair: - * * first - normalized money number - * * second - amount of fractional digits in money number - */ -static std::pair NormalizeMoney(Money number, bool need_fractional_part) { - auto pf = ::GetPaceFactor(); - auto cr = _currency->rate; - auto pfcr = pf / cr; - - int num_fractional_digits; - int fractional_factor; - if (pfcr <= 1) { - num_fractional_digits = 0; - fractional_factor = 1; - } else if (pfcr > 1 && pfcr <= 100) { - num_fractional_digits = 2; - fractional_factor = 100; - } else { - num_fractional_digits = 3; - fractional_factor = 1000; - } - - // We still believe that overflow won't happen with int64 and highest - // possible pace factor (which, as we believe is ~1000). - - Money number_new; - if (need_fractional_part) - number_new = number * fractional_factor; - else - num_fractional_digits = 0; - - double fnumber = (double)number_new / pf; - double intpart; - double rem = std::modf(fnumber, &intpart); - - if (rem > 0.999 || rem < 0.001) - return {number / pf, 0}; - - return {(Money)fnumber, num_fractional_digits}; -} - static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money number, bool compact, const char *last) { /* We are going to make number absolute for printing, so @@ -534,10 +483,6 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n number *= spec->rate; - // kaomoneus/OpenTTD/issues#10 - auto [norm_number, fractional_digits] = NormalizeMoney(number, !compact); - number = norm_number; - /* convert from negative */ if (number < 0) { if (buff + Utf8CharLen(SCC_PUSH_COLOUR) > last) return buff; @@ -569,7 +514,7 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n 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, /*zerofill=*/1, fractional_digits); + buff = FormatNumber(buff, number, last, separator); buff = strecpy(buff, multiplier, last); /* Add suffix part, following symbol_pos specification. @@ -780,13 +725,26 @@ static const Units _units_velocity[] = { { {37888, 16}, STR_UNITS_VELOCITY_GAMEUNITS, 1 }, }; -/** Unit conversions for velocity. */ +/** Unit conversions for power. */ static const Units _units_power[] = { { { 1, 0}, STR_UNITS_POWER_IMPERIAL, 0 }, { {4153, 12}, STR_UNITS_POWER_METRIC, 0 }, { {6109, 13}, STR_UNITS_POWER_SI, 0 }, }; +/** Unit conversions for power to weight. */ +static const Units _units_power_to_weight[] = { + { { 29, 5}, STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL, 1}, + { { 1, 0}, STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC, 1}, + { { 1, 0}, STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI, 1}, + { { 59, 6}, STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL, 1}, + { { 65, 6}, STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC, 1}, + { { 65, 6}, STR_UNITS_POWER_METRIC_TO_WEIGHT_SI, 1}, + { { 173, 8}, STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL, 1}, + { { 3, 2}, STR_UNITS_POWER_SI_TO_WEIGHT_METRIC, 1}, + { { 3, 2}, STR_UNITS_POWER_SI_TO_WEIGHT_SI, 1}, +}; + /** Unit conversions for weight. */ static const UnitsLong _units_weight[] = { { {4515, 12}, STR_UNITS_WEIGHT_SHORT_IMPERIAL, STR_UNITS_WEIGHT_LONG_IMPERIAL }, @@ -984,8 +942,9 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg sub_args.SetParam(i++, param); } else { + s++; // skip the leading \" char *g = stredup(s); - g[p - s] = '\0'; + g[p - s - 1] = '\0'; // skip the trailing \" sub_args_need_free[i] = true; sub_args.SetParam(i++, (uint64)(size_t)g); @@ -997,7 +956,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg buff = GetStringWithArgs(buff, MakeStringID(TEXT_TAB_GAMESCRIPT_START, stringid), &sub_args, last, true); } - for (int i = 0; i < 20; i++) { + for (i = 0; i < 20; i++) { if (sub_args_need_free[i]) free((void *)sub_args.GetParam(i)); } break; @@ -1102,20 +1061,19 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg break; case SCC_RAW_STRING_POINTER: { // {RAW_STRING} - if (game_script) break; - const char *str = (const char *)(size_t)args->GetInt64(SCC_RAW_STRING_POINTER); - buff = FormatString(buff, str, args, last); + const char *raw_string = (const char *)(size_t)args->GetInt64(SCC_RAW_STRING_POINTER); + buff = FormatString(buff, raw_string, args, last); break; } case SCC_STRING: {// {STRING} - StringID str = args->GetInt32(SCC_STRING); - if (game_script && GetStringTab(str) != TEXT_TAB_GAMESCRIPT_START) break; + StringID string_id = args->GetInt32(SCC_STRING); + if (game_script && GetStringTab(string_id) != TEXT_TAB_GAMESCRIPT_START) break; /* WARNING. It's prohibited for the included string to consume any arguments. * For included strings that consume argument, you should use STRING1, STRING2 etc. * To debug stuff you can set argv to nullptr and it will tell you */ StringParameters tmp_params(args->GetDataPointer(), args->GetDataLeft(), nullptr); - buff = GetStringWithArgs(buff, str, &tmp_params, last, next_substr_case_index, game_script); + buff = GetStringWithArgs(buff, string_id, &tmp_params, last, next_substr_case_index, game_script); next_substr_case_index = 0; break; } @@ -1128,14 +1086,14 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg case SCC_STRING6: case SCC_STRING7: { // {STRING1..7} /* Strings that consume arguments */ - StringID str = args->GetInt32(b); - if (game_script && GetStringTab(str) != TEXT_TAB_GAMESCRIPT_START) break; + StringID string_id = args->GetInt32(b); + if (game_script && GetStringTab(string_id) != TEXT_TAB_GAMESCRIPT_START) break; uint size = b - SCC_STRING1 + 1; if (game_script && size > args->GetDataLeft()) { buff = strecat(buff, "(too many parameters)", last); } else { StringParameters sub_args(*args, size); - buff = GetStringWithArgs(buff, str, &sub_args, last, next_substr_case_index, game_script); + buff = GetStringWithArgs(buff, string_id, &sub_args, last, next_substr_case_index, game_script); } next_substr_case_index = 0; break; @@ -1328,6 +1286,19 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg break; } + case SCC_POWER_TO_WEIGHT: { // {POWER_TO_WEIGHT} + auto setting = _settings_game.locale.units_power * 3u + _settings_game.locale.units_weight; + assert(setting < lengthof(_units_power_to_weight)); + + auto const &x = _units_power_to_weight[setting]; + + int64 args_array[] = {x.c.ToDisplay(args->GetInt64()), x.decimal_places}; + + StringParameters tmp_params(args_array); + buff = FormatString(buff, GetStringPtr(x.s), &tmp_params, last); + break; + } + case SCC_VELOCITY: { // {VELOCITY} assert(_settings_game.locale.units_velocity < lengthof(_units_velocity)); unsigned int decimal_places = _units_velocity[_settings_game.locale.units_velocity].decimal_places; @@ -1421,17 +1392,38 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg } case SCC_ENGINE_NAME: { // {ENGINE} - const Engine *e = Engine::GetIfValid(args->GetInt32(SCC_ENGINE_NAME)); + int64 arg = args->GetInt64(SCC_ENGINE_NAME); + const Engine *e = Engine::GetIfValid(static_cast(arg)); if (e == nullptr) break; if (!e->name.empty() && e->IsEnabled()) { int64 args_array[] = {(int64)(size_t)e->name.c_str()}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); - } else { - StringParameters tmp_params(nullptr, 0, nullptr); - buff = GetStringWithArgs(buff, e->info.string_id, &tmp_params, last); + + break; + } + + if (HasBit(e->info.callback_mask, CBM_VEHICLE_NAME)) { + uint16 callback = GetVehicleCallback(CBID_VEHICLE_NAME, static_cast(arg >> 32), 0, e->index, nullptr); + /* Not calling ErrorUnknownCallbackResult due to being inside string processing. */ + if (callback != CALLBACK_FAILED && callback < 0x400) { + const GRFFile *grffile = e->GetGRF(); + assert(grffile != nullptr); + + StartTextRefStackUsage(grffile, 6); + uint64 tmp_dparam[6] = { 0 }; + WChar tmp_type[6] = { 0 }; + StringParameters tmp_params(tmp_dparam, 6, tmp_type); + buff = GetStringWithArgs(buff, GetGRFStringID(grffile->grfid, 0xD000 + callback), &tmp_params, last); + StopTextRefStackUsage(); + + break; + } } + + StringParameters tmp_params(nullptr, 0, nullptr); + buff = GetStringWithArgs(buff, e->info.string_id, &tmp_params, last); break; } @@ -1506,7 +1498,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { - StringID str = st->string_id; + StringID string_id = st->string_id; if (st->indtype != IT_INVALID) { /* Special case where the industry provides the name for the station */ const IndustrySpec *indsp = GetIndustrySpec(st->indtype); @@ -1515,14 +1507,14 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg * thus cause very strange things. Here we check for that before we * actually set the station name. */ if (indsp->station_name != STR_NULL && indsp->station_name != STR_UNDEFINED) { - str = indsp->station_name; + string_id = indsp->station_name; } } uint64 args_array[] = {STR_TOWN_NAME, st->town->index, st->index}; WChar types_array[] = {0, SCC_TOWN_NAME, SCC_NUM}; StringParameters tmp_params(args_array, 3, types_array); - buff = GetStringWithArgs(buff, str, &tmp_params, last); + buff = GetStringWithArgs(buff, string_id, &tmp_params, last); } break; } @@ -1552,9 +1544,9 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg } else { int64 args_array[] = {wp->town->index, wp->town_cn + 1}; StringParameters tmp_params(args_array); - StringID str = ((wp->string_id == STR_SV_STNAME_BUOY) ? STR_FORMAT_BUOY_NAME : STR_FORMAT_WAYPOINT_NAME); - if (wp->town_cn != 0) str++; - buff = GetStringWithArgs(buff, str, &tmp_params, last); + StringID string_id = ((wp->string_id == STR_SV_STNAME_BUOY) ? STR_FORMAT_BUOY_NAME : STR_FORMAT_WAYPOINT_NAME); + if (wp->town_cn != 0) string_id++; + buff = GetStringWithArgs(buff, string_id, &tmp_params, last); } break; } @@ -1576,16 +1568,16 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg int64 args_array[] = {v->unitnumber}; StringParameters tmp_params(args_array); - StringID str; + StringID string_id; switch (v->type) { - default: str = STR_INVALID_VEHICLE; break; - case VEH_TRAIN: str = STR_SV_TRAIN_NAME; break; - case VEH_ROAD: str = STR_SV_ROAD_VEHICLE_NAME; break; - case VEH_SHIP: str = STR_SV_SHIP_NAME; break; - case VEH_AIRCRAFT: str = STR_SV_AIRCRAFT_NAME; break; + default: string_id = STR_INVALID_VEHICLE; break; + case VEH_TRAIN: string_id = STR_SV_TRAIN_NAME; break; + case VEH_ROAD: string_id = STR_SV_ROAD_VEHICLE_NAME; break; + case VEH_SHIP: string_id = STR_SV_SHIP_NAME; break; + case VEH_AIRCRAFT: string_id = STR_SV_AIRCRAFT_NAME; break; } - buff = GetStringWithArgs(buff, str, &tmp_params, last); + buff = GetStringWithArgs(buff, string_id, &tmp_params, last); } break; } @@ -2087,7 +2079,7 @@ const char *GetCurrentLanguageIsoCode() */ bool MissingGlyphSearcher::FindMissingGlyphs() { - InitFreeType(this->Monospace()); + InitFontCache(this->Monospace()); const Sprite *question_mark[FS_END]; for (FontSize size = this->Monospace() ? FS_MONO : FS_BEGIN; size < (this->Monospace() ? FS_END : FS_MONO); size++) { @@ -2112,7 +2104,7 @@ bool MissingGlyphSearcher::FindMissingGlyphs() default: NOT_REACHED(); } - Debug(freetype, 0, "Font is missing glyphs to display char 0x{:X} in {} font size", (int)c, size_name); + Debug(fontcache, 0, "Font is missing glyphs to display char 0x{:X} in {} font size", (int)c, size_name); return true; } } @@ -2156,7 +2148,7 @@ class LanguagePackGlyphSearcher : public MissingGlyphSearcher { return false; } - void SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data) override + void SetFontNames(FontCacheSettings *settings, const char *font_name, const void *os_data) override { #if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) settings->small.font = font_name; @@ -2192,15 +2184,15 @@ 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. */ - bool any_font_configured = !_freetype.medium.font.empty(); - FreeTypeSettings backup = _freetype; + bool any_font_configured = !_fcsettings.medium.font.empty(); + FontCacheSettings backup = _fcsettings; - _freetype.mono.os_handle = nullptr; - _freetype.medium.os_handle = nullptr; + _fcsettings.mono.os_handle = nullptr; + _fcsettings.medium.os_handle = nullptr; - bad_font = !SetFallbackFont(&_freetype, _langpack.langpack->isocode, _langpack.langpack->winlangid, searcher); + bad_font = !SetFallbackFont(&_fcsettings, _langpack.langpack->isocode, _langpack.langpack->winlangid, searcher); - _freetype = backup; + _fcsettings = backup; if (!bad_font && any_font_configured) { /* If the user configured a bad font, and we found a better one, @@ -2219,7 +2211,7 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher) /* Our fallback font does miss characters too, so keep the * user chosen font as that is more likely to be any good than * the wild guess we made */ - InitFreeType(searcher->Monospace()); + InitFontCache(searcher->Monospace()); } } #endif diff --git a/src/strings_func.h b/src/strings_func.h index e9b9f81598cf5..bdb4fc6cd6d73 100644 --- a/src/strings_func.h +++ b/src/strings_func.h @@ -203,6 +203,7 @@ void SetDParamMaxDigits(uint n, uint count, FontSize size = FS_NORMAL); void SetDParamStr(uint n, const char *str); void SetDParamStr(uint n, const std::string &str); +void SetDParamStr(uint n, std::string &&str) = delete; // block passing temporaries to SetDParamStr void CopyInDParam(int offs, const uint64 *src, int num); void CopyOutDParam(uint64 *dst, int offs, int num); @@ -273,7 +274,7 @@ class MissingGlyphSearcher { * @param font_name The new font name. * @param os_data Opaque pointer to OS-specific data. */ - virtual void SetFontNames(struct FreeTypeSettings *settings, const char *font_name, const void *os_data = nullptr) = 0; + virtual void SetFontNames(struct FontCacheSettings *settings, const char *font_name, const void *os_data = nullptr) = 0; bool FindMissingGlyphs(); }; diff --git a/src/subsidy_gui.cpp b/src/subsidy_gui.cpp index b46ca4da29b1c..1a87e1b00bd9a 100644 --- a/src/subsidy_gui.cpp +++ b/src/subsidy_gui.cpp @@ -40,7 +40,7 @@ struct SubsidyListWindow : Window { { if (widget != WID_SUL_PANEL) return; - int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SUL_PANEL, WD_FRAMERECT_TOP); + int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SUL_PANEL, WidgetDimensions::scaled.framerect.top); int num = 0; for (const Subsidy *s : Subsidy::Iterate()) { if (!s->IsAwarded()) { @@ -130,11 +130,11 @@ struct SubsidyListWindow : Window { if (widget != WID_SUL_PANEL) return; Dimension d = maxdim(GetStringBoundingBox(STR_SUBSIDIES_OFFERED_TITLE), GetStringBoundingBox(STR_SUBSIDIES_SUBSIDISED_TITLE)); - resize->height = d.height; + resize->height = FONT_HEIGHT_NORMAL; d.height *= 5; - d.width += padding.width + WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT; - d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += WidgetDimensions::scaled.framerect.Horizontal(); + d.height += WidgetDimensions::scaled.framerect.Vertical(); *size = maxdim(*size, d); } @@ -145,15 +145,13 @@ struct SubsidyListWindow : Window { YearMonthDay ymd; ConvertDateToYMD(_date, &ymd); - int right = r.right - WD_FRAMERECT_RIGHT; - int y = r.top + WD_FRAMERECT_TOP; - int x = r.left + WD_FRAMERECT_LEFT; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); int pos = -this->vscroll->GetPosition(); const int cap = this->vscroll->GetCapacity(); /* Section for drawing the offered subsidies */ - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_TITLE); + if (IsInsideMM(pos, 0, cap)) DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_TITLE); pos++; uint num = 0; @@ -163,7 +161,7 @@ struct SubsidyListWindow : Window { /* Displays the two offered towns */ SetupSubsidyDecodeParam(s, SubsidyDecodeParamType::Gui); SetDParam(7, _date - ymd.day + s->remaining * 32); - DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_FROM_TO); + DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_OFFERED_FROM_TO); } pos++; num++; @@ -171,13 +169,13 @@ struct SubsidyListWindow : Window { } if (num == 0) { - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE); + if (IsInsideMM(pos, 0, cap)) DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE); pos++; } /* Section for drawing the already granted subsidies */ pos++; - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_TITLE); + if (IsInsideMM(pos, 0, cap)) DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_TITLE); pos++; num = 0; @@ -189,7 +187,7 @@ struct SubsidyListWindow : Window { SetDParam(8, _date - ymd.day + s->remaining * 32); /* Displays the two connected stations */ - DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_FROM_TO); + DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_SUBSIDISED_FROM_TO); } pos++; num++; @@ -197,7 +195,7 @@ struct SubsidyListWindow : Window { } if (num == 0) { - if (IsInsideMM(pos, 0, cap)) DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE); + if (IsInsideMM(pos, 0, cap)) DrawString(tr.left, tr.right, tr.top + pos * FONT_HEIGHT_NORMAL, STR_SUBSIDIES_NONE); pos++; } } diff --git a/src/table/control_codes.h b/src/table/control_codes.h index cde0fc9a698dd..db773c28a90be 100644 --- a/src/table/control_codes.h +++ b/src/table/control_codes.h @@ -56,6 +56,7 @@ enum StringControlCode { SCC_CARGO_TINY, SCC_CARGO_LIST, SCC_POWER, + SCC_POWER_TO_WEIGHT, SCC_VOLUME_LONG, SCC_VOLUME_SHORT, SCC_WEIGHT_LONG, diff --git a/src/table/elrail_data.h b/src/table/elrail_data.h index 12132848b8282..5e1b9e792f2f4 100644 --- a/src/table/elrail_data.h +++ b/src/table/elrail_data.h @@ -327,7 +327,9 @@ struct SortableSpriteStruct { /** Distance between wire and rail */ static const uint ELRAIL_ELEVATION = 10; /** Wires that a draw one level higher than the north corner. */ -static const uint ELRAIL_ELEVRAISE = ELRAIL_ELEVATION + TILE_HEIGHT; +static const uint ELRAIL_ELEVRAISE = ELRAIL_ELEVATION + TILE_HEIGHT + 1; +/** Wires that a draw one level lower than the north corner. */ +static const uint ELRAIL_ELEVLOWER = ELRAIL_ELEVATION - 1; static const SortableSpriteStruct RailCatenarySpriteData[] = { /* X direction @@ -345,9 +347,9 @@ static const SortableSpriteStruct RailCatenarySpriteData[] = { /* "down" tiles * Wires */ - { WSO_X_SW_DOWN, 0, 7, 15, 8, 1, ELRAIL_ELEVATION }, //! 6: Wire in X pitch down, pylon on the SW end - { WSO_X_NE_DOWN, 0, 7, 15, 8, 1, ELRAIL_ELEVATION }, //! 7: Wire in X pitch down, pylon on the NE end - { WSO_X_SHORT_DOWN, 0, 7, 15, 8, 1, ELRAIL_ELEVATION }, //! 8: Wire in X pitch down, pylon on both ends + { WSO_X_SW_DOWN, 0, 7, 15, 8, 1, ELRAIL_ELEVLOWER }, //! 6: Wire in X pitch down, pylon on the SW end + { WSO_X_NE_DOWN, 0, 7, 15, 8, 1, ELRAIL_ELEVLOWER }, //! 7: Wire in X pitch down, pylon on the NE end + { WSO_X_SHORT_DOWN, 0, 7, 15, 8, 1, ELRAIL_ELEVLOWER }, //! 8: Wire in X pitch down, pylon on both ends /* Y direction @@ -365,9 +367,9 @@ static const SortableSpriteStruct RailCatenarySpriteData[] = { /* "down" tiles * Wires */ - { WSO_Y_SE_DOWN, 7, 0, 8, 15, 1, ELRAIL_ELEVATION }, //!15: Wire in Y pitch down, pylon on the SE end - { WSO_Y_NW_DOWN, 7, 0, 8, 15, 1, ELRAIL_ELEVATION }, //!16: Wire in Y pitch down, pylon on the NW end - { WSO_Y_SHORT_DOWN, 7, 0, 8, 15, 1, ELRAIL_ELEVATION }, //!17: Wire in Y pitch down, pylon on both ends + { WSO_Y_SE_DOWN, 7, 0, 8, 15, 1, ELRAIL_ELEVLOWER }, //!15: Wire in Y pitch down, pylon on the SE end + { WSO_Y_NW_DOWN, 7, 0, 8, 15, 1, ELRAIL_ELEVLOWER }, //!16: Wire in Y pitch down, pylon on the NW end + { WSO_Y_SHORT_DOWN, 7, 0, 8, 15, 1, ELRAIL_ELEVLOWER }, //!17: Wire in Y pitch down, pylon on both ends /* NS Direction */ { WSO_NS_SHORT, 8, 0, 8, 8, 1, ELRAIL_ELEVATION }, //!18: LEFT trackbit wire, pylon on both ends diff --git a/src/table/engines.h b/src/table/engines.h index ab6ba77467e6a..830ab93ced09d 100644 --- a/src/table/engines.h +++ b/src/table/engines.h @@ -24,7 +24,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MT(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_FLIPS, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } +#define MT(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a multiple-unit train into the EngineInfo struct. @@ -37,7 +37,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MM(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_FLIPS | 1 << EF_RAIL_IS_MU, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } +#define MM(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_IS_MU, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a train carriage into the EngineInfo struct. @@ -50,7 +50,7 @@ * @see MT * @note the 5 between b and f is the load amount */ -#define MW(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_FLIPS, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } +#define MW(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a road vehicle into the EngineInfo struct. @@ -63,7 +63,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MR(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } +#define MR(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of a ship into the EngineInfo struct. @@ -75,7 +75,7 @@ * @param f Bitmask of the climates * @note the 10 between b and f is the load amount */ -#define MS(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 10, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } +#define MS(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 10, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /** * Writes the properties of an aeroplane into the EngineInfo struct. @@ -86,7 +86,7 @@ * @param e Bitmask of the climates * @note the 20 between b and e is the load amount */ -#define MA(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 20, e, CT_INVALID, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } +#define MA(a, b, c, d, e) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 20, e, CT_INVALID, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS, INVALID_ENGINE, ExtraEngineFlags::None } /* Climates * T = Temperate @@ -386,7 +386,7 @@ static const EngineInfo _orig_engine_info[] = { * Tractive effort coefficient by default is the same as TTDPatch, 0.30*256=76 * Air drag value depends on the top speed of the vehicle. */ -#define RVI(a, b, c, d, e, f, g, h, i, j, k) { a, b, c, j, d, e, f, g, h, k, i, 0, 0, 0, VE_DEFAULT, 0, 76, 0, 0, 0 } +#define RVI(a, b, c, d, e, f, g, h, i, j, k) { a, b, c, j, j, d, e, f, g, h, k, i, 0, 0, 0, VE_DEFAULT, 0, 76, 0, 0, 0 } #define M RAILVEH_MULTIHEAD #define W RAILVEH_WAGON #define G RAILVEH_SINGLEHEAD diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index e35b2eecbf2cd..b99a11c4df818 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -10,6 +10,7 @@ #include "../newgrf_house.h" #include "../newgrf_engine.h" #include "../newgrf_roadtype.h" +#include "../newgrf_roadstop.h" /* Helper for filling property tables */ #define NIP(prop, base, variable, type, name) { name, [] (const void *b) -> const void * { return std::addressof(static_cast(b)->variable); }, cpp_sizeof(base, variable), prop, type } @@ -42,6 +43,7 @@ static const NICallback _nic_vehicles[] = { NICV(CBID_VEHICLE_SOUND_EFFECT, CBM_VEHICLE_SOUND_EFFECT), NICV(CBID_VEHICLE_AUTOREPLACE_SELECTION, CBM_NO_BIT), NICV(CBID_VEHICLE_MODIFY_PROPERTY, CBM_NO_BIT), + NICV(CBID_VEHICLE_NAME, CBM_VEHICLE_NAME), NIC_END() }; @@ -606,6 +608,64 @@ static const NIFeature _nif_tramtype = { new NIHRoadType(), }; +#define NICRS(cb_id, bit) NIC(cb_id, RoadStopSpec, callback_mask, bit) +static const NICallback _nic_roadstops[] = { + NICRS(CBID_STATION_AVAILABILITY, CBM_ROAD_STOP_AVAIL), + NICRS(CBID_STATION_ANIM_START_STOP, CBM_NO_BIT), + NICRS(CBID_STATION_ANIM_NEXT_FRAME, CBM_ROAD_STOP_ANIMATION_NEXT_FRAME), + NICRS(CBID_STATION_ANIMATION_SPEED, CBM_ROAD_STOP_ANIMATION_SPEED), + NIC_END() +}; + +static const NIVariable _nif_roadstops[] = { + NIV(0x40, "view/rotation"), + NIV(0x41, "stop type"), + NIV(0x42, "terrain type"), + NIV(0x43, "road type"), + NIV(0x44, "tram type"), + NIV(0x45, "town zone and Manhattan distance of town"), + NIV(0x46, "square of Euclidean distance of town"), + NIV(0x47, "player info"), + NIV(0x48, "bitmask of accepted cargoes"), + NIV(0x49, "current animation frame"), + NIV(0x60, "amount of cargo waiting"), + NIV(0x61, "time since last cargo pickup"), + NIV(0x62, "rating of cargo"), + NIV(0x63, "time spent on route"), + NIV(0x64, "information about last vehicle picking cargo up"), + NIV(0x65, "amount of cargo acceptance"), + NIV(0x66, "animation frame of nearby tile"), + NIV(0x67, "land info of nearby tiles"), + NIV(0x68, "road stop info of nearby tiles"), + NIV(0x69, "information about cargo accepted in the past"), + NIV(0x6A, "GRFID of nearby road stop tiles"), + NIV_END(), +}; + +class NIHRoadStop : public NIHelper { + bool IsInspectable(uint index) const override { return GetRoadStopSpec(index) != nullptr; } + uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, BaseStation::GetByTile(index)->town->index); } + const void *GetInstance(uint index)const override { return nullptr; } + const void *GetSpec(uint index) const override { return GetRoadStopSpec(index); } + void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); } + uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetRoadStopSpec(index)->grf_prop.grffile->grfid : 0; } + + uint Resolve(uint index, uint var, uint32 param, bool *avail) const override + { + int view = GetRoadStopDir(index); + if (IsDriveThroughStopTile(index)) view += 4; + RoadStopResolverObject ro(GetRoadStopSpec(index), BaseStation::GetByTile(index), index, INVALID_ROADTYPE, GetStationType(index), view); + return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); + } +}; + +static const NIFeature _nif_roadstop = { + nullptr, + _nic_roadstops, + _nif_roadstops, + new NIHRoadStop(), +}; + /** Table with all NIFeatures. */ static const NIFeature * const _nifeatures[] = { &_nif_vehicle, // GSF_TRAINS @@ -628,6 +688,7 @@ static const NIFeature * const _nifeatures[] = { &_nif_airporttile, // GSF_AIRPORTTILES &_nif_roadtype, // GSF_ROADTYPES &_nif_tramtype, // GSF_TRAMTYPES + &_nif_roadstop, // GSF_ROADSTOPS &_nif_town, // GSF_FAKE_TOWNS }; static_assert(lengthof(_nifeatures) == GSF_FAKE_END); diff --git a/src/table/object_land.h b/src/table/object_land.h index ed26a0f5009df..e5371712e7c4e 100644 --- a/src/table/object_land.h +++ b/src/table/object_land.h @@ -121,7 +121,7 @@ static const DrawTileSprites _object_hq[] = { #undef TILE_SPRITE_LINE -#define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) { GRFFilePropsBase<2>(), INVALID_OBJECT_CLASS, name, climate, size, build_cost_multiplier, clear_cost_multiplier, 0, MAX_DAY + 1, flags, {0, 0, 0, 0}, 0, height, 1, gen_amount, true } +#define M(name, size, build_cost_multiplier, clear_cost_multiplier, height, climate, gen_amount, flags) { GRFFilePropsBase<2>(), {0, 0, 0, 0}, INVALID_OBJECT_CLASS, name, climate, size, build_cost_multiplier, clear_cost_multiplier, 0, MAX_DAY + 1, flags, 0, height, 1, gen_amount } /* Climates * T = Temperate diff --git a/src/table/opengl_shader.h b/src/table/opengl_shader.h index 5f4244ef1bd29..b644123d14f71 100644 --- a/src/table/opengl_shader.h +++ b/src/table/opengl_shader.h @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * 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. diff --git a/src/table/road_land.h b/src/table/road_land.h index df38f935d50f1..0f84ebf1838ea 100644 --- a/src/table/road_land.h +++ b/src/table/road_land.h @@ -53,6 +53,46 @@ static const DrawTileSprites _crossing_layout = { {0, PAL_NONE}, _crossing_layout_ALL }; +static const DrawTileSeqStruct _crossing_layout_SW_ALL[] = { + TILE_SEQ_LINE(6, PAL_NONE, 13, 0, 3, 3) + TILE_SEQ_LINE(8, PAL_NONE, 13, 13, 3, 3) + TILE_SEQ_END() +}; + +static const DrawTileSprites _crossing_layout_SW = { + {0, PAL_NONE}, _crossing_layout_SW_ALL +}; + +static const DrawTileSeqStruct _crossing_layout_NW_ALL[] = { + TILE_SEQ_LINE(2, PAL_NONE, 0, 0, 3, 3) + TILE_SEQ_LINE(6, PAL_NONE, 13, 0, 3, 3) + TILE_SEQ_END() +}; + +static const DrawTileSprites _crossing_layout_NW = { + {0, PAL_NONE}, _crossing_layout_NW_ALL +}; + +static const DrawTileSeqStruct _crossing_layout_NE_ALL[] = { + TILE_SEQ_LINE(2, PAL_NONE, 0, 0, 3, 3) + TILE_SEQ_LINE(4, PAL_NONE, 0, 13, 3, 3) + TILE_SEQ_END() +}; + +static const DrawTileSprites _crossing_layout_NE = { + {0, PAL_NONE}, _crossing_layout_NE_ALL +}; + +static const DrawTileSeqStruct _crossing_layout_SE_ALL[] = { + TILE_SEQ_LINE(4, PAL_NONE, 0, 13, 3, 3) + TILE_SEQ_LINE(8, PAL_NONE, 13, 13, 3, 3) + TILE_SEQ_END() +}; + +static const DrawTileSprites _crossing_layout_SE = { + {0, PAL_NONE}, _crossing_layout_SE_ALL +}; + #undef TILE_SEQ_LINE #undef TILE_SEQ_END diff --git a/src/table/settings.h.preamble b/src/table/settings.h.preamble index dca29cf88c47b..dd978727ed2c2 100644 --- a/src/table/settings.h.preamble +++ b/src/table/settings.h.preamble @@ -79,6 +79,9 @@ static size_t ConvertLandscape(const char *value); #define SDT_VAR(base, var, type, flags, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, cat, extra, startup)\ NSD(Int, SLE_GENERAL(SL_VAR, base, var, type, 1, from, to, extra), flags, startup, def, min, max, interval, str, strhelp, strval, cat, pre_check, post_callback) +#define SDT_VAR_NAME(base, var, type, flags, def, min, max, interval, str, strhelp, strval, pre_check, post_callback, from, to, cat, extra, startup, name)\ + NSD(Int, SLE_GENERAL_NAME(SL_VAR, name, base, var, type, 1, from, to, extra), flags, startup, def, min, max, interval, str, strhelp, strval, cat, pre_check, post_callback) + #define SDT_BOOL(base, var, flags, def, str, strhelp, strval, pre_check, post_callback, from, to, cat, extra, startup)\ NSD(Bool, SLE_GENERAL(SL_VAR, base, var, SLE_BOOL, 1, from, to, extra), flags, startup, def, str, strhelp, strval, cat, pre_check, post_callback) diff --git a/src/table/settings/company_settings.ini b/src/table/settings/company_settings.ini index 52920e6e6dc9d..ef299e1e22697 100644 --- a/src/table/settings/company_settings.ini +++ b/src/table/settings/company_settings.ini @@ -89,7 +89,7 @@ max = 800 str = STR_CONFIG_SETTING_SERVINT_TRAINS strhelp = STR_CONFIG_SETTING_SERVINT_TRAINS_HELPTEXT strval = STR_CONFIG_SETTING_SERVINT_VALUE -pre_cb = [](auto new_value) { return CanUpdateServiceInterval(VEH_TRAIN, new_value); } +pre_cb = [](auto &new_value) { return CanUpdateServiceInterval(VEH_TRAIN, new_value); } post_cb = [](auto new_value) { UpdateServiceInterval(VEH_TRAIN, new_value); } [SDT_VAR] @@ -102,7 +102,7 @@ max = 800 str = STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES strhelp = STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES_HELPTEXT strval = STR_CONFIG_SETTING_SERVINT_VALUE -pre_cb = [](auto new_value) { return CanUpdateServiceInterval(VEH_ROAD, new_value); } +pre_cb = [](auto &new_value) { return CanUpdateServiceInterval(VEH_ROAD, new_value); } post_cb = [](auto new_value) { UpdateServiceInterval(VEH_ROAD, new_value); } [SDT_VAR] @@ -115,7 +115,7 @@ max = 800 str = STR_CONFIG_SETTING_SERVINT_SHIPS strhelp = STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT strval = STR_CONFIG_SETTING_SERVINT_VALUE -pre_cb = [](auto new_value) { return CanUpdateServiceInterval(VEH_SHIP, new_value); } +pre_cb = [](auto &new_value) { return CanUpdateServiceInterval(VEH_SHIP, new_value); } post_cb = [](auto new_value) { UpdateServiceInterval(VEH_SHIP, new_value); } [SDT_VAR] @@ -128,5 +128,5 @@ max = 800 str = STR_CONFIG_SETTING_SERVINT_AIRCRAFT strhelp = STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT strval = STR_CONFIG_SETTING_SERVINT_VALUE -pre_cb = [](auto new_value) { return CanUpdateServiceInterval(VEH_AIRCRAFT, new_value); } +pre_cb = [](auto &new_value) { return CanUpdateServiceInterval(VEH_AIRCRAFT, new_value); } post_cb = [](auto new_value) { UpdateServiceInterval(VEH_AIRCRAFT, new_value); } diff --git a/src/table/settings/difficulty_settings.ini b/src/table/settings/difficulty_settings.ini index de1b54955cb90..2ada1de992173 100644 --- a/src/table/settings/difficulty_settings.ini +++ b/src/table/settings/difficulty_settings.ini @@ -83,7 +83,7 @@ var = difficulty.industry_density type = SLE_UINT8 from = SLV_97 flags = SF_GUI_DROPDOWN -def = ID_END - 1 +def = ID_NORMAL min = 0 max = ID_END - 1 interval = 1 @@ -96,14 +96,15 @@ cat = SC_BASIC var = difficulty.max_loan type = SLE_UINT32 from = SLV_97 -flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO | SF_GUI_CURRENCY +flags = SF_NEWGAME_ONLY | SF_SCENEDIT_TOO | SF_GUI_CURRENCY | SF_GUI_0_IS_SPECIAL def = 300000 -min = 0 +min = VANILLA_LOAN_INTERVAL max = 2000000000 -interval = 50000 +pre_cb = [](auto &new_value) { new_value = (new_value + VANILLA_LOAN_INTERVAL / 2) / VANILLA_LOAN_INTERVAL * VANILLA_LOAN_INTERVAL; return true; } +interval = VANILLA_LOAN_INTERVAL str = STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN strhelp = STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT -strval = STR_JUST_CURRENCY_LONG +strval = STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_VALUE cat = SC_BASIC [SDT_VAR] diff --git a/src/table/settings/economy_settings.ini b/src/table/settings/economy_settings.ini index 0101e1bf98fd4..ad2a74319dac2 100644 --- a/src/table/settings/economy_settings.ini +++ b/src/table/settings/economy_settings.ini @@ -123,7 +123,7 @@ var = economy.bribe def = true str = STR_CONFIG_SETTING_BRIBE strhelp = STR_CONFIG_SETTING_BRIBE_HELPTEXT -post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } +post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_AUTHORITY); } cat = SC_BASIC [SDT_BOOL] @@ -132,7 +132,7 @@ from = SLV_79 def = true str = STR_CONFIG_SETTING_ALLOW_EXCLUSIVE strhelp = STR_CONFIG_SETTING_ALLOW_EXCLUSIVE_HELPTEXT -post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } +post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_AUTHORITY); } cat = SC_BASIC [SDT_BOOL] @@ -141,7 +141,7 @@ from = SLV_165 def = true str = STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS strhelp = STR_CONFIG_SETTING_ALLOW_FUND_BUILDINGS_HELPTEXT -post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } +post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_AUTHORITY); } cat = SC_BASIC [SDT_BOOL] @@ -150,7 +150,7 @@ from = SLV_160 def = true str = STR_CONFIG_SETTING_ALLOW_FUND_ROAD strhelp = STR_CONFIG_SETTING_ALLOW_FUND_ROAD_HELPTEXT -post_cb = [](auto) { SetWindowClassesDirty(WC_TOWN_AUTHORITY); } +post_cb = [](auto) { InvalidateWindowClassesData(WC_TOWN_AUTHORITY); } cat = SC_BASIC [SDT_BOOL] diff --git a/src/table/settings/game_settings.ini b/src/table/settings/game_settings.ini index c35cbe6e04531..eece3fbbed349 100644 --- a/src/table/settings/game_settings.ini +++ b/src/table/settings/game_settings.ini @@ -170,7 +170,7 @@ max = 1 full = _roadsides str = STR_CONFIG_SETTING_ROAD_SIDE strhelp = STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT -strval = STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT +strval = STR_CONFIG_SETTING_ROAD_SIDE_LEFT pre_cb = CheckRoadSide cat = SC_BASIC diff --git a/src/table/settings/gui_settings.ini b/src/table/settings/gui_settings.ini index cf4ef71ababa0..7abeed98090cb 100644 --- a/src/table/settings/gui_settings.ini +++ b/src/table/settings/gui_settings.ini @@ -728,6 +728,15 @@ strhelp = STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT post_cb = [](auto) { MarkWholeScreenDirty(); } cat = SC_ADVANCED +[SDTC_BOOL] +var = gui.show_cargo_in_vehicle_lists +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = false +str = STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS +strhelp = STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT +post_cb = [](auto) { MarkWholeScreenDirty(); } +cat = SC_ADVANCED + ; For the dedicated build we'll enable dates in logs by default. [SDTC_BOOL] ifdef = DEDICATED @@ -770,7 +779,7 @@ cat = SC_EXPERT var = gui.ai_developer_tools flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC def = false -post_cb = [](auto) { InvalidateWindowClassesData(WC_AI_SETTINGS); } +post_cb = [](auto) { InvalidateWindowClassesData(WC_SCRIPT_SETTINGS); } cat = SC_EXPERT [SDTC_BOOL] @@ -861,3 +870,11 @@ min = 1 max = 65535 cat = SC_EXPERT +[SDTC_BOOL] +var = gui.scale_bevels +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC +def = true +post_cb = [](auto) { SetupWidgetDimensions(); ReInitAllWindows(true); } +cat = SC_BASIC +startup = true + diff --git a/src/table/settings/misc_settings.ini b/src/table/settings/misc_settings.ini index 5d585496de103..dd3a58e24e604 100644 --- a/src/table/settings/misc_settings.ini +++ b/src/table/settings/misc_settings.ini @@ -181,35 +181,35 @@ def = false ifdef = HAS_TRUETYPE_FONT name = ""small_font"" type = SLE_STR -var = _freetype.small.font +var = _fcsettings.small.font def = nullptr [SDTG_SSTR] ifdef = HAS_TRUETYPE_FONT name = ""medium_font"" type = SLE_STR -var = _freetype.medium.font +var = _fcsettings.medium.font def = nullptr [SDTG_SSTR] ifdef = HAS_TRUETYPE_FONT name = ""large_font"" type = SLE_STR -var = _freetype.large.font +var = _fcsettings.large.font def = nullptr [SDTG_SSTR] ifdef = HAS_TRUETYPE_FONT name = ""mono_font"" type = SLE_STR -var = _freetype.mono.font +var = _fcsettings.mono.font def = nullptr [SDTG_VAR] ifdef = HAS_TRUETYPE_FONT name = ""small_size"" type = SLE_UINT -var = _freetype.small.size +var = _fcsettings.small.size def = 0 min = 0 max = 72 @@ -218,7 +218,7 @@ max = 72 ifdef = HAS_TRUETYPE_FONT name = ""medium_size"" type = SLE_UINT -var = _freetype.medium.size +var = _fcsettings.medium.size def = 0 min = 0 max = 72 @@ -227,7 +227,7 @@ max = 72 ifdef = HAS_TRUETYPE_FONT name = ""large_size"" type = SLE_UINT -var = _freetype.large.size +var = _fcsettings.large.size def = 0 min = 0 max = 72 @@ -236,7 +236,7 @@ max = 72 ifdef = HAS_TRUETYPE_FONT name = ""mono_size"" type = SLE_UINT -var = _freetype.mono.size +var = _fcsettings.mono.size def = 0 min = 0 max = 72 @@ -244,25 +244,25 @@ max = 72 [SDTG_BOOL] ifdef = HAS_TRUETYPE_FONT name = ""small_aa"" -var = _freetype.small.aa +var = _fcsettings.small.aa def = false [SDTG_BOOL] ifdef = HAS_TRUETYPE_FONT name = ""medium_aa"" -var = _freetype.medium.aa +var = _fcsettings.medium.aa def = false [SDTG_BOOL] ifdef = HAS_TRUETYPE_FONT name = ""large_aa"" -var = _freetype.large.aa +var = _fcsettings.large.aa def = false [SDTG_BOOL] ifdef = HAS_TRUETYPE_FONT name = ""mono_aa"" -var = _freetype.mono.aa +var = _fcsettings.mono.aa def = false [SDTG_VAR] @@ -334,21 +334,12 @@ max = UINT32_MAX cat = SC_EXPERT [SDTG_VAR] -name = ""gui_zoom"" -type = SLE_INT8 -var = _gui_zoom_cfg -def = ZOOM_LVL_CFG_AUTO -min = ZOOM_LVL_CFG_AUTO -max = ZOOM_LVL_OUT_4X -cat = SC_BASIC - -[SDTG_VAR] -name = ""font_zoom"" -type = SLE_INT8 -var = _font_zoom_cfg -def = ZOOM_LVL_CFG_AUTO -min = ZOOM_LVL_CFG_AUTO -max = ZOOM_LVL_OUT_4X +name = ""gui_scale"" +type = SLE_INT32 +var = _gui_scale_cfg +def = -1 +min = -1 +max = MAX_INTERFACE_SCALE cat = SC_BASIC [SDTG_BOOL] diff --git a/src/table/settings/world_settings.ini b/src/table/settings/world_settings.ini index 5912f89f4cac6..d5fafd9d83236 100644 --- a/src/table/settings/world_settings.ini +++ b/src/table/settings/world_settings.ini @@ -65,7 +65,7 @@ full = _climates load = ConvertLandscape str = STR_CONFIG_SETTING_LANDSCAPE strhelp = STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT -strval = STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE +strval = STR_CLIMATE_TEMPERATE_LANDSCAPE cat = SC_BASIC [SDT_VAR] @@ -271,6 +271,13 @@ min = 1 max = 5000 cat = SC_BASIC +[SDT_VAR] +var = game_creation.custom_industry_number +type = SLE_UINT16 +def = 1 +min = 1 +max = 64000 + [SDT_VAR] var = game_creation.custom_terrain_type type = SLE_UINT8 @@ -415,6 +422,24 @@ max = 1 << 15 interval = 1 cat = SC_EXPERT +[SDT_VAR] +var = construction.build_object_per_64k_frames +type = SLE_UINT32 +def = 32 << 16 +min = 0 +max = 1 << 30 +interval = 1 +cat = SC_EXPERT + +[SDT_VAR] +var = construction.build_object_frame_burst +type = SLE_UINT16 +def = 2048 +min = 0 +max = 1 << 15 +interval = 1 +cat = SC_EXPERT + [SDT_BOOL] var = construction.autoslope from = SLV_75 diff --git a/src/table/sprites.h b/src/table/sprites.h index b7bb91020334a..907d37fdccb34 100644 --- a/src/table/sprites.h +++ b/src/table/sprites.h @@ -290,15 +290,13 @@ static const SpriteID SPR_TRAMWAY_DEPOT_NO_TRACK = SPR_TRAMWAY_BASE + 113; static const uint16 TRAMWAY_SPRITE_COUNT = 119; /** One way road sprites */ -static const SpriteID SPR_ONEWAY_BASE = SPR_TRAMWAY_BASE + TRAMWAY_SPRITE_COUNT; -static const uint16 ONEWAY_SPRITE_COUNT = 6; - -/** Flags sprites (in same order as enum NetworkLanguage) */ -static const SpriteID SPR_FLAGS_BASE = SPR_ONEWAY_BASE + ONEWAY_SPRITE_COUNT; -static const uint16 FLAGS_SPRITE_COUNT = 36; +static const SpriteID SPR_ONEWAY_BASE = SPR_TRAMWAY_BASE + TRAMWAY_SPRITE_COUNT; +static const SpriteID SPR_ONEWAY_SLOPE_N_OFFSET = 6; +static const SpriteID SPR_ONEWAY_SLOPE_S_OFFSET = 12; +static const uint16 ONEWAY_SPRITE_COUNT = 18; /** Tunnel sprites with grass only for custom railtype tunnel. */ -static const SpriteID SPR_RAILTYPE_TUNNEL_BASE = SPR_FLAGS_BASE + FLAGS_SPRITE_COUNT; +static const SpriteID SPR_RAILTYPE_TUNNEL_BASE = SPR_ONEWAY_BASE + ONEWAY_SPRITE_COUNT; static const uint16 RAILTYPE_TUNNEL_BASE_COUNT = 16; /* Not really a sprite, but an empty bounding box. Used to construct bounding boxes that help sorting the sprites, but do not have a sprite associated. */ @@ -1128,6 +1126,10 @@ static const SpriteID SPR_OTTD_N = 4839; static const SpriteID SPR_OTTD_T = 4836; /* Letters not used: R,A,S,Y,C (4837, 4838, 4840, 4843, 4844) */ +/* Range of "special" sprites that are used by the old map generation algorithm. */ +static const SpriteID SPR_MAPGEN_BEGIN = 4845; +static const SpriteID SPR_MAPGEN_END = 4882; + static const SpriteID SPR_HIGHSCORE_CHART_BEGIN = 4804; static const SpriteID SPR_TYCOON_IMG1_BEGIN = 4814; static const SpriteID SPR_TYCOON_IMG2_BEGIN = 4824; @@ -1546,18 +1548,18 @@ enum Modifiers { * @see SpriteSetup */ enum SpriteMasks { - MAX_SPRITES = 1 << SPRITE_WIDTH, ///< Maximum number of sprites that can be loaded at a given time + MAX_SPRITES = 1U << SPRITE_WIDTH, ///< Maximum number of sprites that can be loaded at a given time SPRITE_MASK = MAX_SPRITES - 1, ///< The mask to for the main sprite - MAX_PALETTES = 1 << PALETTE_WIDTH, + MAX_PALETTES = 1U << PALETTE_WIDTH, PALETTE_MASK = MAX_PALETTES - 1, ///< The mask for the auxiliary sprite (the one that takes care of recolouring) }; -static_assert( (1 << TRANSPARENT_BIT & SPRITE_MASK) == 0 ); -static_assert( (1 << RECOLOUR_BIT & SPRITE_MASK) == 0 ); +static_assert( (1U << TRANSPARENT_BIT & SPRITE_MASK) == 0 ); +static_assert( (1U << RECOLOUR_BIT & SPRITE_MASK) == 0 ); static_assert( TRANSPARENT_BIT != RECOLOUR_BIT ); -static_assert( (1 << TRANSPARENT_BIT & PALETTE_MASK) == 0); -static_assert( (1 << RECOLOUR_BIT & PALETTE_MASK) == 0 ); +static_assert( (1U << TRANSPARENT_BIT & PALETTE_MASK) == 0 ); +static_assert( (1U << RECOLOUR_BIT & PALETTE_MASK) == 0 ); static const PaletteID PAL_NONE = 0; diff --git a/src/table/strgen_tables.h b/src/table/strgen_tables.h index d5e9f4b3e998b..65ca77f0779a0 100644 --- a/src/table/strgen_tables.h +++ b/src/table/strgen_tables.h @@ -78,6 +78,7 @@ static const CmdStruct _cmd_structs[] = { {"CARGO_TINY", EmitSingleChar, SCC_CARGO_TINY, 2, 1, C_NONE}, // tiny cargo description with only the amount, not a specifier for the amount or the actual cargo name {"CARGO_LIST", EmitSingleChar, SCC_CARGO_LIST, 1, -1, C_CASE}, {"POWER", EmitSingleChar, SCC_POWER, 1, 0, C_NONE}, + {"POWER_TO_WEIGHT", EmitSingleChar, SCC_POWER_TO_WEIGHT, 1, 0, C_NONE}, {"VOLUME_LONG", EmitSingleChar, SCC_VOLUME_LONG, 1, 0, C_NONE}, {"VOLUME_SHORT", EmitSingleChar, SCC_VOLUME_SHORT, 1, 0, C_NONE}, {"WEIGHT_LONG", EmitSingleChar, SCC_WEIGHT_LONG, 1, 0, C_NONE}, diff --git a/src/table/unicode.h b/src/table/unicode.h index 882fcb569600d..5e142a88f772c 100644 --- a/src/table/unicode.h +++ b/src/table/unicode.h @@ -17,7 +17,7 @@ static const byte CLRA = 0; ///< Identifier to clear all glyphs at this codepoin /* Default unicode mapping table for sprite based glyphs. * This table allows us use unicode characters even though the glyphs don't * exist, or are in the wrong place, in the standard sprite fonts. - * This is not used for FreeType rendering */ + * This is not used for TrueType rendering */ static const DefaultUnicodeMapping _default_unicode_map[] = { { 0x00A0, 0x20 }, // Non-breaking space / Up arrow diff --git a/src/terraform_cmd.cpp b/src/terraform_cmd.cpp index 21df5ccbe3f6a..742e8e201c276 100644 --- a/src/terraform_cmd.cpp +++ b/src/terraform_cmd.cpp @@ -84,7 +84,7 @@ static void TerraformAddDirtyTile(TerraformerState *ts, TileIndex tile) */ static void TerraformAddDirtyTileAround(TerraformerState *ts, TileIndex tile) { - /* Make sure all tiles passed to TerraformAddDirtyTile are within [0, MapSize()] */ + /* Make sure all tiles passed to TerraformAddDirtyTile are within [0, Map::Size()] */ if (TileY(tile) >= 1) TerraformAddDirtyTile(ts, tile + TileDiffXY( 0, -1)); if (TileY(tile) >= 1 && TileX(tile) >= 1) TerraformAddDirtyTile(ts, tile + TileDiffXY(-1, -1)); if (TileX(tile) >= 1) TerraformAddDirtyTile(ts, tile + TileDiffXY(-1, 0)); @@ -101,7 +101,7 @@ static void TerraformAddDirtyTileAround(TerraformerState *ts, TileIndex tile) */ static std::tuple TerraformTileHeight(TerraformerState *ts, TileIndex tile, int height) { - assert(tile < MapSize()); + assert(tile < Map::Size()); /* Check range of destination height */ if (height < 0) return { CommandCost(STR_ERROR_ALREADY_AT_SEA_LEVEL), INVALID_TILE }; @@ -117,7 +117,7 @@ static std::tuple TerraformTileHeight(TerraformerState * /* Check "too close to edge of map". Only possible when freeform-edges is off. */ uint x = TileX(tile); uint y = TileY(tile); - if (!_settings_game.construction.freeform_edges && ((x <= 1) || (y <= 1) || (x >= MapMaxX() - 1) || (y >= MapMaxY() - 1))) { + if (!_settings_game.construction.freeform_edges && ((x <= 1) || (y <= 1) || (x >= Map::MaxX() - 1) || (y >= Map::MaxY() - 1))) { /* * Determine a sensible error tile */ @@ -152,10 +152,10 @@ static std::tuple TerraformTileHeight(TerraformerState * for (ttm = _terraform_tilepos; ttm != endof(_terraform_tilepos); ttm++) { tile += ToTileIndexDiff(*ttm); - if (tile >= MapSize()) continue; + if (tile >= Map::Size()) continue; /* Make sure we don't wrap around the map */ - if (Delta(TileX(orig_tile), TileX(tile)) == MapSizeX() - 1) continue; - if (Delta(TileY(orig_tile), TileY(tile)) == MapSizeY() - 1) continue; + if (Delta(TileX(orig_tile), TileX(tile)) == Map::SizeX() - 1) continue; + if (Delta(TileY(orig_tile), TileY(tile)) == Map::SizeY() - 1) continue; /* Get TileHeight of neighboured tile as of current terraform progress */ int r = TerraformGetHeightOfTile(ts, tile); @@ -190,21 +190,21 @@ std::tuple CmdTerraformLand(DoCommandFlag flags, TerraformerState ts; /* Compute the costs and the terraforming result in a model of the landscape */ - if ((slope & SLOPE_W) != 0 && tile + TileDiffXY(1, 0) < MapSize()) { + if ((slope & SLOPE_W) != 0 && tile + TileDiffXY(1, 0) < Map::Size()) { TileIndex t = tile + TileDiffXY(1, 0); auto [cost, err_tile] = TerraformTileHeight(&ts, t, TileHeight(t) + direction); if (cost.Failed()) return { cost, 0, err_tile }; total_cost.AddCost(cost); } - if ((slope & SLOPE_S) != 0 && tile + TileDiffXY(1, 1) < MapSize()) { + if ((slope & SLOPE_S) != 0 && tile + TileDiffXY(1, 1) < Map::Size()) { TileIndex t = tile + TileDiffXY(1, 1); auto [cost, err_tile] = TerraformTileHeight(&ts, t, TileHeight(t) + direction); if (cost.Failed()) return { cost, 0, err_tile }; total_cost.AddCost(cost); } - if ((slope & SLOPE_E) != 0 && tile + TileDiffXY(0, 1) < MapSize()) { + if ((slope & SLOPE_E) != 0 && tile + TileDiffXY(0, 1) < Map::Size()) { TileIndex t = tile + TileDiffXY(0, 1); auto [cost, err_tile] = TerraformTileHeight(&ts, t, TileHeight(t) + direction); if (cost.Failed()) return { cost, 0, err_tile }; @@ -225,7 +225,7 @@ std::tuple CmdTerraformLand(DoCommandFlag flags, for (TileIndexSet::const_iterator it = ts.dirty_tiles.begin(); it != ts.dirty_tiles.end(); it++) { TileIndex t = *it; - assert(t < MapSize()); + assert(t < Map::Size()); /* MP_VOID tiles can be terraformed but as tunnels and bridges * cannot go under / over these tiles they don't need checking. */ if (IsTileType(t, MP_VOID)) continue; @@ -334,7 +334,7 @@ std::tuple CmdTerraformLand(DoCommandFlag flags, */ std::tuple CmdLevelLand(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, bool diagonal, LevelMode lm) { - if (start_tile >= MapSize()) return { CMD_ERROR, 0, INVALID_TILE }; + if (start_tile >= Map::Size()) return { CMD_ERROR, 0, INVALID_TILE }; /* remember level height */ uint oldh = TileHeight(start_tile); @@ -361,7 +361,7 @@ std::tuple CmdLevelLand(DoCommandFlag flags, Tile if (limit == 0) return { CommandCost(STR_ERROR_TERRAFORM_LIMIT_REACHED), 0, INVALID_TILE }; TileIndex error_tile = INVALID_TILE; - TileIterator *iter = diagonal ? (TileIterator *)new DiagonalTileIterator(tile, start_tile) : new OrthogonalTileIterator(tile, start_tile); + std::unique_ptr iter = TileIterator::Create(tile, start_tile, diagonal); for (; *iter != INVALID_TILE; ++(*iter)) { TileIndex t = *iter; uint curh = TileHeight(t); @@ -379,7 +379,6 @@ std::tuple CmdLevelLand(DoCommandFlag flags, Tile if (flags & DC_EXEC) { money -= ret.GetCost(); if (money < 0) { - delete iter; return { cost, ret.GetCost(), error_tile }; } Command::Do(flags, t, SLOPE_N, curh <= h); @@ -403,7 +402,6 @@ std::tuple CmdLevelLand(DoCommandFlag flags, Tile if (limit <= 0) break; } - delete iter; CommandCost cc_ret = had_success ? cost : last_error; return { cc_ret, 0, cc_ret.Succeeded() ? tile : error_tile }; } diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 260234efc8a2e..2429814518d9c 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -113,8 +113,8 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t if (!_settings_game.construction.freeform_edges) { /* When end_tile is MP_VOID, the error tile will not be visible to the * user. This happens when terraforming at the southern border. */ - if (TileX(end_tile) == MapMaxX()) end_tile += TileDiffXY(-1, 0); - if (TileY(end_tile) == MapMaxY()) end_tile += TileDiffXY(0, -1); + if (TileX(end_tile) == Map::MaxX()) end_tile += TileDiffXY(-1, 0); + if (TileY(end_tile) == Map::MaxY()) end_tile += TileDiffXY(0, -1); } switch (proc) { @@ -201,7 +201,7 @@ struct TerraformToolbarWindow : Window { break; case WID_TT_BUY_LAND: // Buy land button - HandlePlacePushButton(this, WID_TT_BUY_LAND, SPR_CURSOR_BUY_LAND, HT_RECT); + HandlePlacePushButton(this, WID_TT_BUY_LAND, SPR_CURSOR_BUY_LAND, HT_RECT | HT_DIAGONAL); this->last_user_action = widget; break; @@ -242,7 +242,7 @@ struct TerraformToolbarWindow : Window { break; case WID_TT_BUY_LAND: // Buy land button - Command::Post(STR_ERROR_CAN_T_PURCHASE_THIS_LAND, CcPlaySound_CONSTRUCTION_RAIL, tile, OBJECT_OWNED_LAND, 0); + VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_BUILD_OBJECT); break; case WID_TT_PLACE_SIGN: // Place sign button @@ -276,6 +276,16 @@ struct TerraformToolbarWindow : Window { case DDSP_LEVEL_AREA: GUIPlaceProcDragXY(select_proc, start_tile, end_tile); break; + case DDSP_BUILD_OBJECT: + if (!_settings_game.construction.freeform_edges) { + /* When end_tile is MP_VOID, the error tile will not be visible to the + * user. This happens when terraforming at the southern border. */ + if (TileX(end_tile) == Map::MaxX()) end_tile += TileDiffXY(-1, 0); + if (TileY(end_tile) == Map::MaxY()) end_tile += TileDiffXY(0, -1); + } + Command::Post(STR_ERROR_CAN_T_PURCHASE_THIS_LAND, CcPlaySound_CONSTRUCTION_RAIL, + end_tile, start_tile, OBJECT_OWNED_LAND, 0, (_ctrl_pressed ? true : false)); + break; } } } diff --git a/src/textbuf.cpp b/src/textbuf.cpp index 75e1f44848421..30cef7b0cead7 100644 --- a/src/textbuf.cpp +++ b/src/textbuf.cpp @@ -369,13 +369,11 @@ bool Textbuf::MovePos(uint16 keycode) * @param max_chars maximum size in chars, including terminating '\0' */ Textbuf::Textbuf(uint16 max_bytes, uint16 max_chars) - : buf(MallocT(max_bytes)) + : buf(MallocT(max_bytes)), char_iter(StringIterator::Create()) { assert(max_bytes != 0); assert(max_chars != 0); - this->char_iter = StringIterator::Create(); - this->afilter = CS_ALPHANUMERAL; this->max_bytes = max_bytes; this->max_chars = max_chars == UINT16_MAX ? max_bytes : max_chars; @@ -385,7 +383,6 @@ Textbuf::Textbuf(uint16 max_bytes, uint16 max_chars) Textbuf::~Textbuf() { - delete this->char_iter; free(this->buf); } diff --git a/src/textbuf_type.h b/src/textbuf_type.h index b4f234f737659..14e92cbb3de85 100644 --- a/src/textbuf_type.h +++ b/src/textbuf_type.h @@ -67,7 +67,7 @@ struct Textbuf { void DiscardMarkedText(bool update = true); private: - StringIterator *char_iter; + std::unique_ptr char_iter; bool CanDelChar(bool backspace); diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp index e9223af70ab2d..021d7326d54cd 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.cpp @@ -8,6 +8,7 @@ /** @file textfile_gui.cpp Implementation of textfile window. */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "fileio_func.h" #include "fontcache.h" #include "gfx_type.h" @@ -88,7 +89,7 @@ uint TextfileWindow::ReflowContent() line.bottom = height; } } else { - int max_width = this->GetWidget(WID_TF_BACKGROUND)->current_x - WD_FRAMETEXT_LEFT - WD_FRAMERECT_RIGHT; + int max_width = this->GetWidget(WID_TF_BACKGROUND)->current_x - WidgetDimensions::scaled.frametext.Horizontal(); for (auto &line : this->lines) { line.top = height; height += GetStringHeight(line.text, max_width, FS_MONO) / FONT_HEIGHT_MONO; @@ -111,7 +112,7 @@ uint TextfileWindow::GetContentHeight() case WID_TF_BACKGROUND: resize->height = FONT_HEIGHT_MONO; - size->height = 4 * resize->height + TOP_SPACING + BOTTOM_SPACING; // At least 4 lines are visible. + size->height = 4 * resize->height + WidgetDimensions::scaled.frametext.Vertical(); // At least 4 lines are visible. size->width = std::max(200u, size->width); // At least 200 pixels wide. break; } @@ -128,7 +129,7 @@ void TextfileWindow::SetupScrollbars(bool force_reflow) } else { uint height = force_reflow ? this->ReflowContent() : this->GetContentHeight(); this->vscroll->SetCount(std::min(UINT16_MAX, height)); - this->hscroll->SetCount(this->max_length + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT); + this->hscroll->SetCount(this->max_length + WidgetDimensions::scaled.frametext.Horizontal()); } this->SetWidgetDisabledState(WID_TF_HSCROLLBAR, IsWidgetLowered(WID_TF_WRAPTEXT)); @@ -148,17 +149,14 @@ void TextfileWindow::SetupScrollbars(bool force_reflow) { if (widget != WID_TF_BACKGROUND) return; - const int x = r.left + WD_FRAMETEXT_LEFT; - const int y = r.top + WD_FRAMETEXT_TOP; - const int right = r.right - WD_FRAMETEXT_RIGHT; - const int bottom = r.bottom - WD_FRAMETEXT_BOTTOM; + Rect fr = r.Shrink(WidgetDimensions::scaled.frametext); DrawPixelInfo new_dpi; - if (!FillDrawPixelInfo(&new_dpi, x, y, right - x + 1, bottom - y + 1)) return; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &new_dpi; + if (!FillDrawPixelInfo(&new_dpi, fr.left, fr.top, fr.Width(), fr.Height())) return; + AutoRestoreBackup dpi_backup(_cur_dpi, &new_dpi); /* Draw content (now coordinates given to DrawString* are local to the new clipping region). */ + fr = fr.Translate(-fr.left, -fr.top); int line_height = FONT_HEIGHT_MONO; int pos = this->vscroll->GetPosition(); int cap = this->vscroll->GetCapacity(); @@ -169,18 +167,16 @@ void TextfileWindow::SetupScrollbars(bool force_reflow) int y_offset = (line.top - pos) * line_height; if (IsWidgetLowered(WID_TF_WRAPTEXT)) { - DrawStringMultiLine(0, right - x, y_offset, bottom - y, line.text, TC_WHITE, SA_TOP | SA_LEFT, false, FS_MONO); + DrawStringMultiLine(0, fr.right, y_offset, fr.bottom, line.text, TC_BLACK, SA_TOP | SA_LEFT, false, FS_MONO); } else { - DrawString(-this->hscroll->GetPosition(), right - x, y_offset, line.text, TC_WHITE, SA_TOP | SA_LEFT, false, FS_MONO); + DrawString(-this->hscroll->GetPosition(), fr.right, y_offset, line.text, TC_BLACK, SA_TOP | SA_LEFT, false, FS_MONO); } } - - _cur_dpi = old_dpi; } /* virtual */ void TextfileWindow::OnResize() { - this->vscroll->SetCapacityFromWidget(this, WID_TF_BACKGROUND, TOP_SPACING + BOTTOM_SPACING); + this->vscroll->SetCapacityFromWidget(this, WID_TF_BACKGROUND, WidgetDimensions::scaled.frametext.Vertical()); this->hscroll->SetCapacityFromWidget(this, WID_TF_BACKGROUND); this->SetupScrollbars(false); @@ -215,7 +211,7 @@ void TextfileWindow::SetupScrollbars(bool force_reflow) return true; } -/* virtual */ void TextfileWindow::SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data) +/* virtual */ void TextfileWindow::SetFontNames(FontCacheSettings *settings, const char *font_name, const void *os_data) { #if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) settings->mono.font = font_name; diff --git a/src/textfile_gui.h b/src/textfile_gui.h index 5f1db14ca9cfb..cdcae738882d0 100644 --- a/src/textfile_gui.h +++ b/src/textfile_gui.h @@ -36,9 +36,6 @@ struct TextfileWindow : public Window, MissingGlyphSearcher { uint max_length; ///< Maximum length of unwrapped text line. - static const int TOP_SPACING = WD_FRAMETEXT_TOP; ///< Additional spacing at the top of the #WID_TF_BACKGROUND widget. - static const int BOTTOM_SPACING = WD_FRAMETEXT_BOTTOM; ///< Additional spacing at the bottom of the #WID_TF_BACKGROUND widget. - TextfileWindow(TextfileType file_type); ~TextfileWindow(); @@ -52,7 +49,7 @@ struct TextfileWindow : public Window, MissingGlyphSearcher { FontSize DefaultSize() override; const char *NextString() override; bool Monospace() override; - void SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data) override; + void SetFontNames(FontCacheSettings *settings, const char *font_name, const void *os_data) override; virtual void LoadTextfile(const char *textfile, Subdirectory dir); diff --git a/src/tgp.cpp b/src/tgp.cpp index 511b998e23a3a..8608febfd591b 100644 --- a/src/tgp.cpp +++ b/src/tgp.cpp @@ -164,9 +164,9 @@ struct HeightMap std::vector h; //< array of heights /* Even though the sizes are always positive, there are many cases where * X and Y need to be signed integers due to subtractions. */ - int dim_x; //< height map size_x MapSizeX() + 1 - int size_x; //< MapSizeX() - int size_y; //< MapSizeY() + int dim_x; //< height map size_x Map::SizeX() + 1 + int size_x; //< Map::SizeX() + int size_y; //< Map::SizeY() /** * Height map accessor @@ -220,7 +220,7 @@ static height_t TGPGetMaxHeight() /** * Desired maximum height - indexed by: * - _settings_game.difficulty.terrain_type - * - min(MapLogX(), MapLogY()) - MIN_MAP_SIZE_BITS + * - min(Map::LogX(), Map::LogY()) - MIN_MAP_SIZE_BITS * * It is indexed by map size as well as terrain type since the map size limits the height of * a usable mountain. For example, on a 64x64 map a 24 high single peak mountain (as if you @@ -236,7 +236,7 @@ static height_t TGPGetMaxHeight() { 12, 19, 25, 31, 67, 75, 87 }, ///< Alpinist }; - int map_size_bucket = std::min(MapLogX(), MapLogY()) - MIN_MAP_SIZE_BITS; + int map_size_bucket = std::min(Map::LogX(), Map::LogY()) - MIN_MAP_SIZE_BITS; int max_height_from_table = max_height[_settings_game.difficulty.terrain_type][map_size_bucket]; /* If there is a manual map height limit, clamp to it. */ @@ -322,11 +322,11 @@ static inline bool AllocHeightMap() { assert(_height_map.h.empty()); - _height_map.size_x = MapSizeX(); - _height_map.size_y = MapSizeY(); + _height_map.size_x = Map::SizeX(); + _height_map.size_y = Map::SizeY(); /* Allocate memory block for height map row pointers */ - size_t total_size = (_height_map.size_x + 1) * (_height_map.size_y + 1); + size_t total_size = static_cast(_height_map.size_x + 1) * (_height_map.size_y + 1); _height_map.dim_x = _height_map.size_x + 1; _height_map.h.resize(total_size); @@ -362,7 +362,7 @@ static void HeightMapGenerate() /* Trying to apply noise to uninitialized height map */ assert(!_height_map.h.empty()); - int start = std::max(MAX_TGP_FREQUENCIES - (int)std::min(MapLogX(), MapLogY()), 0); + int start = std::max(MAX_TGP_FREQUENCIES - (int)std::min(Map::LogX(), Map::LogY()), 0); bool first = true; for (int frequency = start; frequency < MAX_TGP_FREQUENCIES; frequency++) { @@ -580,7 +580,7 @@ static void HeightMapCurves(uint level) float factor = sqrt((float)_height_map.size_x / (float)_height_map.size_y); uint sx = Clamp((int)(((1 << level) * factor) + 0.5), 1, 128); uint sy = Clamp((int)(((1 << level) / factor) + 0.5), 1, 128); - byte *c = AllocaM(byte, sx * sy); + byte *c = AllocaM(byte, static_cast(sx) * sy); for (uint i = 0; i < sx * sy; i++) { c[i] = Random() % lengthof(curve_maps); @@ -1004,8 +1004,8 @@ void GenerateTerrainPerlin() /* First make sure the tiles at the north border are void tiles if needed. */ if (_settings_game.construction.freeform_edges) { - for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0)); - for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y)); + for (uint x = 0; x < Map::SizeX(); x++) MakeVoid(TileXY(x, 0)); + for (uint y = 0; y < Map::SizeY(); y++) MakeVoid(TileXY(0, y)); } int max_height = H2I(TGPGetMaxHeight()); diff --git a/src/tile_cmd.h b/src/tile_cmd.h index 75964abad5150..2fdf1b30bf3ed 100644 --- a/src/tile_cmd.h +++ b/src/tile_cmd.h @@ -40,8 +40,8 @@ DECLARE_ENUM_AS_BIT_SET(VehicleEnterTileStatus) /** Tile information, used while rendering the tile */ struct TileInfo { - uint x; ///< X position of the tile in unit coordinates - uint y; ///< Y position of the tile in unit coordinates + int x; ///< X position of the tile in unit coordinates + int y; ///< Y position of the tile in unit coordinates Slope tileh; ///< Slope of the tile TileIndex tile; ///< Tile index int z; ///< Height diff --git a/src/tile_map.cpp b/src/tile_map.cpp index 2b8db5e24d37e..09a95385b4887 100644 --- a/src/tile_map.cpp +++ b/src/tile_map.cpp @@ -60,8 +60,8 @@ Slope GetTileSlope(TileIndex tile, int *h) { uint x1 = TileX(tile); uint y1 = TileY(tile); - uint x2 = std::min(x1 + 1, MapMaxX()); - uint y2 = std::min(y1 + 1, MapMaxY()); + uint x2 = std::min(x1 + 1, Map::MaxX()); + uint y2 = std::min(y1 + 1, Map::MaxY()); int hnorth = TileHeight(tile); // Height of the North corner. int hwest = TileHeight(TileXY(x2, y1)); // Height of the West corner. @@ -101,8 +101,8 @@ bool IsTileFlat(TileIndex tile, int *h) { uint x1 = TileX(tile); uint y1 = TileY(tile); - uint x2 = std::min(x1 + 1, MapMaxX()); - uint y2 = std::min(y1 + 1, MapMaxY()); + uint x2 = std::min(x1 + 1, Map::MaxX()); + uint y2 = std::min(y1 + 1, Map::MaxY()); uint z = TileHeight(tile); if (TileHeight(TileXY(x2, y1)) != z) return false; @@ -122,8 +122,8 @@ int GetTileZ(TileIndex tile) { uint x1 = TileX(tile); uint y1 = TileY(tile); - uint x2 = std::min(x1 + 1, MapMaxX()); - uint y2 = std::min(y1 + 1, MapMaxY()); + uint x2 = std::min(x1 + 1, Map::MaxX()); + uint y2 = std::min(y1 + 1, Map::MaxY()); return std::min({ TileHeight(tile), // N corner @@ -142,8 +142,8 @@ int GetTileMaxZ(TileIndex t) { uint x1 = TileX(t); uint y1 = TileY(t); - uint x2 = std::min(x1 + 1, MapMaxX()); - uint y2 = std::min(y1 + 1, MapMaxY()); + uint x2 = std::min(x1 + 1, Map::MaxX()); + uint y2 = std::min(y1 + 1, Map::MaxY()); return std::max({ TileHeight(t), // N corner diff --git a/src/tile_map.h b/src/tile_map.h index b6c715e8a8b06..4111bfbd6b127 100644 --- a/src/tile_map.h +++ b/src/tile_map.h @@ -24,12 +24,12 @@ * * @param tile The tile to get the height from * @return the height of the tile - * @pre tile < MapSize() + * @pre tile < Map::Size() */ -static inline uint TileHeight(TileIndex tile) +debug_inline static uint TileHeight(Tile tile) { - assert(tile < MapSize()); - return _m[tile].height; + assert(tile < Map::Size()); + return tile.height(); } /** @@ -41,7 +41,7 @@ static inline uint TileHeight(TileIndex tile) */ static inline uint TileHeightOutsideMap(int x, int y) { - return TileHeight(TileXY(Clamp(x, 0, MapMaxX()), Clamp(y, 0, MapMaxY()))); + return TileHeight(TileXY(Clamp(x, 0, Map::MaxX()), Clamp(y, 0, Map::MaxY()))); } /** @@ -51,14 +51,14 @@ static inline uint TileHeightOutsideMap(int x, int y) * * @param tile The tile to change the height * @param height The new height value of the tile - * @pre tile < MapSize() + * @pre tile < Map::Size() * @pre height <= MAX_TILE_HEIGHT */ -static inline void SetTileHeight(TileIndex tile, uint height) +static inline void SetTileHeight(Tile tile, uint height) { - assert(tile < MapSize()); + assert(tile < Map::Size()); assert(height <= MAX_TILE_HEIGHT); - _m[tile].height = height; + tile.height() = height; } /** @@ -69,7 +69,7 @@ static inline void SetTileHeight(TileIndex tile, uint height) * @param tile The tile to get the height * @return The height of the tile in pixel */ -static inline uint TilePixelHeight(TileIndex tile) +static inline uint TilePixelHeight(Tile tile) { return TileHeight(tile) * TILE_HEIGHT; } @@ -91,12 +91,12 @@ static inline uint TilePixelHeightOutsideMap(int x, int y) * * @param tile The tile to get the TileType * @return The tiletype of the tile - * @pre tile < MapSize() + * @pre tile < Map::Size() */ -static inline TileType GetTileType(TileIndex tile) +debug_inline static TileType GetTileType(Tile tile) { - assert(tile < MapSize()); - return (TileType)GB(_m[tile].type, 4, 4); + assert(tile < Map::Size()); + return (TileType)GB(tile.type(), 4, 4); } /** @@ -104,16 +104,16 @@ static inline TileType GetTileType(TileIndex tile) * * @param tile The tile to check * @return Whether the tile is in the interior of the map - * @pre tile < MapSize() + * @pre tile < Map::Size() */ -static inline bool IsInnerTile(TileIndex tile) +static inline bool IsInnerTile(Tile tile) { - assert(tile < MapSize()); + assert(tile < Map::Size()); uint x = TileX(tile); uint y = TileY(tile); - return x < MapMaxX() && y < MapMaxY() && ((x > 0 && y > 0) || !_settings_game.construction.freeform_edges); + return x < Map::MaxX() && y < Map::MaxY() && ((x > 0 && y > 0) || !_settings_game.construction.freeform_edges); } /** @@ -125,17 +125,17 @@ static inline bool IsInnerTile(TileIndex tile) * * @param tile The tile to save the new type * @param type The type to save - * @pre tile < MapSize() + * @pre tile < Map::Size() * @pre type MP_VOID <=> tile is on the south-east or south-west edge. */ -static inline void SetTileType(TileIndex tile, TileType type) +static inline void SetTileType(Tile tile, TileType type) { - assert(tile < MapSize()); + assert(tile < Map::Size()); /* VOID tiles (and no others) are exactly allowed at the lower left and right * edges of the map. If _settings_game.construction.freeform_edges is true, * the upper edges of the map are also VOID tiles. */ assert(IsInnerTile(tile) == (type != MP_VOID)); - SB(_m[tile].type, 4, 4, type); + SB(tile.type(), 4, 4, type); } /** @@ -147,7 +147,7 @@ static inline void SetTileType(TileIndex tile, TileType type) * @param type The type to check against * @return true If the type matches against the type of the tile */ -static inline bool IsTileType(TileIndex tile, TileType type) +debug_inline static bool IsTileType(Tile tile, TileType type) { return GetTileType(tile) == type; } @@ -158,9 +158,9 @@ static inline bool IsTileType(TileIndex tile, TileType type) * @param tile The tile to check * @return True if the tile is on the map and not one of MP_VOID. */ -static inline bool IsValidTile(TileIndex tile) +static inline bool IsValidTile(Tile tile) { - return tile < MapSize() && !IsTileType(tile, MP_VOID); + return tile < Map::Size() && !IsTileType(tile, MP_VOID); } /** @@ -175,13 +175,13 @@ static inline bool IsValidTile(TileIndex tile) * @pre IsValidTile(tile) * @pre The type of the tile must not be MP_HOUSE and MP_INDUSTRY */ -static inline Owner GetTileOwner(TileIndex tile) +static inline Owner GetTileOwner(Tile tile) { assert(IsValidTile(tile)); assert(!IsTileType(tile, MP_HOUSE)); assert(!IsTileType(tile, MP_INDUSTRY)); - return (Owner)GB(_m[tile].m1, 0, 5); + return (Owner)GB(tile.m1(), 0, 5); } /** @@ -195,13 +195,13 @@ static inline Owner GetTileOwner(TileIndex tile) * @pre IsValidTile(tile) * @pre The type of the tile must not be MP_HOUSE and MP_INDUSTRY */ -static inline void SetTileOwner(TileIndex tile, Owner owner) +static inline void SetTileOwner(Tile tile, Owner owner) { assert(IsValidTile(tile)); assert(!IsTileType(tile, MP_HOUSE)); assert(!IsTileType(tile, MP_INDUSTRY)); - SB(_m[tile].m1, 0, 5, owner); + SB(tile.m1(), 0, 5, owner); } /** @@ -211,7 +211,7 @@ static inline void SetTileOwner(TileIndex tile, Owner owner) * @param owner The owner to check against * @return True if a tile belongs the the given owner */ -static inline bool IsTileOwner(TileIndex tile, Owner owner) +static inline bool IsTileOwner(Tile tile, Owner owner) { return GetTileOwner(tile) == owner; } @@ -220,25 +220,25 @@ static inline bool IsTileOwner(TileIndex tile, Owner owner) * Set the tropic zone * @param tile the tile to set the zone of * @param type the new type - * @pre tile < MapSize() + * @pre tile < Map::Size() */ -static inline void SetTropicZone(TileIndex tile, TropicZone type) +static inline void SetTropicZone(Tile tile, TropicZone type) { - assert(tile < MapSize()); + assert(tile < Map::Size()); assert(!IsTileType(tile, MP_VOID) || type == TROPICZONE_NORMAL); - SB(_m[tile].type, 0, 2, type); + SB(tile.type(), 0, 2, type); } /** * Get the tropic zone * @param tile the tile to get the zone of - * @pre tile < MapSize() + * @pre tile < Map::Size() * @return the zone type */ -static inline TropicZone GetTropicZone(TileIndex tile) +static inline TropicZone GetTropicZone(Tile tile) { - assert(tile < MapSize()); - return (TropicZone)GB(_m[tile].type, 0, 2); + assert(tile < Map::Size()); + return (TropicZone)GB(tile.type(), 0, 2); } /** @@ -247,10 +247,10 @@ static inline TropicZone GetTropicZone(TileIndex tile) * @pre IsTileType(t, MP_HOUSE) || IsTileType(t, MP_OBJECT) || IsTileType(t, MP_INDUSTRY) ||IsTileType(t, MP_STATION) * @return frame number */ -static inline byte GetAnimationFrame(TileIndex t) +static inline byte GetAnimationFrame(Tile t) { assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_OBJECT) || IsTileType(t, MP_INDUSTRY) ||IsTileType(t, MP_STATION)); - return _me[t].m7; + return t.m7(); } /** @@ -259,10 +259,10 @@ static inline byte GetAnimationFrame(TileIndex t) * @param frame the new frame number * @pre IsTileType(t, MP_HOUSE) || IsTileType(t, MP_OBJECT) || IsTileType(t, MP_INDUSTRY) ||IsTileType(t, MP_STATION) */ -static inline void SetAnimationFrame(TileIndex t, byte frame) +static inline void SetAnimationFrame(Tile t, byte frame) { assert(IsTileType(t, MP_HOUSE) || IsTileType(t, MP_OBJECT) || IsTileType(t, MP_INDUSTRY) ||IsTileType(t, MP_STATION)); - _me[t].m7 = frame; + t.m7() = frame; } Slope GetTileSlope(TileIndex tile, int *h = nullptr); diff --git a/src/tile_type.h b/src/tile_type.h index 6b5514d90e4c6..db7ece562c340 100644 --- a/src/tile_type.h +++ b/src/tile_type.h @@ -85,8 +85,18 @@ enum TropicZone { struct TileIndex : StrongIntegralTypedef { using StrongIntegralTypedef::StrongIntegralTypedef; + debug_inline constexpr TileIndex() = default; + debug_inline constexpr TileIndex(const TileIndex &o) = default; + debug_inline constexpr TileIndex(TileIndex &&o) = default; + + debug_inline constexpr TileIndex(const uint32 &value) : StrongIntegralTypedef(value) {} + + debug_inline constexpr TileIndex &operator =(const TileIndex &rhs) { this->value = rhs.value; return *this; } + debug_inline constexpr TileIndex &operator =(TileIndex &&rhs) { this->value = std::move(rhs.value); return *this; } + debug_inline constexpr TileIndex &operator =(const uint32 &rhs) { this->value = rhs; return *this; } + /** Implicit conversion to the base type for e.g. array indexing. */ - constexpr operator uint32() const { return this->value; } + debug_inline constexpr operator uint32() const { return this->value; } /* Import operators from the base class into our overload set. */ using StrongIntegralTypedef::operator ==; diff --git a/src/tilearea.cpp b/src/tilearea.cpp index 21271f94f1e2e..974f121b6c4ad 100644 --- a/src/tilearea.cpp +++ b/src/tilearea.cpp @@ -20,8 +20,8 @@ */ OrthogonalTileArea::OrthogonalTileArea(TileIndex start, TileIndex end) { - assert(start < MapSize()); - assert(end < MapSize()); + assert(start < Map::Size()); + assert(end < Map::Size()); uint sx = TileX(start); uint sy = TileY(start); @@ -127,8 +127,8 @@ OrthogonalTileArea &OrthogonalTileArea::Expand(int rad) int sx = std::max(x - rad, 0); int sy = std::max(y - rad, 0); - int ex = std::min(x + this->w + rad, MapSizeX()); - int ey = std::min(y + this->h + rad, MapSizeY()); + int ex = std::min(x + this->w + rad, Map::SizeX()); + int ey = std::min(y + this->h + rad, Map::SizeY()); this->tile = TileXY(sx, sy); this->w = ex - sx; @@ -141,9 +141,9 @@ OrthogonalTileArea &OrthogonalTileArea::Expand(int rad) */ void OrthogonalTileArea::ClampToMap() { - assert(this->tile < MapSize()); - this->w = std::min(this->w, MapSizeX() - TileX(this->tile)); - this->h = std::min(this->h, MapSizeY() - TileY(this->tile)); + assert(this->tile < Map::Size()); + this->w = std::min(this->w, Map::SizeX() - TileX(this->tile)); + this->h = std::min(this->h, Map::SizeY() - TileY(this->tile)); } /** @@ -171,8 +171,8 @@ OrthogonalTileIterator OrthogonalTileArea::end() const */ DiagonalTileArea::DiagonalTileArea(TileIndex start, TileIndex end) : tile(start) { - assert(start < MapSize()); - assert(end < MapSize()); + assert(start < Map::Size()); + assert(end < Map::Size()); /* Unfortunately we can't find a new base and make all a and b positive because * the new base might be a "flattened" corner where there actually is no single @@ -274,9 +274,24 @@ TileIterator &DiagonalTileIterator::operator++() uint x = this->base_x + (this->a_cur - this->b_cur) / 2; uint y = this->base_y + (this->b_cur + this->a_cur) / 2; /* Prevent wrapping around the map's borders. */ - this->tile = x >= MapSizeX() || y >= MapSizeY() ? INVALID_TILE : TileXY(x, y); - } while (this->tile > MapSize() && this->b_max != this->b_cur); + this->tile = x >= Map::SizeX() || y >= Map::SizeY() ? INVALID_TILE : TileXY(x, y); + } while (this->tile > Map::Size() && this->b_max != this->b_cur); if (this->b_max == this->b_cur) this->tile = INVALID_TILE; return *this; } + +/** + * Create either an OrthogonalTileIterator or DiagonalTileIterator given the diagonal parameter. + * @param corner1 Tile from where to begin iterating. + * @param corner2 Tile where to end the iterating. + * @param diagonal Whether to create a DiagonalTileIterator or OrthogonalTileIterator. + * @return unique_ptr to the allocated TileIterator. + */ +/* static */ std::unique_ptr TileIterator::Create(TileIndex corner1, TileIndex corner2, bool diagonal) +{ + if (diagonal) { + return std::make_unique(corner1, corner2); + } + return std::make_unique(corner1, corner2); +} diff --git a/src/tilearea_type.h b/src/tilearea_type.h index b6af998a76116..412f7c3752a33 100644 --- a/src/tilearea_type.h +++ b/src/tilearea_type.h @@ -146,7 +146,7 @@ class TileIterator { /** * Allocate a new iterator that is a copy of this one. */ - virtual TileIterator *Clone() const = 0; + virtual std::unique_ptr Clone() const = 0; /** * Equality comparison. @@ -177,6 +177,8 @@ class TileIterator { { return this->tile != rhs; } + + static std::unique_ptr Create(TileIndex corner1, TileIndex corner2, bool diagonal); }; /** Iterator to iterate over a tile area (rectangle) of the map. */ @@ -223,9 +225,9 @@ class OrthogonalTileIterator : public TileIterator { return *this; } - virtual TileIterator *Clone() const + virtual std::unique_ptr Clone() const { - return new OrthogonalTileIterator(*this); + return std::make_unique(*this); } }; @@ -262,9 +264,9 @@ class DiagonalTileIterator : public TileIterator { TileIterator& operator ++(); - virtual TileIterator *Clone() const + virtual std::unique_ptr Clone() const { - return new DiagonalTileIterator(*this); + return std::make_unique(*this); } }; diff --git a/src/tilematrix_type.hpp b/src/tilematrix_type.hpp index 2ca165dc03c32..ee5792ea241e4 100644 --- a/src/tilematrix_type.hpp +++ b/src/tilematrix_type.hpp @@ -101,8 +101,8 @@ class TileMatrix { tile_x -= std::min(extend * N, tile_x); tile_y -= std::min(extend * N, tile_y); - w += std::min(extend * N, MapSizeX() - tile_x - w); - h += std::min(extend * N, MapSizeY() - tile_y - h); + w += std::min(extend * N, Map::SizeX() - tile_x - w); + h += std::min(extend * N, Map::SizeY() - tile_y - h); return TileArea(TileXY(tile_x, tile_y), w, h); } diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index 5db7f87e9fb82..92557fc38447a 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -30,6 +30,7 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, ModifyTimetableFlags mtf, bool timetabled) { Order *order = v->GetOrder(order_number); + assert(order != nullptr); int total_delta = 0; int timetable_delta = 0; @@ -173,13 +174,47 @@ CommandCost CmdChangeTimetable(DoCommandFlag flags, VehicleID veh, VehicleOrderI return CommandCost(); } +/** + * Change timetable data of all orders of a vehicle. + * @param flags Operation to perform. + * @param veh Vehicle with the orders to change. + * @param mtf Timetable data to change (@see ModifyTimetableFlags) + * @param data The data to modify as specified by \c mtf. + * 0 to clear times, UINT16_MAX to clear speed limit. + * @return the cost of this operation or an error + */ +CommandCost CmdBulkChangeTimetable(DoCommandFlag flags, VehicleID veh, ModifyTimetableFlags mtf, uint16 data) +{ + Vehicle *v = Vehicle::GetIfValid(veh); + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; + + CommandCost ret = CheckOwnership(v->owner); + if (ret.Failed()) return ret; + + if (mtf >= MTF_END) return CMD_ERROR; + + if (v->GetNumOrders() == 0) return CMD_ERROR; + + if (flags & DC_EXEC) { + for (VehicleOrderID order_number = 0; order_number < v->GetNumOrders(); order_number++) { + Order *order = v->GetOrder(order_number); + if (order == nullptr || order->IsType(OT_IMPLICIT)) continue; + + Command::Do(DC_EXEC, v->index, order_number, mtf, data); + } + } + + return CommandCost(); +} + /** * Clear the lateness counter to make the vehicle on time. * @param flags Operation to perform. * @param veh Vehicle with the orders to change. + * @param apply_to_group Set to reset the late counter for all vehicles sharing the orders. * @return the cost of this operation or an error */ -CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, VehicleID veh) +CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, VehicleID veh, bool apply_to_group) { Vehicle *v = Vehicle::GetIfValid(veh); if (v == nullptr || !v->IsPrimaryVehicle() || v->orders == nullptr) return CMD_ERROR; @@ -188,8 +223,23 @@ CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, VehicleID veh) if (ret.Failed()) return ret; if (flags & DC_EXEC) { - v->lateness_counter = 0; - SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index); + if (apply_to_group) { + int32 most_late = 0; + for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) { + if (u->lateness_counter > most_late) { + most_late = u->lateness_counter; + } + } + if (most_late > 0) { + for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) { + u->lateness_counter -= most_late; + SetWindowDirty(WC_VEHICLE_TIMETABLE, u->index); + } + } + } else { + v->lateness_counter = 0; + SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index); + } } return CommandCost(); @@ -365,6 +415,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) if (v->cur_real_order_index >= v->GetNumOrders()) return; Order *real_current_order = v->GetOrder(v->cur_real_order_index); + assert(real_current_order != nullptr); VehicleOrderID first_manual_order = 0; for (Order *o = v->GetFirstOrder(); o != nullptr && o->IsType(OT_IMPLICIT); o = o->next) { diff --git a/src/timetable_cmd.h b/src/timetable_cmd.h index ddf1277372f44..73b518f4ddc5f 100644 --- a/src/timetable_cmd.h +++ b/src/timetable_cmd.h @@ -13,13 +13,15 @@ #include "command_type.h" CommandCost CmdChangeTimetable(DoCommandFlag flags, VehicleID veh, VehicleOrderID order_number, ModifyTimetableFlags mtf, uint16 data); -CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, VehicleID veh); +CommandCost CmdBulkChangeTimetable(DoCommandFlag flags, VehicleID veh, ModifyTimetableFlags mtf, uint16 data); +CommandCost CmdSetVehicleOnTime(DoCommandFlag flags, VehicleID veh, bool apply_to_group); CommandCost CmdAutofillTimetable(DoCommandFlag flags, VehicleID veh, bool autofill, bool preserve_wait_time); CommandCost CmdSetTimetableStart(DoCommandFlag flags, VehicleID veh_id, bool timetable_all, Date start_date); -DEF_CMD_TRAIT(CMD_CHANGE_TIMETABLE, CmdChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_VEHICLE_ON_TIME, CmdSetVehicleOnTime, 0, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_AUTOFILL_TIMETABLE, CmdAutofillTimetable, 0, CMDT_ROUTE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_SET_TIMETABLE_START, CmdSetTimetableStart, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CHANGE_TIMETABLE, CmdChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_BULK_CHANGE_TIMETABLE, CmdBulkChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_VEHICLE_ON_TIME, CmdSetVehicleOnTime, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_AUTOFILL_TIMETABLE, CmdAutofillTimetable, 0, CMDT_ROUTE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_SET_TIMETABLE_START, CmdSetTimetableStart, 0, CMDT_ROUTE_MANAGEMENT) #endif /* TIMETABLE_CMD_H */ diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index eb0214aa66b8d..54b82890407f9 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -98,15 +98,15 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID assert(v->GetNumOrders() >= 2); assert(start < v->GetNumOrders()); - Ticks sum = offset; - VehicleOrderID i = start; - const Order *order = v->GetOrder(i); - /* Pre-initialize with unknown time */ for (int i = 0; i < v->GetNumOrders(); ++i) { table[i].arrival = table[i].departure = INVALID_TICKS; } + Ticks sum = offset; + VehicleOrderID i = start; + const Order *order = v->GetOrder(i); + /* Cyclically loop over all orders until we reach the current one again. * As we may start at the current order, do a post-checking loop */ do { @@ -186,6 +186,8 @@ struct TimetableWindow : Window { uint deparr_abbr_width; ///< The width of the departure/arrival abbreviation Scrollbar *vscroll; bool query_is_speed_query; ///< The currently open query window is a speed query and not a time query. + bool set_start_date_all; ///< Set start date using minutes text entry for all timetable entries (ctrl-click) action + bool change_timetable_all; ///< Set wait time or speed for all timetable entries (ctrl-click) action TimetableWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc), @@ -226,24 +228,24 @@ struct TimetableWindow : Window { SetDParamMaxValue(0, MAX_YEAR * DAYS_IN_YEAR, 0, FS_SMALL); this->deparr_time_width = GetStringBoundingBox(GetDateTimeStringID()).width; this->deparr_abbr_width = std::max(GetStringBoundingBox(STR_TIMETABLE_ARRIVAL_ABBREVIATION).width, GetStringBoundingBox(STR_TIMETABLE_DEPARTURE_ABBREVIATION).width); - size->width = WD_FRAMERECT_LEFT + this->deparr_abbr_width + 10 + this->deparr_time_width + WD_FRAMERECT_RIGHT; + size->width = this->deparr_abbr_width + WidgetDimensions::scaled.hsep_wide + this->deparr_time_width + padding.width; FALLTHROUGH; case WID_VT_ARRIVAL_DEPARTURE_SELECTION: case WID_VT_TIMETABLE_PANEL: resize->height = FONT_HEIGHT_NORMAL; - size->height = WD_FRAMERECT_TOP + 8 * resize->height + WD_FRAMERECT_BOTTOM; + size->height = 8 * resize->height + padding.height; break; case WID_VT_SUMMARY_PANEL: - size->height = WD_FRAMERECT_TOP + 2 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM; + size->height = 2 * FONT_HEIGHT_NORMAL + padding.height; break; } } int GetOrderFromTimetableWndPt(int y, const Vehicle *v) { - uint sel = (y - this->GetWidget(WID_VT_TIMETABLE_PANEL)->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL; + uint sel = (y - this->GetWidget(WID_VT_TIMETABLE_PANEL)->pos_y - WidgetDimensions::scaled.framerect.top) / FONT_HEIGHT_NORMAL; if (sel >= this->vscroll->GetCapacity()) return INVALID_ORDER; @@ -338,13 +340,13 @@ struct TimetableWindow : Window { bool disable = true; if (selected != -1) { const Order *order = v->GetOrder(((selected + 1) / 2) % v->GetNumOrders()); - if (selected % 2 == 1) { + if (selected % 2 != 0) { disable = order != nullptr && (order->IsType(OT_CONDITIONAL) || order->IsType(OT_IMPLICIT)); } else { disable = order == nullptr || ((!order->IsType(OT_GOTO_STATION) || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) && !order->IsType(OT_CONDITIONAL)); } } - bool disable_speed = disable || selected % 2 != 1 || v->type == VEH_AIRCRAFT; + bool disable_speed = disable || selected % 2 == 0 || v->type == VEH_AIRCRAFT; this->SetWidgetDisabledState(WID_VT_CHANGE_TIME, disable); this->SetWidgetDisabledState(WID_VT_CLEAR_TIME, disable); @@ -386,15 +388,15 @@ struct TimetableWindow : Window { switch (widget) { case WID_VT_TIMETABLE_PANEL: { - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); int i = this->vscroll->GetPosition(); VehicleOrderID order_id = (i + 1) / 2; bool final_order = false; bool rtl = _current_text_dir == TD_RTL; SetDParamMaxValue(0, v->GetNumOrders(), 2); - int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + 3; - int middle = rtl ? r.right - WD_FRAMERECT_RIGHT - index_column_width : r.left + WD_FRAMERECT_LEFT + index_column_width; + int index_column_width = GetStringBoundingBox(STR_ORDER_INDEX).width + 2 * GetSpriteSize(rtl ? SPR_ARROW_RIGHT : SPR_ARROW_LEFT).width + WidgetDimensions::scaled.hsep_normal; + int middle = rtl ? tr.right - index_column_width : tr.left + index_column_width; const Order *order = v->GetOrder(order_id); while (order != nullptr) { @@ -402,7 +404,7 @@ struct TimetableWindow : Window { if (!this->vscroll->IsVisible(i)) break; if (i % 2 == 0) { - DrawOrderString(v, order, order_id, y, i == selected, true, r.left + WD_FRAMERECT_LEFT, middle, r.right - WD_FRAMERECT_RIGHT); + DrawOrderString(v, order, order_id, tr.top, i == selected, true, tr.left, middle, tr.right); order_id++; @@ -438,13 +440,13 @@ struct TimetableWindow : Window { } SetDParam(2, order->GetMaxSpeed()); - DrawString(rtl ? r.left + WD_FRAMERECT_LEFT : middle, rtl ? middle : r.right - WD_FRAMERECT_LEFT, y, string, colour); + DrawString(rtl ? tr.left : middle, rtl ? middle : tr.right, tr.top, string, colour); if (final_order) break; } i++; - y += FONT_HEIGHT_NORMAL; + tr.top += FONT_HEIGHT_NORMAL; } break; } @@ -462,16 +464,13 @@ struct TimetableWindow : Window { VehicleOrderID earlyID = BuildArrivalDepartureList(v, arr_dep) ? cur_order : (VehicleOrderID)INVALID_VEH_ORDER_ID; - int y = r.top + WD_FRAMERECT_TOP; - + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); bool show_late = this->show_expected && v->lateness_counter > VANILLA_DAY_TICKS; Ticks offset = show_late ? 0 : -v->lateness_counter; bool rtl = _current_text_dir == TD_RTL; - int abbr_left = rtl ? r.right - WD_FRAMERECT_RIGHT - this->deparr_abbr_width : r.left + WD_FRAMERECT_LEFT; - int abbr_right = rtl ? r.right - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT + this->deparr_abbr_width; - int time_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.right - WD_FRAMERECT_RIGHT - this->deparr_time_width; - int time_right = rtl ? r.left + WD_FRAMERECT_LEFT + this->deparr_time_width : r.right - WD_FRAMERECT_RIGHT; + Rect abbr = tr.WithWidth(this->deparr_abbr_width, rtl); + Rect time = tr.WithWidth(this->deparr_time_width, !rtl); for (int i = this->vscroll->GetPosition(); i / 2 < v->GetNumOrders(); ++i) { // note: i is also incremented in the loop /* Don't draw anything if it extends past the end of the window. */ @@ -479,54 +478,54 @@ struct TimetableWindow : Window { if (i % 2 == 0) { if (arr_dep[i / 2].arrival != INVALID_TICKS) { - DrawString(abbr_left, abbr_right, y, STR_TIMETABLE_ARRIVAL_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK); + DrawString(abbr.left, abbr.right, tr.top, STR_TIMETABLE_ARRIVAL_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK); if (this->show_expected && i / 2 == earlyID) { SetDateTimeParams(0, _date, arr_dep[i / 2].arrival); - DrawString(time_left, time_right, y, GetDateTimeStringID(), TC_GREEN); + DrawString(time.left, time.right, tr.top, GetDateTimeStringID(), TC_GREEN); } else { SetDateTimeParams(0, _date, arr_dep[i / 2].arrival + offset); - DrawString(time_left, time_right, y, GetDateTimeStringID(), + DrawString(time.left, time.right, tr.top, GetDateTimeStringID(), show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK); } } } else { if (arr_dep[i / 2].departure != INVALID_TICKS) { - DrawString(abbr_left, abbr_right, y, STR_TIMETABLE_DEPARTURE_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK); + DrawString(abbr.left, abbr.right, tr.top, STR_TIMETABLE_DEPARTURE_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK); SetDateTimeParams(0, _date, arr_dep[i/2].departure + offset); - DrawString(time_left, time_right, y, GetDateTimeStringID(), + DrawString(time.left, time.right, tr.top, GetDateTimeStringID(), show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK); } } - y += FONT_HEIGHT_NORMAL; + tr.top += FONT_HEIGHT_NORMAL; } break; } case WID_VT_SUMMARY_PANEL: { - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); Ticks total_time = v->orders != nullptr ? v->orders->GetTimetableDurationIncomplete() : 0; if (total_time != 0) { SetTimetableParams(0, 1, total_time); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, v->orders->IsCompleteTimetable() ? STR_TIMETABLE_TOTAL_TIME : STR_TIMETABLE_TOTAL_TIME_INCOMPLETE); + DrawString(tr, v->orders->IsCompleteTimetable() ? STR_TIMETABLE_TOTAL_TIME : STR_TIMETABLE_TOTAL_TIME_INCOMPLETE); } - y += FONT_HEIGHT_NORMAL; + tr.top += FONT_HEIGHT_NORMAL; if (v->timetable_start != 0) { /* We are running towards the first station so we can start the * timetable at the given time. */ SetDParam(0, GetDateTimeStringID()); SetDateTimeParams(1, v->timetable_start); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_TIMETABLE_STATUS_START_AT_DATETIME); + DrawString(tr, STR_TIMETABLE_STATUS_START_AT_DATETIME); } else if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) { /* We aren't running on a timetable yet, so how can we be "on time" * when we aren't even "on service"/"on duty"? */ - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_TIMETABLE_STATUS_NOT_STARTED); + DrawString(tr, STR_TIMETABLE_STATUS_NOT_STARTED); } else if (v->lateness_counter == 0 || (!_settings_client.gui.timetable_in_ticks && v->lateness_counter / VANILLA_DAY_TICKS == 0)) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_TIMETABLE_STATUS_ON_TIME); + DrawString(tr, STR_TIMETABLE_STATUS_ON_TIME); } else { SetTimetableParams(0, 1, abs(v->lateness_counter)); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, v->lateness_counter < 0 ? STR_TIMETABLE_STATUS_EARLY : STR_TIMETABLE_STATUS_LATE); + DrawString(tr, v->lateness_counter < 0 ? STR_TIMETABLE_STATUS_EARLY : STR_TIMETABLE_STATUS_LATE); } break; } @@ -536,7 +535,7 @@ struct TimetableWindow : Window { static inline std::tuple PackTimetableArgs(const Vehicle *v, uint selected, bool speed) { uint order_number = (selected + 1) / 2; - ModifyTimetableFlags mtf = (selected % 2 == 1) ? (speed ? MTF_TRAVEL_SPEED : MTF_TRAVEL_TIME) : MTF_WAIT_TIME; + ModifyTimetableFlags mtf = (selected % 2 != 0) ? (speed ? MTF_TRAVEL_SPEED : MTF_TRAVEL_TIME) : MTF_WAIT_TIME; if (order_number >= v->GetNumOrders()) order_number = 0; @@ -588,7 +587,7 @@ struct TimetableWindow : Window { StringID current = STR_EMPTY; if (order != nullptr) { - uint time = (selected % 2 == 1) ? order->GetTravelTime() : order->GetWaitTime(); + uint time = (selected % 2 != 0) ? order->GetTravelTime() : order->GetWaitTime(); if (!_settings_client.gui.timetable_in_ticks) time = TicksToTimeUnits((Ticks)time); @@ -599,6 +598,7 @@ struct TimetableWindow : Window { } this->query_is_speed_query = false; + this->change_timetable_all = _ctrl_pressed && (order != nullptr); ShowQueryString(current, STR_TIMETABLE_CHANGE_TIME, 31, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED); break; } @@ -619,24 +619,33 @@ struct TimetableWindow : Window { } this->query_is_speed_query = true; + this->change_timetable_all = _ctrl_pressed && (order != nullptr); ShowQueryString(current, STR_TIMETABLE_CHANGE_SPEED, 31, this, CS_NUMERAL, QSF_NONE); break; } case WID_VT_CLEAR_TIME: { // Clear waiting time. auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, false); - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, 0); + if (_ctrl_pressed) { + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, mtf, 0); + } else { + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, 0); + } break; } case WID_VT_CLEAR_SPEED: { // Clear max speed button. auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, true); - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, UINT16_MAX); + if (_ctrl_pressed) { + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, mtf, UINT16_MAX); + } else { + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, UINT16_MAX); + } break; } case WID_VT_RESET_LATENESS: // Reset the vehicle's late counter. - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index); + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, _ctrl_pressed); break; case WID_VT_AUTOFILL: { // Autofill the timetable. @@ -671,13 +680,18 @@ struct TimetableWindow : Window { } auto [order_id, mtf] = PackTimetableArgs(v, this->sel_index, this->query_is_speed_query); - Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, std::min(val, UINT16_MAX)); + + if (this->change_timetable_all) { + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, mtf, std::min(val, UINT16_MAX)); + } else { + Command::Post(STR_ERROR_CAN_T_TIMETABLE_VEHICLE, v->index, order_id, mtf, std::min(val, UINT16_MAX)); + } } void OnResize() override { /* Update the scroll bar */ - this->vscroll->SetCapacityFromWidget(this, WID_VT_TIMETABLE_PANEL, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + this->vscroll->SetCapacityFromWidget(this, WID_VT_TIMETABLE_PANEL, WidgetDimensions::scaled.framerect.Vertical()); } /** diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 13c52f2b4eb13..d03371d42884c 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -33,6 +33,8 @@ #include "console_gui.h" #include "news_gui.h" #include "ai/ai_gui.hpp" +#include "game/game_gui.hpp" +#include "script/script_gui.h" #include "tilehighlight_func.h" #include "smallmap_gui.h" #include "graph_gui.h" @@ -50,6 +52,8 @@ #include "guitimer_func.h" #include "screenshot_gui.h" #include "misc_cmd.h" +#include "league_gui.h" +#include "league_base.h" #include "widgets/toolbar_widget.h" @@ -94,21 +98,22 @@ class DropDownListCheckedItem : public DropDownListStringItem { DropDownListCheckedItem(StringID string, int result, bool masked, bool checked) : DropDownListStringItem(string, result, masked), checked(checked) { - this->checkmark_width = GetStringBoundingBox(STR_JUST_CHECKMARK).width + 3; + this->checkmark_width = GetStringBoundingBox(STR_JUST_CHECKMARK).width + WidgetDimensions::scaled.hsep_wide; } - uint Width() const + uint Width() const override { return DropDownListStringItem::Width() + this->checkmark_width; } - void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const + void Draw(const Rect &r, bool sel, Colours bg_colour) const override { bool rtl = _current_text_dir == TD_RTL; + Rect tr = r.Shrink(WidgetDimensions::scaled.dropdowntext, RectPadding::zero); if (this->checked) { - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK); + DrawString(tr, STR_JUST_CHECKMARK, sel ? TC_WHITE : TC_BLACK); } - DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : this->checkmark_width), right - WD_FRAMERECT_RIGHT - (rtl ? this->checkmark_width : 0), top, this->String(), sel ? TC_WHITE : TC_BLACK); + DrawString(tr.Indent(this->checkmark_width, rtl), this->String(), sel ? TC_WHITE : TC_BLACK); } }; @@ -137,15 +142,15 @@ class DropDownListCompanyItem : public DropDownListItem { CompanyID company = (CompanyID)this->result; SetDParam(0, company); SetDParam(1, company); - return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + this->lock_size.width + 6; + return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + this->lock_size.width + WidgetDimensions::scaled.dropdowntext.Horizontal() + WidgetDimensions::scaled.hsep_wide; } uint Height(uint width) const override { - return std::max(std::max(this->icon_size.height, this->lock_size.height) + 2U, (uint)FONT_HEIGHT_NORMAL); + return std::max(std::max(this->icon_size.height, this->lock_size.height) + WidgetDimensions::scaled.imgbtn.Vertical(), (uint)FONT_HEIGHT_NORMAL); } - void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const override + void Draw(const Rect &r, bool sel, Colours bg_colour) const override { CompanyID company = (CompanyID)this->result; bool rtl = _current_text_dir == TD_RTL; @@ -153,13 +158,14 @@ class DropDownListCompanyItem : public DropDownListItem { /* It's possible the company is deleted while the dropdown is open */ if (!Company::IsValidID(company)) return; - int icon_offset = (bottom - top - icon_size.height) / 2; - int text_offset = (bottom - top - FONT_HEIGHT_NORMAL) / 2; - int lock_offset = (bottom - top - lock_size.height) / 2; + Rect tr = r.Shrink(WidgetDimensions::scaled.dropdowntext, RectPadding::zero); + int icon_y = CenterBounds(r.top, r.bottom, icon_size.height); + int text_y = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL); + int lock_y = CenterBounds(r.top, r.bottom, lock_size.height); - DrawCompanyIcon(company, rtl ? right - this->icon_size.width - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT, top + icon_offset); + DrawCompanyIcon(company, tr.WithWidth(this->icon_size.width, rtl).left, icon_y); if (NetworkCompanyIsPassworded(company)) { - DrawSprite(SPR_LOCK, PAL_NONE, rtl ? left + WD_FRAMERECT_LEFT : right - this->lock_size.width - WD_FRAMERECT_RIGHT, top + lock_offset); + DrawSprite(SPR_LOCK, PAL_NONE, tr.WithWidth(this->lock_size.width, !rtl).left, lock_y); } SetDParam(0, company); @@ -170,7 +176,8 @@ class DropDownListCompanyItem : public DropDownListItem { } else { col = sel ? TC_WHITE : TC_BLACK; } - DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 3 + this->lock_size.width : 3 + this->icon_size.width), right - WD_FRAMERECT_RIGHT - (rtl ? 3 + this->icon_size.width : 3 + this->lock_size.width), top + text_offset, STR_COMPANY_NAME_COMPANY_NUM, col); + tr = tr.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal, rtl).Indent(this->lock_size.width + WidgetDimensions::scaled.hsep_normal, !rtl); + DrawString(tr.left, tr.right, text_y, STR_COMPANY_NAME_COMPANY_NUM, col); } }; @@ -246,7 +253,6 @@ static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0) PopupMainToolbMenu(w, widget, std::move(list), _local_company == COMPANY_SPECTATOR ? (widget == WID_TN_COMPANIES ? CTMN_CLIENT_LIST : CTMN_SPECTATOR) : (int)_local_company); } - static ToolbarMode _toolbar_mode; static CallBackFunction SelectSignTool() @@ -292,7 +298,8 @@ static CallBackFunction ToolbarFastForwardClick(Window *w) enum OptionMenuEntries { OME_GAMEOPTIONS, OME_SETTINGS, - OME_SCRIPT_SETTINGS, + OME_AI_SETTINGS, + OME_GAMESCRIPT_SETTINGS, OME_NEWGRFSETTINGS, OME_TRANSPARENCIES, OME_SHOW_TOWNNAMES, @@ -320,7 +327,10 @@ static CallBackFunction ToolbarOptionsClick(Window *w) /* Changes to the per-AI settings don't get send from the server to the clients. Clients get * the settings once they join but never update it. As such don't show the window at all * to network clients. */ - if (!_networking || _network_server) list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_SCRIPT_SETTINGS, OME_SCRIPT_SETTINGS, false)); + if (!_networking || _network_server) { + list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_AI_SETTINGS, OME_AI_SETTINGS, false)); + list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS, OME_GAMESCRIPT_SETTINGS, false)); + } list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false)); list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false)); list.emplace_back(new DropDownListItem(-1, false)); @@ -350,7 +360,8 @@ static CallBackFunction MenuClickSettings(int index) switch (index) { case OME_GAMEOPTIONS: ShowGameOptions(); return CBF_NONE; case OME_SETTINGS: ShowGameSettings(); return CBF_NONE; - case OME_SCRIPT_SETTINGS: ShowAIConfigWindow(); return CBF_NONE; + case OME_AI_SETTINGS: ShowAIConfigWindow(); return CBF_NONE; + case OME_GAMESCRIPT_SETTINGS: ShowGSConfigWindow(); return CBF_NONE; case OME_NEWGRFSETTINGS: ShowNewGRFSettings(!_networking && _settings_client.gui.UserIsAllowedToChangeNewGRFs(), true, true, &_grfconfig); return CBF_NONE; case OME_TRANSPARENCIES: ShowTransparencyToolbar(); break; @@ -663,60 +674,97 @@ static CallBackFunction MenuClickGoal(int index) return CBF_NONE; } -/* --- Graphs button menu --- */ - -static CallBackFunction ToolbarGraphsClick(Window *w) -{ - PopupMainToolbMenu(w, WID_TN_GRAPHS, STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, (_toolbar_mode == TB_NORMAL) ? 6 : 8); - return CBF_NONE; -} +/* --- Graphs and League Table button menu --- */ /** - * Handle click on the entry in the Graphs menu. - * - * @param index Graph to show. - * @return #CBF_NONE + * Enum for the League Toolbar's and Graph Toolbar's related buttons. + * Use continuous numbering as League Toolbar can be combined into the Graph Toolbar. */ -static CallBackFunction MenuClickGraphs(int index) -{ - switch (index) { - case 0: ShowOperatingProfitGraph(); break; - case 1: ShowIncomeGraph(); break; - case 2: ShowDeliveredCargoGraph(); break; - case 3: ShowPerformanceHistoryGraph(); break; - case 4: ShowCompanyValueGraph(); break; - case 5: ShowCargoPaymentRates(); break; - /* functions for combined graphs/league button */ - case 6: ShowCompanyLeagueTable(); break; - case 7: ShowPerformanceRatingDetail(); break; +static const int GRMN_OPERATING_PROFIT_GRAPH = -1; ///< Show operating profit graph +static const int GRMN_INCOME_GRAPH = -2; ///< Show income graph +static const int GRMN_DELIVERED_CARGO_GRAPH = -3; ///< Show delivered cargo graph +static const int GRMN_PERFORMANCE_HISTORY_GRAPH = -4; ///< Show performance history graph +static const int GRMN_COMPANY_VALUE_GRAPH = -5; ///< Show company value graph +static const int GRMN_CARGO_PAYMENT_RATES = -6; ///< Show cargo payment rates graph +static const int LTMN_PERFORMANCE_LEAGUE = -7; ///< Show default league table +static const int LTMN_PERFORMANCE_RATING = -8; ///< Show detailed performance rating +static const int LTMN_HIGHSCORE = -9; ///< Show highscrore table + +static void AddDropDownLeagueTableOptions(DropDownList &list) { + if (LeagueTable::GetNumItems() > 0) { + for (LeagueTable *lt : LeagueTable::Iterate()) { + list.emplace_back(new DropDownListCharStringItem(lt->title, lt->index, false)); + } + } else { + list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, LTMN_PERFORMANCE_LEAGUE, false)); + list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_DETAILED_PERFORMANCE_RATING, LTMN_PERFORMANCE_RATING, false)); + if (!_networking) { + list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_HIGHSCORE, LTMN_HIGHSCORE, false)); + } } - return CBF_NONE; } -/* --- League button menu --- */ +static CallBackFunction ToolbarGraphsClick(Window *w) +{ + DropDownList list; + + list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_OPERATING_PROFIT_GRAPH, GRMN_OPERATING_PROFIT_GRAPH, false)); + list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_INCOME_GRAPH, GRMN_INCOME_GRAPH, false)); + list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_DELIVERED_CARGO_GRAPH, GRMN_DELIVERED_CARGO_GRAPH, false)); + list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_PERFORMANCE_HISTORY_GRAPH, GRMN_PERFORMANCE_HISTORY_GRAPH, false)); + list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_COMPANY_VALUE_GRAPH, GRMN_COMPANY_VALUE_GRAPH, false)); + list.emplace_back(new DropDownListStringItem(STR_GRAPH_MENU_CARGO_PAYMENT_RATES, GRMN_CARGO_PAYMENT_RATES, false)); + + if (_toolbar_mode != TB_NORMAL) AddDropDownLeagueTableOptions(list); + + ShowDropDownList(w, std::move(list), GRMN_OPERATING_PROFIT_GRAPH, WID_TN_GRAPHS, 140, true, true); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + + return CBF_NONE; +} static CallBackFunction ToolbarLeagueClick(Window *w) { - PopupMainToolbMenu(w, WID_TN_LEAGUE, STR_GRAPH_MENU_COMPANY_LEAGUE_TABLE, _networking ? 2 : 3); + DropDownList list; + + AddDropDownLeagueTableOptions(list); + + int selected = list[0]->result; + ShowDropDownList(w, std::move(list), selected, WID_TN_LEAGUE, 140, true, true); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + return CBF_NONE; } /** - * Handle click on the entry in the CompanyLeague menu. + * Handle click on the entry in the Graphs or CompanyLeague. * - * @param index Menu entry number. + * @param index Graph to show. * @return #CBF_NONE */ -static CallBackFunction MenuClickLeague(int index) +static CallBackFunction MenuClickGraphsOrLeague(int index) { switch (index) { - case 0: ShowCompanyLeagueTable(); break; - case 1: ShowPerformanceRatingDetail(); break; - case 2: ShowHighscoreTable(); break; + case GRMN_OPERATING_PROFIT_GRAPH: ShowOperatingProfitGraph(); break; + case GRMN_INCOME_GRAPH: ShowIncomeGraph(); break; + case GRMN_DELIVERED_CARGO_GRAPH: ShowDeliveredCargoGraph(); break; + case GRMN_PERFORMANCE_HISTORY_GRAPH: ShowPerformanceHistoryGraph(); break; + case GRMN_COMPANY_VALUE_GRAPH: ShowCompanyValueGraph(); break; + case GRMN_CARGO_PAYMENT_RATES: ShowCargoPaymentRates(); break; + case LTMN_PERFORMANCE_LEAGUE: ShowPerformanceLeagueTable(); break; + case LTMN_PERFORMANCE_RATING: ShowPerformanceRatingDetail(); break; + case LTMN_HIGHSCORE: ShowHighscoreTable(); break; + default: { + if (LeagueTable::IsValidID(index)) { + ShowScriptLeagueTable((LeagueTableID)index); + } + } } return CBF_NONE; } + + /* --- Industries button menu --- */ static CallBackFunction ToolbarIndustryClick(Window *w) @@ -837,7 +885,7 @@ static CallBackFunction MenuClickShowAir(int index) static CallBackFunction ToolbarZoomInClick(Window *w) { - if (DoZoomInOutWindow(ZOOM_IN, FindWindowById(WC_MAIN_WINDOW, 0))) { + if (DoZoomInOutWindow(ZOOM_IN, GetMainWindow())) { w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)WID_TE_ZOOM_IN : (byte)WID_TN_ZOOM_IN); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); } @@ -848,7 +896,7 @@ static CallBackFunction ToolbarZoomInClick(Window *w) static CallBackFunction ToolbarZoomOutClick(Window *w) { - if (DoZoomInOutWindow(ZOOM_OUT, FindWindowById(WC_MAIN_WINDOW, 0))) { + if (DoZoomInOutWindow(ZOOM_OUT, GetMainWindow())) { w->HandleButtonClick((_game_mode == GM_EDITOR) ? (byte)WID_TE_ZOOM_OUT : (byte)WID_TN_ZOOM_OUT); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); } @@ -1116,7 +1164,7 @@ static CallBackFunction MenuClickHelp(int index) switch (index) { case 0: return PlaceLandBlockInfo(); case 2: IConsoleSwitch(); break; - case 3: ShowAIDebugWindow(); break; + case 3: ShowScriptDebugWindow(); break; case 4: ShowScreenshotWindow(); break; case 5: ShowFramerateWindow(); break; case 6: ShowAboutWindow(); break; @@ -1152,7 +1200,6 @@ static CallBackFunction ToolbarScenDatePanel(Window *w) { SetDParam(0, _settings_game.game_creation.starting_year); ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, w, CS_NUMERAL, QSF_ENABLE_DEFAULT); - _left_button_clicked = false; return CBF_NONE; } @@ -1291,8 +1338,8 @@ static MenuClickedProc * const _menu_clicked_procs[] = { MenuClickCompany, // 9 MenuClickStory, // 10 MenuClickGoal, // 11 - MenuClickGraphs, // 12 - MenuClickLeague, // 13 + MenuClickGraphsOrLeague, // 12 + MenuClickGraphsOrLeague, // 13 MenuClickIndustry, // 14 MenuClickShowTrains, // 15 MenuClickShowRoad, // 16 @@ -1346,10 +1393,10 @@ class NWidgetToolbarContainer : public NWidgetContainer { /* First initialise some variables... */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical()); if (this->IsButton(child_wid->type)) { nbuttons++; - this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right); + this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal()); } else if (child_wid->type == NWID_SPACER) { this->spacers++; } @@ -2012,7 +2059,7 @@ struct MainToolbarWindow : Window { case MTHK_STORY: ShowStoryBook(_local_company); break; case MTHK_GOAL: ShowGoalsList(_local_company); break; case MTHK_GRAPHS: ShowOperatingProfitGraph(); break; - case MTHK_LEAGUE: ShowCompanyLeagueTable(); break; + case MTHK_LEAGUE: ShowFirstLeagueTable(); break; case MTHK_INDUSTRIES: ShowBuildIndustryWindow(); break; case MTHK_TRAIN_LIST: ShowVehicleListWindow(_local_company, VEH_TRAIN); break; case MTHK_ROADVEH_LIST: ShowVehicleListWindow(_local_company, VEH_ROAD); break; @@ -2027,7 +2074,7 @@ struct MainToolbarWindow : Window { case MTHK_BUILD_AIRPORT: ShowBuildAirToolbar(); break; case MTHK_BUILD_TREES: ShowBuildTreesToolbar(); break; case MTHK_MUSIC: ShowMusicWindow(); break; - case MTHK_AI_DEBUG: ShowAIDebugWindow(); break; + case MTHK_SCRIPT_DEBUG: ShowScriptDebugWindow(); break; case MTHK_SMALL_SCREENSHOT: MakeScreenshotWithConfirm(SC_VIEWPORT); break; case MTHK_ZOOMEDIN_SCREENSHOT: MakeScreenshotWithConfirm(SC_ZOOMEDIN); break; case MTHK_DEFAULTZOOM_SCREENSHOT: MakeScreenshotWithConfirm(SC_DEFAULTZOOM); break; @@ -2100,7 +2147,7 @@ struct MainToolbarWindow : Window { void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; - if (FindWindowById(WC_MAIN_WINDOW, 0) != nullptr) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT); + HandleZoomMessage(this, GetMainWindow()->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT); } static HotkeyList hotkeys; @@ -2141,7 +2188,7 @@ static Hotkey maintoolbar_hotkeys[] = { Hotkey(WKC_SHIFT | WKC_F10, "build_airport", MTHK_BUILD_AIRPORT), Hotkey(WKC_SHIFT | WKC_F11, "build_trees", MTHK_BUILD_TREES), Hotkey(WKC_SHIFT | WKC_F12, "music", MTHK_MUSIC), - Hotkey((uint16)0, "ai_debug", MTHK_AI_DEBUG), + Hotkey((uint16)0, "ai_debug", MTHK_SCRIPT_DEBUG), Hotkey(WKC_CTRL | 'S', "small_screenshot", MTHK_SMALL_SCREENSHOT), Hotkey(WKC_CTRL | 'P', "zoomedin_screenshot", MTHK_ZOOMEDIN_SCREENSHOT), Hotkey(WKC_CTRL | 'D', "defaultzoom_screenshot", MTHK_DEFAULTZOOM_SCREENSHOT), @@ -2337,19 +2384,23 @@ struct ScenarioEditorToolbarWindow : Window { this->DrawWidgets(); } - void DrawWidget(const Rect &r, int widget) const override + void SetStringParameters(int widget) const override { switch (widget) { case WID_TE_DATE: SetDParam(0, ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1)); - DrawString(r.left, r.right, (this->height - FONT_HEIGHT_NORMAL) / 2, STR_WHITE_DATE_LONG, TC_FROMSTRING, SA_HOR_CENTER); break; + } + } + void DrawWidget(const Rect &r, int widget) const override + { + switch (widget) { case WID_TE_SPACER: { - int height = r.bottom - r.top; + int height = r.Height(); if (height > 2 * FONT_HEIGHT_NORMAL) { - DrawString(r.left, r.right, (height + 1) / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_HOR_CENTER); - DrawString(r.left, r.right, (height + 1) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(r.left, r.right, height / 2 - FONT_HEIGHT_NORMAL, STR_SCENEDIT_TOOLBAR_OPENTTD, TC_FROMSTRING, SA_HOR_CENTER); + DrawString(r.left, r.right, height / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER); } else { DrawString(r.left, r.right, (height - FONT_HEIGHT_NORMAL) / 2, STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR, TC_FROMSTRING, SA_HOR_CENTER); } @@ -2362,13 +2413,12 @@ struct ScenarioEditorToolbarWindow : Window { { switch (widget) { case WID_TE_SPACER: - size->width = std::max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD).width, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + size->width = std::max(GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_OPENTTD).width, GetStringBoundingBox(STR_SCENEDIT_TOOLBAR_SCENARIO_EDITOR).width) + padding.width; break; case WID_TE_DATE: SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1)); *size = GetStringBoundingBox(STR_WHITE_DATE_LONG); - size->height = std::max(size->height, GetSpriteSize(SPR_IMG_SAVE).height + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM); break; } } @@ -2471,7 +2521,7 @@ struct ScenarioEditorToolbarWindow : Window { void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; - if (FindWindowById(WC_MAIN_WINDOW, 0) != nullptr) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT); + HandleZoomMessage(this, GetMainWindow()->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT); } void OnQueryTextFinished(char *str) override @@ -2531,10 +2581,10 @@ static const NWidgetPart _nested_toolb_scen_inner_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_SPACER), EndContainer(), NWidget(NWID_SPACER), NWidget(WWT_PANEL, COLOUR_GREY, WID_TE_DATE_PANEL), - NWidget(NWID_HORIZONTAL), SetPIP(3, 2, 3), - NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_BACKWARD), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD), - NWidget(WWT_EMPTY, COLOUR_GREY, WID_TE_DATE), SetDataTip(STR_NULL, STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE), - NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_FORWARD), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), + NWidget(NWID_HORIZONTAL), SetPIP(2, 2, 2), SetPadding(1), + NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_BACKWARD), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD), SetFill(0, 1), + NWidget(WWT_TEXT, COLOUR_GREY, WID_TE_DATE), SetDataTip(STR_WHITE_DATE_LONG, STR_SCENEDIT_TOOLBAR_TOOLTIP_SET_DATE), SetAlignment(SA_CENTER), SetFill(0, 1), + NWidget(WWT_IMGBTN, COLOUR_GREY, WID_TE_DATE_FORWARD), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1), EndContainer(), EndContainer(), NWidget(NWID_SPACER), diff --git a/src/toolbar_gui.h b/src/toolbar_gui.h index 5b8000f0c19fb..cede0a7c19808 100644 --- a/src/toolbar_gui.h +++ b/src/toolbar_gui.h @@ -41,7 +41,7 @@ enum MainToolbarHotkeys { MTHK_BUILD_TREES, MTHK_MUSIC, MTHK_LANDINFO, - MTHK_AI_DEBUG, + MTHK_SCRIPT_DEBUG, MTHK_SMALL_SCREENSHOT, MTHK_ZOOMEDIN_SCREENSHOT, MTHK_DEFAULTZOOM_SCREENSHOT, diff --git a/src/town.h b/src/town.h index 4560c67710a61..19e199951f9e9 100644 --- a/src/town.h +++ b/src/town.h @@ -200,18 +200,6 @@ Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX); void ResetHouses(); -void ClearTownHouse(Town *t, TileIndex tile); -void UpdateTownMaxPass(Town *t); -void UpdateTownRadius(Town *t); -CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags); -Town *ClosestTownFromTile(TileIndex tile, uint threshold); -void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags); -HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile); -void SetTownRatingTestMode(bool mode); -uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t); -bool GenerateTowns(TownLayout layout); -const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect); - /** Town actions of a company. */ enum TownActions { TACT_NONE = 0x00, ///< Empty action set. @@ -234,6 +222,18 @@ enum TownActions { }; DECLARE_ENUM_AS_BIT_SET(TownActions) +void ClearTownHouse(Town *t, TileIndex tile); +void UpdateTownMaxPass(Town *t); +void UpdateTownRadius(Town *t); +CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags); +Town *ClosestTownFromTile(TileIndex tile, uint threshold); +void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags); +HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile); +void SetTownRatingTestMode(bool mode); +TownActions GetMaskOfTownActions(CompanyID cid, const Town *t); +bool GenerateTowns(TownLayout layout); +const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect); + extern const byte _town_action_costs[TACT_COUNT]; /** diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index ef771bc12b82f..234c6ddf9b1ea 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -93,7 +93,7 @@ static bool TestTownOwnsBridge(TileIndex tile, const Town *t) if (!town_owned) { /* Or other adjacent road */ - TileIndex adjacent = tile + TileOffsByDiagDir(ReverseDiagDir(GetTunnelBridgeDirection(GetOtherTunnelBridgeEnd(tile)))); + adjacent = tile + TileOffsByDiagDir(ReverseDiagDir(GetTunnelBridgeDirection(GetOtherTunnelBridgeEnd(tile)))); town_owned = IsTileType(adjacent, MP_ROAD) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index; } @@ -121,7 +121,7 @@ Town::~Town() #endif /* WITH_ASSERT */ /* Check no tile is related to us. */ - for (TileIndex tile = 0; tile < MapSize(); ++tile) { + for (TileIndex tile = 0; tile < Map::Size(); ++tile) { switch (GetTileType(tile)) { case MP_HOUSE: assert(GetTownIndex(tile) != this->index); @@ -408,7 +408,7 @@ void Town::UpdateVirtCoord() SetDParam(1, this->cache.population); this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_LVL_BASE, _settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN, - STR_VIEWPORT_TOWN); + STR_VIEWPORT_TOWN_TINY_WHITE); _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeTown(this->index)); @@ -974,7 +974,7 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir) static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir) { - assert(tile < MapSize()); + assert(tile < Map::Size()); CommandCost r = std::get<0>(Command::Do(DC_AUTO | DC_NO_WATER, tile, edges, dir)); if (r.Failed() || r.GetCost() >= (_price[PR_TERRAFORM] + 2) * 8) return false; @@ -984,7 +984,7 @@ static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir) static void LevelTownLand(TileIndex tile) { - assert(tile < MapSize()); + assert(tile < Map::Size()); /* Don't terraform if land is plain or if there's a house there. */ if (IsTileType(tile, MP_HOUSE)) return; @@ -1160,6 +1160,27 @@ static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, con return Command::Do(DC_AUTO | DC_NO_WATER, next_tile, rcmd, rt, DRD_NONE, t->index).Succeeded(); } +/** + * CircularTileSearch proc which checks for a nearby parallel bridge to avoid building redundant bridges. + * @param tile The tile to search. + * @param user_data Reference to the valid direction of the proposed bridge. + * @return true if another bridge exists, else false. + */ +static bool RedundantBridgeExistsNearby(TileIndex tile, void *user_data) +{ + /* Don't look into the void. */ + if (!IsValidTile(tile)) return false; + + /* Only consider bridge head tiles. */ + if (!IsBridgeTile(tile)) return false; + + /* Only consider road bridges. */ + if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return false; + + /* If the bridge is facing the same direction as the proposed bridge, we've found a redundant bridge. */ + return (GetTileSlope(tile) & InclinedSlope(ReverseDiagDir(*(DiagDirection *)user_data))); +} + /** * Grows the town with a bridge. * At first we check if a bridge is reasonable. @@ -1221,6 +1242,11 @@ static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDi /* Make sure the road can be continued past the bridge. At this point, bridge_tile holds the end tile of the bridge. */ if (!CanRoadContinueIntoNextTile(t, bridge_tile, bridge_dir)) return false; + /* If another parallel bridge exists nearby, this one would be redundant and shouldn't be built. We don't care about flat bridges. */ + TileIndex search = tile; + DiagDirection direction_to_match = bridge_dir; + if (slope != SLOPE_FLAT && CircularTileSearch(&search, bridge_length, 0, 0, RedundantBridgeExistsNearby, &direction_to_match)) return false; + for (uint8 times = 0; times <= 22; times++) { byte bridge_type = RandomRange(MAX_BRIDGES - 1); @@ -1358,7 +1384,7 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t RoadBits rcmd = ROAD_NONE; // RoadBits for the road construction command TileIndex tile = *tile_ptr; // The main tile on which we base our growth - assert(tile < MapSize()); + assert(tile < Map::Size()); if (cur_rb == ROAD_NONE) { /* Tile has no road. First reset the status counter @@ -1606,7 +1632,7 @@ static bool GrowTownAtRoad(Town *t, TileIndex tile) */ DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town - assert(tile < MapSize()); + assert(tile < Map::Size()); /* Number of times to search. * Better roads, 2X2 and 3X3 grid grow quite fast so we give @@ -2205,7 +2231,7 @@ bool GenerateTowns(TownLayout layout) { uint current_number = 0; uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.number_towns : 0; - uint total = (difficulty == (uint)CUSTOM_TOWN_NUMBER_DIFFICULTY) ? _settings_game.game_creation.custom_town_number : ScaleByMapSize(_num_initial_towns[difficulty] + (Random() & 7)); + uint total = (difficulty == (uint)CUSTOM_TOWN_NUMBER_DIFFICULTY) ? _settings_game.game_creation.custom_town_number : Map::ScaleBySize(_num_initial_towns[difficulty] + (Random() & 7)); total = std::min(TownPool::MAX_SIZE, total); uint32 townnameparts; TownNames town_names; @@ -2219,7 +2245,7 @@ bool GenerateTowns(TownLayout layout) bool city = (_settings_game.economy.larger_towns != 0 && Chance16(1, _settings_game.economy.larger_towns)); IncreaseGeneratingWorldProgress(GWP_TOWN); /* Get a unique name for the town. */ - if (!GenerateTownName(&townnameparts, &town_names)) continue; + if (!GenerateTownName(_random, &townnameparts, &town_names)) continue; /* try 20 times to create a random-sized town for the first loop. */ if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag. } while (--total); @@ -2233,7 +2259,7 @@ bool GenerateTowns(TownLayout layout) /* If current_number is still zero at this point, it means that not a single town has been created. * So give it a last try, but now more aggressive */ - if (GenerateTownName(&townnameparts) && + if (GenerateTownName(_random, &townnameparts) && CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) { return true; } @@ -2630,15 +2656,15 @@ static bool BuildTownHouse(Town *t, TileIndex tile) byte construction_stage = 0; if (_generating_world || _game_mode == GM_EDITOR) { - uint32 r = Random(); + uint32 construction_random = Random(); construction_stage = TOWN_HOUSE_COMPLETED; - if (Chance16(1, 7)) construction_stage = GB(r, 0, 2); + if (Chance16(1, 7)) construction_stage = GB(construction_random, 0, 2); if (construction_stage == TOWN_HOUSE_COMPLETED) { ChangePopulation(t, hs->population); } else { - construction_counter = GB(r, 2, 2); + construction_counter = GB(construction_random, 2, 2); } } @@ -2965,7 +2991,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id) * 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 current_tile = 0; current_tile < MapSize(); ++current_tile) { + for (TileIndex current_tile = 0; current_tile < Map::Size(); ++current_tile) { if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) { CommandCost ret = Command::Do(flags, current_tile); if (ret.Failed()) return ret; @@ -2973,7 +2999,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id) } /* Check all remaining tiles for town ownership. */ - for (TileIndex current_tile = 0; current_tile < MapSize(); ++current_tile) { + for (TileIndex current_tile = 0; current_tile < Map::Size(); ++current_tile) { bool try_clear = false; switch (GetTileType(current_tile)) { case MP_ROAD: @@ -3267,21 +3293,19 @@ static TownActionProc * const _town_action_proc[] = { /** * Get a list of available actions to do at a town. - * @param nump if not nullptr add put the number of available actions in it * @param cid the company that is querying the town * @param t the town that is queried * @return bitmasked value of enabled actions */ -uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t) +TownActions GetMaskOfTownActions(CompanyID cid, const Town *t) { - int num = 0; TownActions buttons = TACT_NONE; /* Spectators and unwanted have no options */ if (cid != COMPANY_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[cid])) { - /* Things worth more than this are not shown */ - Money avail = Company::Get(cid)->money + _price[PR_STATION_VALUE] * 200; + /* Actions worth more than this are not able to be performed */ + Money avail = Company::Get(cid)->money; /* Check the action bits for validity and * if they are valid add them */ @@ -3305,12 +3329,10 @@ uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t) if (avail >= _town_action_costs[i] * _price[PR_TOWN_ACTION] >> 8) { buttons |= cur; - num++; } } } - if (nump != nullptr) *nump = num; return buttons; } @@ -3328,7 +3350,7 @@ CommandCost CmdDoTownAction(DoCommandFlag flags, TownID town_id, uint8 action) Town *t = Town::GetIfValid(town_id); if (t == nullptr || action >= lengthof(_town_action_proc)) return CMD_ERROR; - if (!HasBit(GetMaskOfTownActions(nullptr, _current_company, t), action)) return CMD_ERROR; + if (!HasBit(GetMaskOfTownActions(_current_company, t), action)) return CMD_ERROR; CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * _town_action_costs[action] >> 8); @@ -3736,7 +3758,7 @@ void TownsMonthlyLoop() void TownsYearlyLoop() { /* Increment house ages */ - for (TileIndex t = 0; t < MapSize(); t++) { + for (TileIndex t = 0; t < Map::Size(); t++) { if (!IsTileType(t, MP_HOUSE)) continue; IncrementHouseAge(t); } diff --git a/src/town_cmd.h b/src/town_cmd.h index 74af1e10e14f2..52ea486c93c5b 100644 --- a/src/town_cmd.h +++ b/src/town_cmd.h @@ -28,7 +28,7 @@ CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id); DEF_CMD_TRAIT(CMD_FOUND_TOWN, CmdFoundTown, CMD_DEITY | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // founding random town can fail only in exec run DEF_CMD_TRAIT(CMD_RENAME_TOWN, CmdRenameTown, CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_DO_TOWN_ACTION, CmdDoTownAction, 0, CMDT_LANDSCAPE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_DO_TOWN_ACTION, CmdDoTownAction, CMD_LOCATION, CMDT_LANDSCAPE_CONSTRUCTION) DEF_CMD_TRAIT(CMD_TOWN_CARGO_GOAL, CmdTownCargoGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT) DEF_CMD_TRAIT(CMD_TOWN_GROWTH_RATE, CmdTownGrowthRate, CMD_DEITY, CMDT_OTHER_MANAGEMENT) DEF_CMD_TRAIT(CMD_TOWN_RATING, CmdTownRating, CMD_DEITY, CMDT_OTHER_MANAGEMENT) diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 6206ffc894e02..9076b0b56d4c6 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -40,6 +40,7 @@ #include "table/strings.h" #include "safeguards.h" +#include "zoom_func.h" TownKdtree _town_local_authority_kdtree(&Kdtree_TownXYFunc); @@ -49,16 +50,13 @@ static const NWidgetPart _nested_town_authority_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_BROWN), NWidget(WWT_CAPTION, COLOUR_BROWN, WID_TA_CAPTION), SetDataTip(STR_LOCAL_AUTHORITY_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), - NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TA_ZONE_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_LOCAL_AUTHORITY_ZONE, STR_LOCAL_AUTHORITY_ZONE_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TA_ZONE_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_LOCAL_AUTHORITY_ZONE, STR_LOCAL_AUTHORITY_ZONE_TOOLTIP), NWidget(WWT_SHADEBOX, COLOUR_BROWN), NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN), NWidget(WWT_STICKYBOX, COLOUR_BROWN), EndContainer(), NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_RATING_INFO), SetMinimalSize(317, 92), SetResize(1, 1), EndContainer(), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_COMMAND_LIST), SetMinimalSize(305, 52), SetResize(1, 0), SetDataTip(0x0, STR_LOCAL_AUTHORITY_ACTIONS_TOOLTIP), SetScrollbar(WID_TA_SCROLLBAR), EndContainer(), - NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_TA_SCROLLBAR), - EndContainer(), + NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_COMMAND_LIST), SetMinimalSize(317, 52), SetResize(1, 0), SetDataTip(0x0, STR_LOCAL_AUTHORITY_ACTIONS_TOOLTIP), EndContainer(), NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_ACTION_INFO), SetMinimalSize(317, 52), SetResize(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TA_EXECUTE), SetMinimalSize(317, 12), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_LOCAL_AUTHORITY_DO_IT_BUTTON, STR_LOCAL_AUTHORITY_DO_IT_TOOLTIP), @@ -71,22 +69,25 @@ struct TownAuthorityWindow : Window { private: Town *town; ///< Town being displayed. int sel_index; ///< Currently selected town action, \c 0 to \c TACT_COUNT-1, \c -1 means no action selected. - Scrollbar *vscroll; uint displayed_actions_on_previous_painting; ///< Actions that were available on the previous call to OnPaint() + TownActions enabled_actions; ///< Actions that are enabled in settings. + TownActions available_actions; ///< Actions that are available to execute for the current company. + + Dimension icon_size; ///< Dimensions of company icon + Dimension exclusive_size; ///< Dimensions of exlusive icon /** * Get the position of the Nth set bit. * * If there is no Nth bit set return -1 * - * @param bits The value to search in * @param n The Nth set bit from which we want to know the position - * @return The position of the Nth set bit + * @return The position of the Nth set bit, or -1 if no Nth bit set. */ - static int GetNthSetBit(uint32 bits, int n) + int GetNthSetBit(int n) { if (n >= 0) { - for (uint i : SetBitIterator(bits)) { + for (uint i : SetBitIterator(this->enabled_actions)) { n--; if (n < 0) return i; } @@ -94,93 +95,126 @@ struct TownAuthorityWindow : Window { return -1; } + /** + * Gets all town authority actions enabled in settings. + * + * @return Bitmask of actions enabled in the settings. + */ + static TownActions GetEnabledActions() + { + TownActions enabled = TACT_ALL; + + if (!_settings_game.economy.fund_roads) CLRBITS(enabled, TACT_ROAD_REBUILD); + if (!_settings_game.economy.fund_buildings) CLRBITS(enabled, TACT_FUND_BUILDINGS); + if (!_settings_game.economy.exclusive_rights) CLRBITS(enabled, TACT_BUY_RIGHTS); + if (!_settings_game.economy.bribe) CLRBITS(enabled, TACT_BRIBE); + + return enabled; + } + public: - TownAuthorityWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc), sel_index(-1), displayed_actions_on_previous_painting(0) + TownAuthorityWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc), sel_index(-1), displayed_actions_on_previous_painting(0), available_actions(TACT_NONE) { this->town = Town::Get(window_number); + this->enabled_actions = GetEnabledActions(); this->InitNested(window_number); - this->vscroll = this->GetScrollbar(WID_TA_SCROLLBAR); - this->vscroll->SetCapacity((this->GetWidget(WID_TA_COMMAND_LIST)->current_y - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM) / FONT_HEIGHT_NORMAL); } - void OnPaint() override + void OnInit() override { - int numact; - uint buttons = GetMaskOfTownActions(&numact, _local_company, this->town); - if (buttons != displayed_actions_on_previous_painting) this->SetDirty(); - displayed_actions_on_previous_painting = buttons; - - this->vscroll->SetCount(numact + 1); + this->icon_size = GetSpriteSize(SPR_COMPANY_ICON); + this->exclusive_size = GetSpriteSize(SPR_EXCLUSIVE_TRANSPORT); + } - if (this->sel_index != -1 && !HasBit(buttons, this->sel_index)) { - this->sel_index = -1; - } + void OnPaint() override + { + this->available_actions = GetMaskOfTownActions(_local_company, this->town); + if (this->available_actions != displayed_actions_on_previous_painting) this->SetDirty(); + displayed_actions_on_previous_painting = this->available_actions; this->SetWidgetLoweredState(WID_TA_ZONE_BUTTON, this->town->show_zone); - this->SetWidgetDisabledState(WID_TA_EXECUTE, this->sel_index == -1); + this->SetWidgetDisabledState(WID_TA_EXECUTE, (this->sel_index == -1) || !HasBit(this->available_actions, this->sel_index)); this->DrawWidgets(); - if (!this->IsShaded()) this->DrawRatings(); + if (!this->IsShaded()) + { + this->DrawRatings(); + this->DrawActions(); + } } /** Draw the contents of the ratings panel. May request a resize of the window if the contents does not fit. */ void DrawRatings() { - NWidgetBase *nwid = this->GetWidget(WID_TA_RATING_INFO); - uint left = nwid->pos_x + WD_FRAMERECT_LEFT; - uint right = nwid->pos_x + nwid->current_x - 1 - WD_FRAMERECT_RIGHT; - - uint y = nwid->pos_y + WD_FRAMERECT_TOP; + Rect r = this->GetWidget(WID_TA_RATING_INFO)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); - DrawString(left, right, y, STR_LOCAL_AUTHORITY_COMPANY_RATINGS); - y += FONT_HEIGHT_NORMAL; + int text_y_offset = (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2; + int icon_y_offset = (this->resize.step_height - this->icon_size.height) / 2; + int exclusive_y_offset = (this->resize.step_height - this->exclusive_size.height) / 2; - Dimension icon_size = GetSpriteSize(SPR_COMPANY_ICON); - int icon_width = icon_size.width; - int icon_y_offset = (FONT_HEIGHT_NORMAL - icon_size.height) / 2; - - Dimension exclusive_size = GetSpriteSize(SPR_EXCLUSIVE_TRANSPORT); - int exclusive_width = exclusive_size.width; - int exclusive_y_offset = (FONT_HEIGHT_NORMAL - exclusive_size.height) / 2; + DrawString(r.left, r.right, r.top + text_y_offset, STR_LOCAL_AUTHORITY_COMPANY_RATINGS); + r.top += this->resize.step_height; bool rtl = _current_text_dir == TD_RTL; - uint text_left = left + (rtl ? 0 : icon_width + exclusive_width + 4); - uint text_right = right - (rtl ? icon_width + exclusive_width + 4 : 0); - uint icon_left = rtl ? right - icon_width : left; - uint exclusive_left = rtl ? right - icon_width - exclusive_width - 2 : left + icon_width + 2; + Rect icon = r.WithWidth(this->icon_size.width, rtl); + Rect exclusive = r.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal, rtl).WithWidth(this->exclusive_size.width, rtl); + Rect text = r.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal + this->exclusive_size.width + WidgetDimensions::scaled.hsep_normal, rtl); /* Draw list of companies */ for (const Company *c : Company::Iterate()) { if ((HasBit(this->town->have_ratings, c->index) || this->town->exclusivity == c->index)) { - DrawCompanyIcon(c->index, icon_left, y + icon_y_offset); + DrawCompanyIcon(c->index, icon.left, text.top + icon_y_offset); SetDParam(0, c->index); SetDParam(1, c->index); - int r = this->town->ratings[c->index]; + int rating = this->town->ratings[c->index]; StringID str = STR_CARGO_RATING_APPALLING; - if (r > RATING_APPALLING) str++; - if (r > RATING_VERYPOOR) str++; - if (r > RATING_POOR) str++; - if (r > RATING_MEDIOCRE) str++; - if (r > RATING_GOOD) str++; - if (r > RATING_VERYGOOD) str++; - if (r > RATING_EXCELLENT) str++; + if (rating > RATING_APPALLING) str++; + if (rating > RATING_VERYPOOR) str++; + if (rating > RATING_POOR) str++; + if (rating > RATING_MEDIOCRE) str++; + if (rating > RATING_GOOD) str++; + if (rating > RATING_VERYGOOD) str++; + if (rating > RATING_EXCELLENT) str++; SetDParam(2, str); if (this->town->exclusivity == c->index) { - DrawSprite(SPR_EXCLUSIVE_TRANSPORT, COMPANY_SPRITE_COLOUR(c->index), exclusive_left, y + exclusive_y_offset); + DrawSprite(SPR_EXCLUSIVE_TRANSPORT, COMPANY_SPRITE_COLOUR(c->index), exclusive.left, text.top + exclusive_y_offset); } - DrawString(text_left, text_right, y, STR_LOCAL_AUTHORITY_COMPANY_RATING); - y += FONT_HEIGHT_NORMAL; + DrawString(text.left, text.right, text.top + text_y_offset, STR_LOCAL_AUTHORITY_COMPANY_RATING); + text.top += this->resize.step_height; } } - y = y + WD_FRAMERECT_BOTTOM - nwid->pos_y; // Compute needed size of the widget. - if (y > nwid->current_y) { + text.bottom = text.top - 1; + if (text.bottom > r.bottom) { /* If the company list is too big to fit, mark ourself dirty and draw again. */ - ResizeWindow(this, 0, y - nwid->current_y, false); + ResizeWindow(this, 0, text.bottom - r.bottom, false); + } + } + + /** Draws the contents of the actions panel. May re-initialise window to resize panel, if the list does not fit. */ + void DrawActions() + { + Rect r = this->GetWidget(WID_TA_COMMAND_LIST)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect); + + DrawString(r, STR_LOCAL_AUTHORITY_ACTIONS_TITLE); + r.top += FONT_HEIGHT_NORMAL; + + /* Draw list of actions */ + for (int i = 0; i < TACT_COUNT; i++) { + /* Don't show actions if disabled in settings. */ + if (!HasBit(this->enabled_actions, i)) continue; + + /* Set colour of action based on ability to execute and if selected. */ + TextColour action_colour = TC_GREY | TC_NO_SHADE; + if (HasBit(this->available_actions, i)) action_colour = TC_ORANGE; + if (this->sel_index == i) action_colour = TC_WHITE; + + DrawString(r, STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i, action_colour); + r.top += FONT_HEIGHT_NORMAL; } } @@ -194,33 +228,15 @@ struct TownAuthorityWindow : Window { switch (widget) { case WID_TA_ACTION_INFO: if (this->sel_index != -1) { - SetDParam(0, _price[PR_TOWN_ACTION] * _town_action_costs[this->sel_index] >> 8); - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, - STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING + this->sel_index); - } - break; - case WID_TA_COMMAND_LIST: { - int numact; - uint buttons = GetMaskOfTownActions(&numact, _local_company, this->town); - int y = r.top + WD_FRAMERECT_TOP; - int pos = this->vscroll->GetPosition(); - - if (--pos < 0) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_LOCAL_AUTHORITY_ACTIONS_TITLE); - y += FONT_HEIGHT_NORMAL; - } + Money action_cost = _price[PR_TOWN_ACTION] * _town_action_costs[this->sel_index] >> 8; + bool affordable = Company::IsValidID(_local_company) && action_cost < Company::Get(_local_company)->money; - for (int i = 0; buttons; i++, buttons >>= 1) { - if (pos <= -5) break; ///< Draw only the 5 fitting lines - - if ((buttons & 1) && --pos < 0) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, - STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i, this->sel_index == i ? TC_WHITE : TC_ORANGE); - y += FONT_HEIGHT_NORMAL; - } + SetDParam(0, action_cost); + DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), + STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING + this->sel_index, + affordable ? TC_YELLOW : TC_RED); } break; - } } } @@ -229,31 +245,29 @@ struct TownAuthorityWindow : Window { switch (widget) { case WID_TA_ACTION_INFO: { assert(size->width > padding.width && size->height > padding.height); - size->width -= WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - size->height -= WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; Dimension d = {0, 0}; for (int i = 0; i < TACT_COUNT; i++) { SetDParam(0, _price[PR_TOWN_ACTION] * _town_action_costs[i] >> 8); d = maxdim(d, GetStringMultiLineBoundingBox(STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING + i, *size)); } + d.width += padding.width; + d.height += padding.height; *size = maxdim(*size, d); - size->width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - size->height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; break; } case WID_TA_COMMAND_LIST: - size->height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM; + size->height = (TACT_COUNT + 1) * FONT_HEIGHT_NORMAL + padding.height; size->width = GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTIONS_TITLE).width; for (uint i = 0; i < TACT_COUNT; i++ ) { size->width = std::max(size->width, GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + i).width); } - size->width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + size->width += padding.width; break; case WID_TA_RATING_INFO: - resize->height = FONT_HEIGHT_NORMAL; - size->height = WD_FRAMERECT_TOP + 9 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM; + resize->height = std::max({this->icon_size.height + WidgetDimensions::scaled.vsep_normal, this->exclusive_size.height + WidgetDimensions::scaled.vsep_normal, (uint)FONT_HEIGHT_NORMAL}); + size->height = 9 * resize->height + padding.height; break; } } @@ -274,16 +288,16 @@ struct TownAuthorityWindow : Window { } case WID_TA_COMMAND_LIST: { - int y = this->GetRowFromWidget(pt.y, WID_TA_COMMAND_LIST, 1, FONT_HEIGHT_NORMAL); - if (!IsInsideMM(y, 0, 5)) return; + int y = this->GetRowFromWidget(pt.y, WID_TA_COMMAND_LIST, 1, FONT_HEIGHT_NORMAL) - 1; - y = GetNthSetBit(GetMaskOfTownActions(nullptr, _local_company, this->town), y + this->vscroll->GetPosition() - 1); + y = GetNthSetBit(y); if (y >= 0) { this->sel_index = y; this->SetDirty(); } + /* When double-clicking, continue */ - if (click_count == 1 || y < 0) break; + if (click_count == 1 || y < 0 || !HasBit(this->available_actions, y)) break; FALLTHROUGH; } @@ -297,6 +311,16 @@ struct TownAuthorityWindow : Window { { this->SetDirty(); } + + void OnInvalidateData(int data = 0, bool gui_scope = true) override + { + if (!gui_scope) return; + + this->enabled_actions = this->GetEnabledActions(); + if (!HasBit(this->enabled_actions, this->sel_index)) { + this->sel_index = -1; + } + } }; static WindowDesc _town_authority_desc( @@ -331,7 +355,7 @@ struct TownViewWindow : Window { this->flags |= WF_DISABLE_VP_SCROLL; NWidgetViewport *nvp = this->GetWidget(WID_TV_VIEWPORT); - nvp->InitializeViewport(this, this->town->xy, ZOOM_LVL_NEWS); + nvp->InitializeViewport(this, this->town->xy, ScaleZoomGUI(ZOOM_LVL_TOWN)); /* disable renaming town in network games if you are not the server */ this->SetWidgetDisabledState(WID_TV_CHANGE_NAME, _networking && !_network_server); @@ -360,21 +384,24 @@ struct TownViewWindow : Window { { if (widget != WID_TV_INFO) return; - uint y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); SetDParam(0, this->town->cache.population); SetDParam(1, this->town->cache.num_houses); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y, STR_TOWN_VIEW_POPULATION_HOUSES); + DrawString(tr, STR_TOWN_VIEW_POPULATION_HOUSES); + tr.top += FONT_HEIGHT_NORMAL; SetDParam(0, 1 << CT_PASSENGERS); SetDParam(1, this->town->supplied[CT_PASSENGERS].old_act); SetDParam(2, this->town->supplied[CT_PASSENGERS].old_max); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX); + DrawString(tr, STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX); + tr.top += FONT_HEIGHT_NORMAL; SetDParam(0, 1 << CT_MAIL); SetDParam(1, this->town->supplied[CT_MAIL].old_act); SetDParam(2, this->town->supplied[CT_MAIL].old_max); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX); + DrawString(tr, STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX); + tr.top += FONT_HEIGHT_NORMAL; bool first = true; for (int i = TE_BEGIN; i < TE_END; i++) { @@ -383,13 +410,12 @@ struct TownViewWindow : Window { if (this->town->goal[i] == TOWN_GROWTH_DESERT && (GetTropicZone(this->town->xy) != TROPICZONE_DESERT || this->town->cache.population <= 60)) continue; if (first) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH); + DrawString(tr, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH); + tr.top += FONT_HEIGHT_NORMAL; first = false; } bool rtl = _current_text_dir == TD_RTL; - uint cargo_text_left = r.left + WD_FRAMERECT_LEFT + (rtl ? 0 : 20); - uint cargo_text_right = r.right - WD_FRAMERECT_RIGHT - (rtl ? 20 : 0); const CargoSpec *cargo = FindFirstCargoWithTownEffect((TownEffect)i); assert(cargo != nullptr); @@ -419,26 +445,30 @@ struct TownViewWindow : Window { SetDParam(2, cargo->Index()); SetDParam(3, this->town->goal[i]); } - DrawString(cargo_text_left, cargo_text_right, y += FONT_HEIGHT_NORMAL, string); + DrawString(tr.Indent(20, rtl), string); + tr.top += FONT_HEIGHT_NORMAL; } if (HasBit(this->town->flags, TOWN_IS_GROWING)) { SetDParam(0, RoundDivSU(this->town->growth_rate + 1, DAY_TICKS)); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED); + DrawString(tr, this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED); + tr.top += FONT_HEIGHT_NORMAL; } else { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_TOWN_GROW_STOPPED); + DrawString(tr, STR_TOWN_VIEW_TOWN_GROW_STOPPED); + tr.top += FONT_HEIGHT_NORMAL; } /* only show the town noise, if the noise option is activated. */ if (_settings_game.economy.station_noise_level) { SetDParam(0, this->town->noise_reached); SetDParam(1, this->town->MaxTownNoise()); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_NOISE_IN_TOWN); + DrawString(tr, STR_TOWN_VIEW_NOISE_IN_TOWN); + tr.top += FONT_HEIGHT_NORMAL; } if (!this->town->text.empty()) { SetDParamStr(0, this->town->text); - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y += FONT_HEIGHT_NORMAL, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); + tr.top = DrawStringMultiLine(tr, STR_JUST_RAW_STRING, TC_BLACK); } } @@ -489,7 +519,7 @@ struct TownViewWindow : Window { { switch (widget) { case WID_TV_INFO: - size->height = GetDesiredInfoHeight(size->width); + size->height = GetDesiredInfoHeight(size->width) + padding.height; break; } } @@ -500,7 +530,7 @@ struct TownViewWindow : Window { */ uint GetDesiredInfoHeight(int width) const { - uint aimed_height = 3 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + uint aimed_height = 3 * FONT_HEIGHT_NORMAL; bool first = true; for (int i = TE_BEGIN; i < TE_END; i++) { @@ -520,7 +550,7 @@ struct TownViewWindow : Window { if (!this->town->text.empty()) { SetDParamStr(0, this->town->text); - aimed_height += GetStringHeight(STR_JUST_RAW_STRING, width - WD_FRAMERECT_LEFT - WD_FRAMERECT_RIGHT); + aimed_height += GetStringHeight(STR_JUST_RAW_STRING, width - WidgetDimensions::scaled.framerect.Horizontal()); } return aimed_height; @@ -792,18 +822,17 @@ struct TownDirectoryWindow : public Window { case WID_TD_LIST: { int n = 0; - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); if (this->towns.size() == 0) { // No towns available. - DrawString(r.left + WD_FRAMERECT_LEFT, r.right, y, STR_TOWN_DIRECTORY_NONE); + DrawString(tr, STR_TOWN_DIRECTORY_NONE); break; } /* At least one town available. */ bool rtl = _current_text_dir == TD_RTL; Dimension icon_size = GetSpriteSize(SPR_TOWN_RATING_GOOD); - int text_left = r.left + WD_FRAMERECT_LEFT + (rtl ? 0 : icon_size.width + 2); - int text_right = r.right - WD_FRAMERECT_RIGHT - (rtl ? icon_size.width + 2 : 0); - int icon_x = rtl ? r.right - WD_FRAMERECT_RIGHT - icon_size.width : r.left + WD_FRAMERECT_LEFT; + int icon_x = tr.WithWidth(icon_size.width, rtl).left; + tr = tr.Indent(icon_size.width + WidgetDimensions::scaled.hsep_normal, rtl); for (uint i = this->vscroll->GetPosition(); i < this->towns.size(); i++) { const Town *t = this->towns[i]; @@ -811,19 +840,19 @@ struct TownDirectoryWindow : public Window { /* Draw rating icon. */ if (_game_mode == GM_EDITOR || !HasBit(t->have_ratings, _local_company)) { - DrawSprite(SPR_TOWN_RATING_NA, PAL_NONE, icon_x, y + (this->resize.step_height - icon_size.height) / 2); + DrawSprite(SPR_TOWN_RATING_NA, PAL_NONE, icon_x, tr.top + (this->resize.step_height - icon_size.height) / 2); } else { SpriteID icon = SPR_TOWN_RATING_APALLING; if (t->ratings[_local_company] > RATING_VERYPOOR) icon = SPR_TOWN_RATING_MEDIOCRE; if (t->ratings[_local_company] > RATING_GOOD) icon = SPR_TOWN_RATING_GOOD; - DrawSprite(icon, PAL_NONE, icon_x, y + (this->resize.step_height - icon_size.height) / 2); + DrawSprite(icon, PAL_NONE, icon_x, tr.top + (this->resize.step_height - icon_size.height) / 2); } SetDParam(0, t->index); SetDParam(1, t->cache.population); - DrawString(text_left, text_right, y + (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2, GetTownString(t)); + DrawString(tr.left, tr.right, tr.top + (this->resize.step_height - FONT_HEIGHT_NORMAL) / 2, GetTownString(t)); - y += this->resize.step_height; + tr.top += this->resize.step_height; if (++n == this->vscroll->GetCapacity()) break; // max number of towns in 1 window } break; @@ -867,8 +896,8 @@ struct TownDirectoryWindow : public Window { d.height = std::max(d.height, icon_size.height); resize->height = d.height; d.height *= 5; - d.width += padding.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; + d.width += padding.width; + d.height += padding.height; *size = maxdim(*size, d); break; } @@ -905,7 +934,7 @@ struct TownDirectoryWindow : public Window { break; case WID_TD_LIST: { // Click on Town Matrix - uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_TD_LIST, WD_FRAMERECT_TOP); + uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_TD_LIST, WidgetDimensions::scaled.framerect.top); if (id_v >= this->towns.size()) return; // click out of town bounds const Town *t = this->towns[id_v]; @@ -1037,7 +1066,9 @@ static const NWidgetPart _nested_found_town_widgets[] = { NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_RANDOM_TOWN), SetMinimalSize(156, 12), SetFill(1, 0), SetDataTip(STR_FOUND_TOWN_RANDOM_TOWN_BUTTON, STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP), SetPadding(0, 2, 1, 2), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_MANY_RANDOM_TOWNS), SetMinimalSize(156, 12), SetFill(1, 0), - SetDataTip(STR_FOUND_TOWN_MANY_RANDOM_TOWNS, STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP), SetPadding(0, 2, 0, 2), + SetDataTip(STR_FOUND_TOWN_MANY_RANDOM_TOWNS, STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP), SetPadding(0, 2, 1, 2), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_EXPAND_ALL_TOWNS), SetMinimalSize(156, 12), SetFill(1, 0), + SetDataTip(STR_FOUND_TOWN_EXPAND_ALL_TOWNS, STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP), SetPadding(0, 2, 0, 2), /* Town name selection. */ NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetMinimalSize(156, 14), SetPadding(0, 2, 0, 2), SetDataTip(STR_FOUND_TOWN_NAME_TITLE, STR_NULL), NWidget(WWT_EDITBOX, COLOUR_GREY, WID_TF_TOWN_NAME_EDITBOX), SetMinimalSize(156, 12), SetPadding(0, 2, 3, 2), @@ -1115,7 +1146,7 @@ struct FoundTownWindow : Window { void RandomTownName() { - this->townnamevalid = GenerateTownName(&this->townnameparts); + this->townnamevalid = GenerateTownName(_interactive_random, &this->townnameparts); if (!this->townnamevalid) { this->townname_editbox.text.DeleteAll(); @@ -1131,7 +1162,7 @@ struct FoundTownWindow : Window { void UpdateButtons(bool check_availability) { if (check_availability && _game_mode != GM_EDITOR) { - this->SetWidgetsDisabledState(true, WID_TF_RANDOM_TOWN, WID_TF_MANY_RANDOM_TOWNS, WID_TF_SIZE_LARGE, WIDGET_LIST_END); + this->SetWidgetsDisabledState(true, WID_TF_RANDOM_TOWN, WID_TF_MANY_RANDOM_TOWNS, WID_TF_EXPAND_ALL_TOWNS, WID_TF_SIZE_LARGE, WIDGET_LIST_END); this->SetWidgetsDisabledState(_settings_game.economy.found_town != TF_CUSTOM_LAYOUT, WID_TF_LAYOUT_ORIGINAL, WID_TF_LAYOUT_BETTER, WID_TF_LAYOUT_GRID2, WID_TF_LAYOUT_GRID3, WID_TF_LAYOUT_RANDOM, WIDGET_LIST_END); if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT) town_layout = _settings_game.economy.town_layout; @@ -1198,6 +1229,12 @@ struct FoundTownWindow : Window { break; } + case WID_TF_EXPAND_ALL_TOWNS: + for (Town *t : Town::Iterate()) { + Command::Do(DC_EXEC, t->index, 0); + } + break; + case WID_TF_SIZE_SMALL: case WID_TF_SIZE_MEDIUM: case WID_TF_SIZE_LARGE: case WID_TF_SIZE_RANDOM: this->town_size = (TownSize)(widget - WID_TF_SIZE_SMALL); this->UpdateButtons(false); diff --git a/src/town_map.h b/src/town_map.h index 248b1bd323361..42a2b5d04975d 100644 --- a/src/town_map.h +++ b/src/town_map.h @@ -19,10 +19,10 @@ * @pre IsTileType(t, MP_HOUSE) or IsTileType(t, MP_ROAD) but not a road depot * @return TownID */ -static inline TownID GetTownIndex(TileIndex t) +static inline TownID GetTownIndex(Tile t) { assert(IsTileType(t, MP_HOUSE) || (IsTileType(t, MP_ROAD) && !IsRoadDepot(t))); - return _m[t].m2; + return t.m2(); } /** @@ -31,10 +31,10 @@ static inline TownID GetTownIndex(TileIndex t) * @param index the index of the town * @pre IsTileType(t, MP_HOUSE) or IsTileType(t, MP_ROAD) but not a road depot */ -static inline void SetTownIndex(TileIndex t, TownID index) +static inline void SetTownIndex(Tile t, TownID index) { assert(IsTileType(t, MP_HOUSE) || (IsTileType(t, MP_ROAD) && !IsRoadDepot(t))); - _m[t].m2 = index; + t.m2() = index; } /** @@ -44,10 +44,10 @@ static inline void SetTownIndex(TileIndex t, TownID index) * @pre IsTileType(t, MP_HOUSE) * @return house type */ -static inline HouseID GetCleanHouseType(TileIndex t) +static inline HouseID GetCleanHouseType(Tile t) { assert(IsTileType(t, MP_HOUSE)); - return _m[t].m4 | (GB(_m[t].m3, 6, 1) << 8); + return t.m4() | (GB(t.m3(), 6, 1) << 8); } /** @@ -56,7 +56,7 @@ static inline HouseID GetCleanHouseType(TileIndex t) * @pre IsTileType(t, MP_HOUSE) * @return house type */ -static inline HouseID GetHouseType(TileIndex t) +static inline HouseID GetHouseType(Tile t) { return GetTranslatedHouseID(GetCleanHouseType(t)); } @@ -67,11 +67,11 @@ static inline HouseID GetHouseType(TileIndex t) * @param house_id the new house type * @pre IsTileType(t, MP_HOUSE) */ -static inline void SetHouseType(TileIndex t, HouseID house_id) +static inline void SetHouseType(Tile t, HouseID house_id) { assert(IsTileType(t, MP_HOUSE)); - _m[t].m4 = GB(house_id, 0, 8); - SB(_m[t].m3, 6, 1, GB(house_id, 8, 1)); + t.m4() = GB(house_id, 0, 8); + SB(t.m3(), 6, 1, GB(house_id, 8, 1)); } /** @@ -79,9 +79,9 @@ static inline void SetHouseType(TileIndex t, HouseID house_id) * @param t the tile * @return has destination */ -static inline bool LiftHasDestination(TileIndex t) +static inline bool LiftHasDestination(Tile t) { - return HasBit(_me[t].m7, 0); + return HasBit(t.m7(), 0); } /** @@ -90,10 +90,10 @@ static inline bool LiftHasDestination(TileIndex t) * @param t the tile * @param dest new destination */ -static inline void SetLiftDestination(TileIndex t, byte dest) +static inline void SetLiftDestination(Tile t, byte dest) { - SetBit(_me[t].m7, 0); - SB(_me[t].m7, 1, 3, dest); + SetBit(t.m7(), 0); + SB(t.m7(), 1, 3, dest); } /** @@ -101,9 +101,9 @@ static inline void SetLiftDestination(TileIndex t, byte dest) * @param t the tile * @return destination */ -static inline byte GetLiftDestination(TileIndex t) +static inline byte GetLiftDestination(Tile t) { - return GB(_me[t].m7, 1, 3); + return GB(t.m7(), 1, 3); } /** @@ -112,9 +112,9 @@ static inline byte GetLiftDestination(TileIndex t) * and the destination. * @param t the tile */ -static inline void HaltLift(TileIndex t) +static inline void HaltLift(Tile t) { - SB(_me[t].m7, 0, 4, 0); + SB(t.m7(), 0, 4, 0); } /** @@ -122,9 +122,9 @@ static inline void HaltLift(TileIndex t) * @param t the tile * @return position, from 0 to 36 */ -static inline byte GetLiftPosition(TileIndex t) +static inline byte GetLiftPosition(Tile t) { - return GB(_me[t].m6, 2, 6); + return GB(t.m6(), 2, 6); } /** @@ -132,9 +132,9 @@ static inline byte GetLiftPosition(TileIndex t) * @param t the tile * @param pos position, from 0 to 36 */ -static inline void SetLiftPosition(TileIndex t, byte pos) +static inline void SetLiftPosition(Tile t, byte pos) { - SB(_me[t].m6, 2, 6, pos); + SB(t.m6(), 2, 6, pos); } /** @@ -142,10 +142,10 @@ static inline void SetLiftPosition(TileIndex t, byte pos) * @param t the tile * @return true if it is, false if it is not */ -static inline bool IsHouseCompleted(TileIndex t) +static inline bool IsHouseCompleted(Tile t) { assert(IsTileType(t, MP_HOUSE)); - return HasBit(_m[t].m3, 7); + return HasBit(t.m3(), 7); } /** @@ -153,10 +153,10 @@ static inline bool IsHouseCompleted(TileIndex t) * @param t the tile * @param status */ -static inline void SetHouseCompleted(TileIndex t, bool status) +static inline void SetHouseCompleted(Tile t, bool status) { assert(IsTileType(t, MP_HOUSE)); - SB(_m[t].m3, 7, 1, !!status); + SB(t.m3(), 7, 1, !!status); } /** @@ -180,10 +180,10 @@ static inline void SetHouseCompleted(TileIndex t, bool status) * @pre IsTileType(t, MP_HOUSE) * @return the building stage of the house */ -static inline byte GetHouseBuildingStage(TileIndex t) +static inline byte GetHouseBuildingStage(Tile t) { assert(IsTileType(t, MP_HOUSE)); - return IsHouseCompleted(t) ? (byte)TOWN_HOUSE_COMPLETED : GB(_m[t].m5, 3, 2); + return IsHouseCompleted(t) ? (byte)TOWN_HOUSE_COMPLETED : GB(t.m5(), 3, 2); } /** @@ -192,10 +192,10 @@ static inline byte GetHouseBuildingStage(TileIndex t) * @pre IsTileType(t, MP_HOUSE) * @return the construction stage of the house */ -static inline byte GetHouseConstructionTick(TileIndex t) +static inline byte GetHouseConstructionTick(Tile t) { assert(IsTileType(t, MP_HOUSE)); - return IsHouseCompleted(t) ? 0 : GB(_m[t].m5, 0, 3); + return IsHouseCompleted(t) ? 0 : GB(t.m5(), 0, 3); } /** @@ -205,12 +205,12 @@ static inline byte GetHouseConstructionTick(TileIndex t) * @param t the tile of the house to increment the construction stage of * @pre IsTileType(t, MP_HOUSE) */ -static inline void IncHouseConstructionTick(TileIndex t) +static inline void IncHouseConstructionTick(Tile t) { assert(IsTileType(t, MP_HOUSE)); - AB(_m[t].m5, 0, 5, 1); + AB(t.m5(), 0, 5, 1); - if (GB(_m[t].m5, 3, 2) == TOWN_HOUSE_COMPLETED) { + if (GB(t.m5(), 3, 2) == TOWN_HOUSE_COMPLETED) { /* House is now completed. * Store the year of construction as well, for newgrf house purpose */ SetHouseCompleted(t, true); @@ -223,10 +223,10 @@ static inline void IncHouseConstructionTick(TileIndex t) * @param t the tile of this house * @pre IsTileType(t, MP_HOUSE) && IsHouseCompleted(t) */ -static inline void ResetHouseAge(TileIndex t) +static inline void ResetHouseAge(Tile t) { assert(IsTileType(t, MP_HOUSE) && IsHouseCompleted(t)); - _m[t].m5 = 0; + t.m5() = 0; } /** @@ -234,10 +234,10 @@ static inline void ResetHouseAge(TileIndex t) * @param t the tile of this house * @pre IsTileType(t, MP_HOUSE) */ -static inline void IncrementHouseAge(TileIndex t) +static inline void IncrementHouseAge(Tile t) { assert(IsTileType(t, MP_HOUSE)); - if (IsHouseCompleted(t) && _m[t].m5 < 0xFF) _m[t].m5++; + if (IsHouseCompleted(t) && t.m5() < 0xFF) t.m5()++; } /** @@ -246,10 +246,10 @@ static inline void IncrementHouseAge(TileIndex t) * @pre IsTileType(t, MP_HOUSE) * @return year */ -static inline Year GetHouseAge(TileIndex t) +static inline Year GetHouseAge(Tile t) { assert(IsTileType(t, MP_HOUSE)); - return IsHouseCompleted(t) ? _m[t].m5 : 0; + return IsHouseCompleted(t) ? t.m5() : 0; } /** @@ -259,10 +259,10 @@ static inline Year GetHouseAge(TileIndex t) * @param random the new random bits * @pre IsTileType(t, MP_HOUSE) */ -static inline void SetHouseRandomBits(TileIndex t, byte random) +static inline void SetHouseRandomBits(Tile t, byte random) { assert(IsTileType(t, MP_HOUSE)); - _m[t].m1 = random; + t.m1() = random; } /** @@ -272,10 +272,10 @@ static inline void SetHouseRandomBits(TileIndex t, byte random) * @pre IsTileType(t, MP_HOUSE) * @return random bits */ -static inline byte GetHouseRandomBits(TileIndex t) +static inline byte GetHouseRandomBits(Tile t) { assert(IsTileType(t, MP_HOUSE)); - return _m[t].m1; + return t.m1(); } /** @@ -285,10 +285,10 @@ static inline byte GetHouseRandomBits(TileIndex t) * @param triggers the activated triggers * @pre IsTileType(t, MP_HOUSE) */ -static inline void SetHouseTriggers(TileIndex t, byte triggers) +static inline void SetHouseTriggers(Tile t, byte triggers) { assert(IsTileType(t, MP_HOUSE)); - SB(_m[t].m3, 0, 5, triggers); + SB(t.m3(), 0, 5, triggers); } /** @@ -298,10 +298,10 @@ static inline void SetHouseTriggers(TileIndex t, byte triggers) * @pre IsTileType(t, MP_HOUSE) * @return triggers */ -static inline byte GetHouseTriggers(TileIndex t) +static inline byte GetHouseTriggers(Tile t) { assert(IsTileType(t, MP_HOUSE)); - return GB(_m[t].m3, 0, 5); + return GB(t.m3(), 0, 5); } /** @@ -310,10 +310,10 @@ static inline byte GetHouseTriggers(TileIndex t) * @pre IsTileType(t, MP_HOUSE) * @return time remaining */ -static inline byte GetHouseProcessingTime(TileIndex t) +static inline byte GetHouseProcessingTime(Tile t) { assert(IsTileType(t, MP_HOUSE)); - return GB(_me[t].m6, 2, 6); + return GB(t.m6(), 2, 6); } /** @@ -322,10 +322,10 @@ static inline byte GetHouseProcessingTime(TileIndex t) * @param time the time to be set * @pre IsTileType(t, MP_HOUSE) */ -static inline void SetHouseProcessingTime(TileIndex t, byte time) +static inline void SetHouseProcessingTime(Tile t, byte time) { assert(IsTileType(t, MP_HOUSE)); - SB(_me[t].m6, 2, 6, time); + SB(t.m6(), 2, 6, time); } /** @@ -333,10 +333,10 @@ static inline void SetHouseProcessingTime(TileIndex t, byte time) * @param t the house tile * @pre IsTileType(t, MP_HOUSE) */ -static inline void DecHouseProcessingTime(TileIndex t) +static inline void DecHouseProcessingTime(Tile t) { assert(IsTileType(t, MP_HOUSE)); - _me[t].m6 -= 1 << 2; + t.m6() -= 1 << 2; } /** @@ -349,17 +349,17 @@ static inline void DecHouseProcessingTime(TileIndex t) * @param random_bits required for newgrf houses * @pre IsTileType(t, MP_CLEAR) */ -static inline void MakeHouseTile(TileIndex t, TownID tid, byte counter, byte stage, HouseID type, byte random_bits) +static inline void MakeHouseTile(Tile t, TownID tid, byte counter, byte stage, HouseID type, byte random_bits) { assert(IsTileType(t, MP_CLEAR)); SetTileType(t, MP_HOUSE); - _m[t].m1 = random_bits; - _m[t].m2 = tid; - _m[t].m3 = 0; + t.m1() = random_bits; + t.m2() = tid; + t.m3() = 0; SetHouseType(t, type); SetHouseCompleted(t, stage == TOWN_HOUSE_COMPLETED); - _m[t].m5 = IsHouseCompleted(t) ? 0 : (stage << 3 | counter); + t.m5() = IsHouseCompleted(t) ? 0 : (stage << 3 | counter); SetAnimationFrame(t, 0); SetHouseProcessingTime(t, HouseSpec::Get(type)->processing_time); } diff --git a/src/townname.cpp b/src/townname.cpp index bce894bfcfaa9..86954b933ce74 100644 --- a/src/townname.cpp +++ b/src/townname.cpp @@ -112,11 +112,12 @@ bool VerifyTownName(uint32 r, const TownNameParams *par, TownNames *town_names) /** * Generates valid town name. + * @param randomizer the source of random data for generating the name * @param townnameparts if a name is generated, it's stored there * @param town_names if a name is generated, check its uniqueness with the set * @return true iff a name was generated */ -bool GenerateTownName(uint32 *townnameparts, TownNames *town_names) +bool GenerateTownName(Randomizer &randomizer, uint32 *townnameparts, TownNames *town_names) { TownNameParams par(_settings_game.game_creation.town_name); @@ -130,7 +131,7 @@ bool GenerateTownName(uint32 *townnameparts, TownNames *town_names) * the other towns may take considerable amount of time (10000 is * too much). */ for (int i = 1000; i != 0; i--) { - uint32 r = _generating_world ? Random() : InteractiveRandom(); + uint32 r = randomizer.Next(); if (!VerifyTownName(r, &par, town_names)) continue; *townnameparts = r; diff --git a/src/townname_func.h b/src/townname_func.h index 6438d2b283dc0..a3d29e467dce5 100644 --- a/src/townname_func.h +++ b/src/townname_func.h @@ -10,12 +10,13 @@ #ifndef TOWNNAME_FUNC_H #define TOWNNAME_FUNC_H +#include "core/random_func.hpp" #include "townname_type.h" char *GenerateTownNameString(char *buf, const char *last, size_t lang, uint32 seed); char *GetTownName(char *buff, const TownNameParams *par, uint32 townnameparts, const char *last); char *GetTownName(char *buff, const Town *t, const char *last); bool VerifyTownName(uint32 r, const TownNameParams *par, TownNames *town_names = nullptr); -bool GenerateTownName(uint32 *townnameparts, TownNames *town_names = nullptr); +bool GenerateTownName(Randomizer &randomizer, uint32 *townnameparts, TownNames *town_names = nullptr); #endif /* TOWNNAME_FUNC_H */ diff --git a/src/train.h b/src/train.h index 27f5cee5cf4a5..9eb5145a927db 100644 --- a/src/train.h +++ b/src/train.h @@ -65,6 +65,8 @@ int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, i void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type); +bool TrainOnCrossing(TileIndex tile); + /** Variables that are cached to improve performance and such */ struct TrainCache { /* Cached wagon override spritegroup */ @@ -107,24 +109,25 @@ struct Train FINAL : public GroundVehicle { friend struct GroundVehicle; // GroundVehicle needs to use the acceleration functions defined at Train. - void MarkDirty(); - void UpdateDeltaXY(); - ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_TRAIN_REVENUE : EXPENSES_TRAIN_RUN; } - void PlayLeaveStationSound() const; - bool IsPrimaryVehicle() const { return this->IsFrontEngine(); } - void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const; - int GetDisplaySpeed() const { return this->gcache.last_speed; } - int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed; } - Money GetRunningCost() const; + void MarkDirty() override; + void UpdateDeltaXY() override; + ExpensesType GetExpenseType(bool income) const override { return income ? EXPENSES_TRAIN_REVENUE : EXPENSES_TRAIN_RUN; } + void PlayLeaveStationSound(bool force = false) const override; + bool IsPrimaryVehicle() const override { return this->IsFrontEngine(); } + void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override; + int GetDisplaySpeed() const override { return this->gcache.last_speed; } + int GetDisplayMaxSpeed() const override { return this->vcache.cached_max_speed; } + Money GetRunningCost() const override; + int GetCursorImageOffset() const; int GetDisplayImageWidth(Point *offset = nullptr) const; - bool IsInDepot() const { return this->track == TRACK_BIT_DEPOT; } - bool Tick(); - void OnNewVanillaDay(); - void OnNewDay(); - uint Crash(bool flooded = false); - Trackdir GetVehicleTrackdir() const; - TileIndex GetOrderStationLocation(StationID station); - bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse); + bool IsInDepot() const override { return this->track == TRACK_BIT_DEPOT; } + bool Tick() override; + void OnNewVanillaDay() override; + void OnNewDay() override; + uint Crash(bool flooded = false) override; + Trackdir GetVehicleTrackdir() const override; + TileIndex GetOrderStationLocation(StationID station) override; + ClosestDepot FindClosestDepot() override; void ReserveTrackUnderConsist() const; @@ -136,7 +139,7 @@ struct Train FINAL : public GroundVehicle { void UpdateAcceleration(); - int GetCurrentMaxSpeed() const; + int GetCurrentMaxSpeed() const override; /** * Get the next real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist. @@ -214,7 +217,7 @@ struct Train FINAL : public GroundVehicle { */ inline uint16 GetWeight() const { - uint16 weight = (CargoSpec::Get(this->cargo_type)->weight * this->cargo.StoredCount() * FreightWagonMult(this->cargo_type)) / 16; + uint16 weight = CargoSpec::Get(this->cargo_type)->WeightOfNUnitsInTrain(this->cargo.StoredCount()); /* Vehicle weight is not added for articulated parts. */ if (!this->IsArticulatedPart()) { @@ -229,6 +232,12 @@ struct Train FINAL : public GroundVehicle { return weight; } + /** + * Calculates the weight value that this vehicle will have when fully loaded with its current cargo. + * @return Weight value in tonnes. + */ + uint16 GetMaxWeight() const override; + /** * Allows to know the tractive effort value that this vehicle will use. * @return Tractive effort value from the engine. diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 2b36706466b2d..0fd566d58d120 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -434,6 +434,21 @@ void Train::UpdateAcceleration() this->acceleration = Clamp(power / weight * 4, 1, 255); } +int Train::GetCursorImageOffset() const +{ + if (this->gcache.cached_veh_length != 8 && HasBit(this->flags, VRF_REVERSE_DIRECTION) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_RAIL_FLIPS)) { + int reference_width = TRAININFO_DEFAULT_VEHICLE_WIDTH; + + const Engine *e = this->GetEngine(); + if (e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) { + reference_width = e->GetGRF()->traininfo_vehicle_width; + } + + return ScaleSpriteTrad((this->gcache.cached_veh_length - (int)VEHICLE_LENGTH) * reference_width / (int)VEHICLE_LENGTH); + } + return 0; +} + /** * Get the width of a train vehicle image in the GUI. * @param offset Additional offset for positioning the sprite; set to nullptr if not needed @@ -451,10 +466,14 @@ int Train::GetDisplayImageWidth(Point *offset) const } if (offset != nullptr) { - offset->x = ScaleGUITrad(reference_width) / 2; - offset->y = ScaleGUITrad(vehicle_pitch); + if (HasBit(this->flags, VRF_REVERSE_DIRECTION) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_RAIL_FLIPS)) { + offset->x = ScaleSpriteTrad((this->gcache.cached_veh_length - VEHICLE_LENGTH / 2) * reference_width / VEHICLE_LENGTH); + } else { + offset->x = ScaleSpriteTrad(reference_width) / 2; + } + offset->y = ScaleSpriteTrad(vehicle_pitch); } - return ScaleGUITrad(this->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH); + return ScaleSpriteTrad(this->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH); } static SpriteID GetDefaultTrainSprite(uint8 spritenum, Direction direction) @@ -500,7 +519,7 @@ static void GetRailIcon(EngineID engine, bool rear_head, int &y, EngineImageType GetCustomVehicleIcon(engine, dir, image_type, result); if (result->IsValid()) { if (e->GetGRF() != nullptr) { - y += ScaleGUITrad(e->GetGRF()->traininfo_vehicle_pitch); + y += ScaleSpriteTrad(e->GetGRF()->traininfo_vehicle_pitch); } return; } @@ -528,11 +547,11 @@ void DrawTrainEngine(int left, int right, int preferred_x, int y, EngineID engin seqr.GetBounds(&rectr); preferred_x = Clamp(preferred_x, - left - UnScaleGUI(rectf.left) + ScaleGUITrad(14), - right - UnScaleGUI(rectr.right) - ScaleGUITrad(15)); + left - UnScaleGUI(rectf.left) + ScaleSpriteTrad(14), + right - UnScaleGUI(rectr.right) - ScaleSpriteTrad(15)); - seqf.Draw(preferred_x - ScaleGUITrad(14), yf, pal, pal == PALETTE_CRASH); - seqr.Draw(preferred_x + ScaleGUITrad(15), yr, pal, pal == PALETTE_CRASH); + seqf.Draw(preferred_x - ScaleSpriteTrad(14), yf, pal, pal == PALETTE_CRASH); + seqr.Draw(preferred_x + ScaleSpriteTrad(15), yr, pal, pal == PALETTE_CRASH); } else { VehicleSpriteSeq seq; GetRailIcon(engine, false, y, image_type, &seq); @@ -566,8 +585,8 @@ void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, Rect rect; seq.GetBounds(&rect); - width = UnScaleGUI(rect.right - rect.left + 1); - height = UnScaleGUI(rect.bottom - rect.top + 1); + width = UnScaleGUI(rect.Width()); + height = UnScaleGUI(rect.Height()); xoffs = UnScaleGUI(rect.left); yoffs = UnScaleGUI(rect.top); @@ -576,9 +595,9 @@ void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, seq.GetBounds(&rect); /* Calculate values relative to an imaginary center between the two sprites. */ - width = ScaleGUITrad(TRAININFO_DEFAULT_VEHICLE_WIDTH) + UnScaleGUI(rect.right) - xoffs; - height = std::max(height, UnScaleGUI(rect.bottom - rect.top + 1)); - xoffs = xoffs - ScaleGUITrad(TRAININFO_DEFAULT_VEHICLE_WIDTH) / 2; + width = ScaleSpriteTrad(TRAININFO_DEFAULT_VEHICLE_WIDTH) + UnScaleGUI(rect.right) - xoffs; + height = std::max(height, UnScaleGUI(rect.Height())); + xoffs = xoffs - ScaleSpriteTrad(TRAININFO_DEFAULT_VEHICLE_WIDTH) / 2; yoffs = std::min(yoffs, UnScaleGUI(rect.top)); } } @@ -1184,7 +1203,7 @@ CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID dst = Train::GetIfValid(dest_veh); if (dst == nullptr) return CMD_ERROR; - CommandCost ret = CheckOwnership(dst->owner); + ret = CheckOwnership(dst->owner); if (ret.Failed()) return ret; /* Do not allow appending to crashed vehicles, too */ @@ -1253,7 +1272,7 @@ CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID /* If the autoreplace flag is set we do not need to test for the validity * because we are going to revert the train to its original state. As we * assume the original state was correct autoreplace can skip this. */ - CommandCost ret = ValidateTrains(original_dst_head, dst_head, original_src_head, src_head, true); + ret = ValidateTrains(original_dst_head, dst_head, original_src_head, src_head, true); if (ret.Failed()) { /* Restore the train we had. */ RestoreTrainBackup(original_src); @@ -1439,7 +1458,15 @@ void Train::UpdateDeltaXY() this->x_bb_offs = 0; this->y_bb_offs = 0; - if (!IsDiagonalDirection(this->direction)) { + /* Set if flipped and engine is NOT flagged with custom flip handling. */ + int flipped = HasBit(this->flags, VRF_REVERSE_DIRECTION) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_RAIL_FLIPS); + /* If flipped and vehicle length is odd, we need to adjust the bounding box offset slightly. */ + int flip_offs = flipped && (this->gcache.cached_veh_length & 1); + + Direction dir = this->direction; + if (flipped) dir = ReverseDir(dir); + + if (!IsDiagonalDirection(dir)) { static const int _sign_table[] = { /* x, y */ @@ -1449,25 +1476,25 @@ void Train::UpdateDeltaXY() 1, -1, // DIR_W }; - int half_shorten = (VEHICLE_LENGTH - this->gcache.cached_veh_length) / 2; + int half_shorten = (VEHICLE_LENGTH - this->gcache.cached_veh_length + flipped) / 2; /* For all straight directions, move the bound box to the centre of the vehicle, but keep the size. */ - this->x_offs -= half_shorten * _sign_table[this->direction]; - this->y_offs -= half_shorten * _sign_table[this->direction + 1]; - this->x_extent += this->x_bb_offs = half_shorten * _sign_table[direction]; - this->y_extent += this->y_bb_offs = half_shorten * _sign_table[direction + 1]; + this->x_offs -= half_shorten * _sign_table[dir]; + this->y_offs -= half_shorten * _sign_table[dir + 1]; + this->x_extent += this->x_bb_offs = half_shorten * _sign_table[dir]; + this->y_extent += this->y_bb_offs = half_shorten * _sign_table[dir + 1]; } else { - switch (this->direction) { + switch (dir) { /* Shorten southern corner of the bounding box according the vehicle length * and center the bounding box on the vehicle. */ case DIR_NE: - this->x_offs = 1 - (this->gcache.cached_veh_length + 1) / 2; + this->x_offs = 1 - (this->gcache.cached_veh_length + 1) / 2 + flip_offs; this->x_extent = this->gcache.cached_veh_length - 1; this->x_bb_offs = -1; break; case DIR_NW: - this->y_offs = 1 - (this->gcache.cached_veh_length + 1) / 2; + this->y_offs = 1 - (this->gcache.cached_veh_length + 1) / 2 + flip_offs; this->y_extent = this->gcache.cached_veh_length - 1; this->y_bb_offs = -1; break; @@ -1475,13 +1502,13 @@ void Train::UpdateDeltaXY() /* Move northern corner of the bounding box down according to vehicle length * and center the bounding box on the vehicle. */ case DIR_SW: - this->x_offs = 1 + (this->gcache.cached_veh_length + 1) / 2 - VEHICLE_LENGTH; + this->x_offs = 1 + (this->gcache.cached_veh_length + 1) / 2 - VEHICLE_LENGTH - flip_offs; this->x_extent = VEHICLE_LENGTH - 1; this->x_bb_offs = VEHICLE_LENGTH - this->gcache.cached_veh_length - 1; break; case DIR_SE: - this->y_offs = 1 + (this->gcache.cached_veh_length + 1) / 2 - VEHICLE_LENGTH; + this->y_offs = 1 + (this->gcache.cached_veh_length + 1) / 2 - VEHICLE_LENGTH - flip_offs; this->y_extent = VEHICLE_LENGTH - 1; this->y_bb_offs = VEHICLE_LENGTH - this->gcache.cached_veh_length - 1; break; @@ -1632,6 +1659,19 @@ static Vehicle *TrainOnTileEnum(Vehicle *v, void *) return (v->type == VEH_TRAIN) ? v : nullptr; } +/** + * Check if a level crossing tile has a train on it + * @param tile tile to test + * @return true if a train is on the crossing + * @pre tile is a level crossing + */ +bool TrainOnCrossing(TileIndex tile) +{ + assert(IsLevelCrossingTile(tile)); + + return HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum); +} + /** * Checks if a train is approaching a rail-road crossing @@ -1675,29 +1715,88 @@ static bool TrainApproachingCrossing(TileIndex tile) return HasVehicleOnPos(tile_from, &tile, &TrainApproachingCrossingEnum); } +/** + * Check if a level crossing should be barred. + * @param tile The tile to check. + * @return True if the crossing should be barred, else false. + */ +static inline bool CheckLevelCrossing(TileIndex tile) +{ + /* reserved || train on crossing || train approaching crossing */ + return HasCrossingReservation(tile) || TrainOnCrossing(tile) || TrainApproachingCrossing(tile); +} /** - * Sets correct crossing state - * @param tile tile to update - * @param sound should we play sound? - * @pre tile is a rail-road crossing + * Sets a level crossing tile to the correct state. + * @param tile Tile to update. + * @param sound Should we play sound? + * @param force_barred Should we set the crossing to barred? + * @pre tile is a rail-road crossing. */ -void UpdateLevelCrossing(TileIndex tile, bool sound) +static void UpdateLevelCrossingTile(TileIndex tile, bool sound, bool force_barred) { assert(IsLevelCrossingTile(tile)); + bool set_barred; - /* reserved || train on crossing || train approaching crossing */ - bool new_state = HasCrossingReservation(tile) || HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum) || TrainApproachingCrossing(tile); + /* We force the crossing to be barred when an adjacent crossing is barred, otherwise let it decide for itself. */ + set_barred = force_barred || CheckLevelCrossing(tile); - if (new_state != IsCrossingBarred(tile)) { - if (new_state && sound) { - if (_settings_client.sound.ambient) SndPlayTileFx(SND_0E_LEVEL_CROSSING, tile); - } - SetCrossingBarred(tile, new_state); + /* The state has changed */ + if (set_barred != IsCrossingBarred(tile)) { + if (set_barred && sound && _settings_client.sound.ambient) SndPlayTileFx(SND_0E_LEVEL_CROSSING, tile); + SetCrossingBarred(tile, set_barred); MarkTileDirtyByTile(tile); } } +/** + * Update a level crossing to barred or open (crossing may include multiple adjacent tiles). + * @param tile Tile which causes the update. + * @param sound Should we play sound? + * @param force_bar Should we force the crossing to be barred? + */ +void UpdateLevelCrossing(TileIndex tile, bool sound, bool force_bar) +{ + if (!IsLevelCrossingTile(tile)) return; + + bool forced_state = force_bar; + + const Axis axis = GetCrossingRoadAxis(tile); + const DiagDirection dir1 = AxisToDiagDir(axis); + const DiagDirection dir2 = ReverseDiagDir(dir1); + + /* Check if an adjacent crossing is barred. */ + for (DiagDirection dir : { dir1, dir2 }) { + for (TileIndex t = tile; !forced_state && t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == axis; t = TileAddByDiagDir(t, dir)) { + forced_state |= CheckLevelCrossing(t); + } + } + + /* Now that we know whether all tiles in this crossing should be barred or open, + * we need to update those tiles. We start with the tile itself, then look along the road axis. */ + UpdateLevelCrossingTile(tile, sound, forced_state); + for (DiagDirection dir : { dir1, dir2 }) { + for (TileIndex t = TileAddByDiagDir(tile, dir); t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == axis; t = TileAddByDiagDir(t, dir)) { + UpdateLevelCrossingTile(t, sound, forced_state); + } + } +} + +/** + * Find adjacent level crossing tiles in this multi-track crossing and mark them dirty. + * @param The tile which causes the update. + */ +void MarkDirtyAdjacentLevelCrossingTiles(TileIndex tile, Axis road_axis) +{ + const DiagDirection dir1 = AxisToDiagDir(road_axis); + const DiagDirection dir2 = ReverseDiagDir(dir1); + for (DiagDirection dir : { dir1, dir2 }) { + const TileIndex t = TileAddByDiagDir(tile, dir); + if (t < Map::Size() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == road_axis) { + MarkTileDirtyByTile(t); + } + } +} /** * Bars crossing and plays ding-ding sound if not barred already @@ -1707,9 +1806,8 @@ void UpdateLevelCrossing(TileIndex tile, bool sound) static inline void MaybeBarCrossingWithSound(TileIndex tile) { if (!IsCrossingBarred(tile)) { - BarCrossing(tile); - if (_settings_client.sound.ambient) SndPlayTileFx(SND_0E_LEVEL_CROSSING, tile); - MarkTileDirtyByTile(tile); + SetCrossingReservation(tile, true); + UpdateLevelCrossing(tile, true); } } @@ -1918,7 +2016,6 @@ CommandCost CmdReverseTrainDirection(DoCommandFlag flags, VehicleID veh_id, bool if (v->IsMultiheaded() || HasBit(EngInfo(v->engine_type)->callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) { return_cmd_error(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE_MULTIPLE_UNITS); } - if (!HasBit(EngInfo(v->engine_type)->misc_flags, EF_RAIL_FLIPS)) return CMD_ERROR; Train *front = v->First(); /* make sure the vehicle is stopped in the depot */ @@ -2023,27 +2120,16 @@ static FindDepotData FindClosestTrainDepot(Train *v, int max_distance) } } -/** - * Locate the closest depot for this consist, and return the information to the caller. - * @param[out] location If not \c nullptr and a depot is found, store its location in the given address. - * @param[out] destination If not \c nullptr and a depot is found, store its index in the given address. - * @param[out] reverse If not \c nullptr and a depot is found, store reversal information in the given address. - * @return A depot has been found. - */ -bool Train::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) +ClosestDepot Train::FindClosestDepot() { FindDepotData tfdd = FindClosestTrainDepot(this, 0); - if (tfdd.best_length == UINT_MAX) return false; - - if (location != nullptr) *location = tfdd.tile; - if (destination != nullptr) *destination = GetDepotIndex(tfdd.tile); - if (reverse != nullptr) *reverse = tfdd.reverse; + if (tfdd.best_length == UINT_MAX) return ClosestDepot(); - return true; + return ClosestDepot(tfdd.tile, GetDepotIndex(tfdd.tile), tfdd.reverse); } /** Play a sound for a train leaving the station. */ -void Train::PlayLeaveStationSound() const +void Train::PlayLeaveStationSound(bool force) const { static const SoundFx sfx[] = { SND_04_DEPARTURE_STEAM, @@ -2053,10 +2139,9 @@ void Train::PlayLeaveStationSound() const SND_41_DEPARTURE_MAGLEV }; - if (PlayVehicleSound(this, VSE_START)) return; + if (PlayVehicleSound(this, VSE_START, force)) return; - EngineID engtype = this->engine_type; - SndPlayVehicleFx(sfx[RailVehInfo(engtype)->engclass], this); + SndPlayVehicleFx(sfx[RailVehInfo(this->engine_type)->engclass], this); } /** @@ -2319,13 +2404,16 @@ static const byte _initial_tile_subcoord[6][4][3] = { * @param[out] path_found Whether a path has been found or not. * @param do_track_reservation Path reservation is requested * @param[out] dest State and destination of the requested path + * @param[out] final_dest Final tile of the best path found * @return The best track the train should follow */ -static Track DoTrainPathfind(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool do_track_reservation, PBSTileInfo *dest) +static Track DoTrainPathfind(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool do_track_reservation, PBSTileInfo *dest, TileIndex *final_dest) { + if (final_dest != nullptr) *final_dest = INVALID_TILE; + switch (_settings_game.pf.pathfinder_for_trains) { case VPF_NPF: return NPFTrainChooseTrack(v, path_found, do_track_reservation, dest); - case VPF_YAPF: return YapfTrainChooseTrack(v, tile, enterdir, tracks, path_found, do_track_reservation, dest); + case VPF_YAPF: return YapfTrainChooseTrack(v, tile, enterdir, tracks, path_found, do_track_reservation, dest, final_dest); default: NOT_REACHED(); } @@ -2447,6 +2535,7 @@ class VehicleOrderSaver { StationID old_last_station_visited; VehicleOrderID index; bool suppress_implicit_orders; + bool restored; public: VehicleOrderSaver(Train *_v) : @@ -2455,16 +2544,29 @@ class VehicleOrderSaver { old_dest_tile(_v->dest_tile), old_last_station_visited(_v->last_station_visited), index(_v->cur_real_order_index), - suppress_implicit_orders(HasBit(_v->gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS)) + suppress_implicit_orders(HasBit(_v->gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS)), + restored(false) { } - ~VehicleOrderSaver() + /** + * Restore the saved order to the vehicle. + */ + void Restore() { this->v->current_order = this->old_order; this->v->dest_tile = this->old_dest_tile; this->v->last_station_visited = this->old_last_station_visited; SB(this->v->gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS, 1, suppress_implicit_orders ? 1: 0); + this->restored = true; + } + + /** + * Restore the saved order to the vehicle, if Restore() has not already been called. + */ + ~VehicleOrderSaver() + { + if (!this->restored) this->Restore(); } /** @@ -2525,6 +2627,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, Track best_track = INVALID_TRACK; bool do_track_reservation = _settings_game.pf.reserve_paths || force_res; bool changed_signal = false; + TileIndex final_dest = INVALID_TILE; assert((tracks & ~TRACK_BIT_MASK) == 0); @@ -2597,7 +2700,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, bool path_found = true; TileIndex new_tile = res_dest.tile; - Track next_track = DoTrainPathfind(v, new_tile, dest_enterdir, tracks, path_found, do_track_reservation, &res_dest); + Track next_track = DoTrainPathfind(v, new_tile, dest_enterdir, tracks, path_found, do_track_reservation, &res_dest, &final_dest); if (new_tile == tile) best_track = next_track; v->HandlePathfindingResult(path_found); } @@ -2645,7 +2748,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, if (orders.SwitchToNextOrder(true)) { PBSTileInfo cur_dest; bool path_found; - DoTrainPathfind(v, next_tile, exitdir, reachable, path_found, true, &cur_dest); + DoTrainPathfind(v, next_tile, exitdir, reachable, path_found, true, &cur_dest, nullptr); if (cur_dest.tile != INVALID_TILE) { res_dest = cur_dest; if (res_dest.okay) continue; @@ -2671,6 +2774,15 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, if (changed_signal) MarkTileDirtyByTile(tile); + orders.Restore(); + if (v->current_order.IsType(OT_GOTO_DEPOT) && + (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) && + final_dest != INVALID_TILE && IsRailDepotTile(final_dest)) { + v->current_order.SetDestination(GetDepotIndex(final_dest)); + v->dest_tile = final_dest; + SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); + } + return best_track; } @@ -3911,11 +4023,11 @@ Money Train::GetRunningCost() const */ bool Train::Tick() { - PerformanceAccumulator framerate(PFE_GL_TRAINS); - this->tick_counter++; if (this->IsFrontEngine()) { + PerformanceAccumulator framerate(PFE_GL_TRAINS); + if (!(this->vehstatus & VS_STOPPED) || this->cur_speed > 0) this->running_ticks++; this->current_order_time++; @@ -3975,7 +4087,7 @@ static void CheckIfTrainNeedsService(Train *v) } SetBit(v->gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS); - v->current_order.MakeGoToDepot(depot, ODTFB_SERVICE); + v->current_order.MakeGoToDepot(depot, ODTFB_SERVICE, ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS, ODATFB_NEAREST_DEPOT); v->dest_tile = tfdd.tile; SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); } @@ -4039,3 +4151,20 @@ Trackdir Train::GetVehicleTrackdir() const return TrackDirectionToTrackdir(FindFirstTrack(this->track), this->direction); } + +uint16 Train::GetMaxWeight() const +{ + uint16 weight = CargoSpec::Get(this->cargo_type)->WeightOfNUnitsInTrain(this->GetEngine()->DetermineCapacity(this)); + + /* Vehicle weight is not added for articulated parts. */ + if (!this->IsArticulatedPart()) { + weight += GetVehicleProperty(this, PROP_TRAIN_WEIGHT, RailVehInfo(this->engine_type)->weight); + } + + /* Powered wagons have extra weight added. */ + if (HasBit(this->flags, VRF_POWEREDWAGON)) { + weight += RailVehInfo(this->gcache.first_engine)->pow_wag_weight; + } + + return weight; +} diff --git a/src/train_cmd.h b/src/train_cmd.h index 97bd43a74b322..3d224717a5149 100644 --- a/src/train_cmd.h +++ b/src/train_cmd.h @@ -21,10 +21,10 @@ CommandCost CmdMoveRailVehicle(DoCommandFlag flags, VehicleID src_veh, VehicleID CommandCost CmdForceTrainProceed(DoCommandFlag flags, VehicleID veh_id); CommandCost CmdReverseTrainDirection(DoCommandFlag flags, VehicleID veh_id, bool reverse_single_veh); -DEF_CMD_TRAIT(CMD_MOVE_RAIL_VEHICLE, CmdMoveRailVehicle, 0, CMDT_VEHICLE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_FORCE_TRAIN_PROCEED, CmdForceTrainProceed, 0, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_REVERSE_TRAIN_DIRECTION, CmdReverseTrainDirection, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_MOVE_RAIL_VEHICLE, CmdMoveRailVehicle, CMD_LOCATION, CMDT_VEHICLE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_FORCE_TRAIN_PROCEED, CmdForceTrainProceed, CMD_LOCATION, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_REVERSE_TRAIN_DIRECTION, CmdReverseTrainDirection, CMD_LOCATION, CMDT_VEHICLE_MANAGEMENT) -void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, TileIndex tile, EngineID, bool, CargoID, ClientID); +void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, CargoArray, TileIndex tile, EngineID, bool, CargoID, ClientID); #endif /* TRAIN_CMD_H */ diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 9fe06a9383486..e6a3d0f1354f8 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.cpp @@ -27,7 +27,7 @@ * @param new_veh_id ID of the ne vehicle. * @param tile The tile the command was executed on. */ -void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, TileIndex tile, EngineID, bool, CargoID, ClientID) +void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, CargoArray, TileIndex tile, EngineID, bool, CargoID, ClientID) { if (result.Failed()) return; @@ -44,7 +44,7 @@ void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, if (found != nullptr) { found = found->Last(); /* put the new wagon at the end of the loco. */ - Command::Post(new_veh_id, found->index, false); + Command::Post(found->tile, new_veh_id, found->index, false); InvalidateWindowClassesData(WC_TRAINS_LIST, 0); } } @@ -53,11 +53,12 @@ void CcBuildWagon(Commands cmd, const CommandCost &result, VehicleID new_veh_id, * Highlight the position where a rail vehicle is dragged over by drawing a light gray background. * @param px The current x position to draw from. * @param max_width The maximum space available to draw. + * @param y The vertical centre position to draw from. * @param selection Selected vehicle that is dragged. * @param chain Whether a whole chain is dragged. * @return The width of the highlight mark. */ -static int HighlightDragPosition(int px, int max_width, VehicleID selection, bool chain) +static int HighlightDragPosition(int px, int max_width, int y, VehicleID selection, bool chain) { bool rtl = _current_text_dir == TD_RTL; @@ -72,8 +73,11 @@ static int HighlightDragPosition(int px, int max_width, VehicleID selection, boo int drag_hlight_width = std::max(drag_hlight_right - drag_hlight_left + 1, 0); if (drag_hlight_width > 0) { - GfxFillRect(drag_hlight_left + WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP + 1, - drag_hlight_right - WD_FRAMERECT_RIGHT, ScaleGUITrad(13) - WD_FRAMERECT_BOTTOM, _colour_gradient[COLOUR_GREY][7]); + int height = ScaleSpriteTrad(12); + int top = y - height / 2; + Rect r = {drag_hlight_left, top, drag_hlight_right, top + height - 1}; + /* Sprite-scaling is used here as the area is from sprite size */ + GfxFillRect(r.Shrink(ScaleSpriteTrad(1)), _colour_gradient[COLOUR_GREY][7]); } return drag_hlight_width; @@ -82,81 +86,80 @@ static int HighlightDragPosition(int px, int max_width, VehicleID selection, boo /** * Draws an image of a whole train * @param v Front vehicle - * @param left The minimum horizontal position - * @param right The maximum horizontal position - * @param y Vertical position to draw at + * @param r Rect to draw at * @param selection Selected vehicle to draw a frame around * @param skip Number of pixels to skip at the front (for scrolling) * @param drag_dest The vehicle another one is dragged over, \c INVALID_VEHICLE if none. */ -void DrawTrainImage(const Train *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip, VehicleID drag_dest) +void DrawTrainImage(const Train *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip, VehicleID drag_dest) { bool rtl = _current_text_dir == TD_RTL; Direction dir = rtl ? DIR_E : DIR_W; - DrawPixelInfo tmp_dpi, *old_dpi; + DrawPixelInfo tmp_dpi; /* Position of highlight box */ int highlight_l = 0; int highlight_r = 0; - int max_width = right - left + 1; - int height = ScaleGUITrad(14); - - if (!FillDrawPixelInfo(&tmp_dpi, left, y, max_width, height)) return; - - old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; - - int px = rtl ? max_width + skip : -skip; - bool sel_articulated = false; - bool dragging = (drag_dest != INVALID_VEHICLE); - bool drag_at_end_of_train = (drag_dest == v->index); // Head index is used to mark dragging at end of train. - for (; v != nullptr && (rtl ? px > 0 : px < max_width); v = v->Next()) { - if (dragging && !drag_at_end_of_train && drag_dest == v->index) { - /* Highlight the drag-and-drop destination inside the train. */ - int drag_hlight_width = HighlightDragPosition(px, max_width, selection, _cursor.vehchain); - px += rtl ? -drag_hlight_width : drag_hlight_width; - } + int max_width = r.Width(); - Point offset; - int width = Train::From(v)->GetDisplayImageWidth(&offset); + if (!FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) return; - if (rtl ? px + width > 0 : px - width < max_width) { - PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); - VehicleSpriteSeq seq; - v->GetImage(dir, image_type, &seq); - seq.Draw(px + (rtl ? -offset.x : offset.x), height / 2 + offset.y, pal, (v->vehstatus & VS_CRASHED) != 0); - } + { + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); + + int px = rtl ? max_width + skip : -skip; + int y = r.Height() / 2; + bool sel_articulated = false; + bool dragging = (drag_dest != INVALID_VEHICLE); + bool drag_at_end_of_train = (drag_dest == v->index); // Head index is used to mark dragging at end of train. + for (; v != nullptr && (rtl ? px > 0 : px < max_width); v = v->Next()) { + if (dragging && !drag_at_end_of_train && drag_dest == v->index) { + /* Highlight the drag-and-drop destination inside the train. */ + int drag_hlight_width = HighlightDragPosition(px, max_width, y, selection, _cursor.vehchain); + px += rtl ? -drag_hlight_width : drag_hlight_width; + } + + Point offset; + int width = Train::From(v)->GetDisplayImageWidth(&offset); - if (!v->IsArticulatedPart()) sel_articulated = false; - - if (v->index == selection) { - /* Set the highlight position */ - highlight_l = rtl ? px - width : px; - highlight_r = rtl ? px - 1 : px + width - 1; - sel_articulated = true; - } else if ((_cursor.vehchain && highlight_r != 0) || sel_articulated) { - if (rtl) { - highlight_l -= width; - } else { - highlight_r += width; + if (rtl ? px + width > 0 : px - width < max_width) { + PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); + VehicleSpriteSeq seq; + v->GetImage(dir, image_type, &seq); + seq.Draw(px + (rtl ? -offset.x : offset.x), y + offset.y, pal, (v->vehstatus & VS_CRASHED) != 0); } - } - px += rtl ? -width : width; - } + if (!v->IsArticulatedPart()) sel_articulated = false; + + if (v->index == selection) { + /* Set the highlight position */ + highlight_l = rtl ? px - width : px; + highlight_r = rtl ? px - 1 : px + width - 1; + sel_articulated = true; + } else if ((_cursor.vehchain && highlight_r != 0) || sel_articulated) { + if (rtl) { + highlight_l -= width; + } else { + highlight_r += width; + } + } - if (dragging && drag_at_end_of_train) { - /* Highlight the drag-and-drop destination at the end of the train. */ - HighlightDragPosition(px, max_width, selection, _cursor.vehchain); + px += rtl ? -width : width; + } + + if (dragging && drag_at_end_of_train) { + /* Highlight the drag-and-drop destination at the end of the train. */ + HighlightDragPosition(px, max_width, y, selection, _cursor.vehchain); + } } if (highlight_l != highlight_r) { /* Draw the highlight. Now done after drawing all the engines, as * the next engine after the highlight could overlap it. */ - DrawFrameRect(highlight_l, 0, highlight_r, height - 1, COLOUR_WHITE, FR_BORDERONLY); + int height = ScaleSpriteTrad(12); + Rect hr = {highlight_l, 0, highlight_r, height - 1}; + DrawFrameRect(hr.Translate(r.left, CenterBounds(r.top, r.bottom, height)).Expand(WidgetDimensions::scaled.bevel), COLOUR_WHITE, FR_BORDERONLY); } - - _cur_dpi = old_dpi; } /** Helper struct for the cargo details information */ @@ -182,7 +185,6 @@ struct CargoSummaryItem { static const uint TRAIN_DETAILS_MIN_INDENT = 32; ///< Minimum indent level in the train details window static const uint TRAIN_DETAILS_MAX_INDENT = 72; ///< Maximum indent level in the train details window; wider than this and we start on a new line -static const int TRAIN_DETAILS_LIST_INDENT = 10; ///< Indent for list items in the Total Cargo window /** Container for the cargo summary information. */ typedef std::vector CargoSummary; @@ -225,11 +227,11 @@ static void TrainDetailsCargoTab(const CargoSummaryItem *item, int left, int rig static void TrainDetailsInfoTab(const Vehicle *v, int left, int right, int y) { if (RailVehInfo(v->engine_type)->railveh_type == RAILVEH_WAGON) { - SetDParam(0, v->engine_type); + SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails)); SetDParam(1, v->value); DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE); } else { - SetDParam(0, v->engine_type); + SetDParam(0, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails)); SetDParam(1, v->build_year); SetDParam(2, v->value); DrawString(left, right, y, STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE); @@ -341,7 +343,7 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab) num += std::max(1u, (unsigned)_cargo_summary.size()); uint length = GetLengthOfArticulatedVehicle(v); - if (length > TRAIN_DETAILS_MAX_INDENT) num++; + if (length > (uint)ScaleSpriteTrad(TRAIN_DETAILS_MAX_INDENT)) num++; } } @@ -352,32 +354,22 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab) * Draw the details for the given vehicle at the given position * * @param v current vehicle - * @param left The left most coordinate to draw - * @param right The right most coordinate to draw - * @param y The y coordinate + * @param r the Rect to draw within * @param vscroll_pos Position of scrollbar * @param vscroll_cap Number of lines currently displayed * @param det_tab Selected details tab */ -void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab) +void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab) { - /* get rid of awkward offset */ - y -= WD_MATRIX_TOP; - - /* Indent the total cargo capacity details */ - int offs_left = _current_text_dir == TD_LTR ? TRAIN_DETAILS_LIST_INDENT : 0; - int offs_right = _current_text_dir == TD_LTR ? 0 : TRAIN_DETAILS_LIST_INDENT; - - int sprite_height = ScaleGUITrad(GetVehicleHeight(VEH_TRAIN)); - int line_height = std::max(sprite_height, WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM); + bool rtl = _current_text_dir == TD_RTL; + int line_height = r.Height(); int sprite_y_offset = line_height / 2; int text_y_offset = (line_height - FONT_HEIGHT_NORMAL) / 2; /* draw the first 3 details tabs */ if (det_tab != TDW_TAB_TOTALS) { - bool rtl = _current_text_dir == TD_RTL; Direction dir = rtl ? DIR_E : DIR_W; - int x = rtl ? right : left; + int x = rtl ? r.right : r.left; for (; v != nullptr && vscroll_pos > -vscroll_cap; v = v->GetNextVehicle()) { GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary); @@ -392,53 +384,52 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po int pitch = 0; const Engine *e = Engine::Get(v->engine_type); if (e->GetGRF() != nullptr) { - pitch = ScaleGUITrad(e->GetGRF()->traininfo_vehicle_pitch); + pitch = ScaleSpriteTrad(e->GetGRF()->traininfo_vehicle_pitch); } PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); VehicleSpriteSeq seq; u->GetImage(dir, EIT_IN_DETAILS, &seq); - seq.Draw(px + (rtl ? -offset.x : offset.x), y - line_height * vscroll_pos + sprite_y_offset + pitch, pal, (v->vehstatus & VS_CRASHED) != 0); + seq.Draw(px + (rtl ? -offset.x : offset.x), r.top - line_height * vscroll_pos + sprite_y_offset + pitch, pal, (v->vehstatus & VS_CRASHED) != 0); } px += rtl ? -width : width; dx += width; u = u->Next(); } while (u != nullptr && u->IsArticulatedPart()); - bool separate_sprite_row = (dx > (uint)ScaleGUITrad(TRAIN_DETAILS_MAX_INDENT)); + bool separate_sprite_row = (dx > (uint)ScaleSpriteTrad(TRAIN_DETAILS_MAX_INDENT)); if (separate_sprite_row) { vscroll_pos--; dx = 0; } + int sprite_width = std::max(dx, ScaleSpriteTrad(TRAIN_DETAILS_MIN_INDENT)) + WidgetDimensions::scaled.hsep_normal; + Rect dr = r.Indent(sprite_width, rtl); uint num_lines = std::max(1u, (unsigned)_cargo_summary.size()); for (uint i = 0; i < num_lines; i++) { - int sprite_width = std::max(dx, ScaleGUITrad(TRAIN_DETAILS_MIN_INDENT)) + 3; - int data_left = left + (rtl ? 0 : sprite_width); - int data_right = right - (rtl ? sprite_width : 0); if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) { - int py = y - line_height * vscroll_pos + text_y_offset; + int py = r.top - line_height * vscroll_pos + text_y_offset; if (i > 0 || separate_sprite_row) { - if (vscroll_pos != 0) GfxFillRect(left, py - WD_MATRIX_TOP - 1, right, py - WD_MATRIX_TOP, _colour_gradient[COLOUR_GREY][5]); + if (vscroll_pos != 0) GfxFillRect(r.left, py - WidgetDimensions::scaled.matrix.top - 1, r.right, py - WidgetDimensions::scaled.matrix.top, _colour_gradient[COLOUR_GREY][5]); } switch (det_tab) { case TDW_TAB_CARGO: if (i < _cargo_summary.size()) { - TrainDetailsCargoTab(&_cargo_summary[i], data_left, data_right, py); + TrainDetailsCargoTab(&_cargo_summary[i], dr.left, dr.right, py); } else { - DrawString(data_left, data_right, py, STR_QUANTITY_N_A, TC_LIGHT_BLUE); + DrawString(dr.left, dr.right, py, STR_QUANTITY_N_A, TC_LIGHT_BLUE); } break; case TDW_TAB_INFO: - if (i == 0) TrainDetailsInfoTab(v, data_left, data_right, py); + if (i == 0) TrainDetailsInfoTab(v, dr.left, dr.right, py); break; case TDW_TAB_CAPACITY: if (i < _cargo_summary.size()) { - TrainDetailsCapacityTab(&_cargo_summary[i], data_left, data_right, py); + TrainDetailsCapacityTab(&_cargo_summary[i], dr.left, dr.right, py); } else { SetDParam(0, STR_EMPTY); - DrawString(data_left, data_right, py, STR_VEHICLE_INFO_NO_CAPACITY); + DrawString(dr.left, dr.right, py, STR_VEHICLE_INFO_NO_CAPACITY); } break; @@ -449,6 +440,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po } } } else { + int y = r.top; CargoArray act_cargo; CargoArray max_cargo; Money feeder_share = 0; @@ -460,9 +452,11 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po } /* draw total cargo tab */ - DrawString(left, right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT); + DrawString(r.left, r.right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT); y += line_height; + /* Indent the total cargo capacity details */ + Rect ir = r.Indent(WidgetDimensions::scaled.hsep_indent, rtl); for (CargoID i = 0; i < NUM_CARGO; i++) { if (max_cargo[i] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) { SetDParam(0, i); // {CARGO} #1 @@ -470,11 +464,11 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po SetDParam(2, i); // {SHORTCARGO} #1 SetDParam(3, max_cargo[i]); // {SHORTCARGO} #2 SetDParam(4, _settings_game.vehicle.freight_trains); - DrawString(left + offs_left, right - offs_right, y + text_y_offset, FreightWagonMult(i) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY); + DrawString(ir.left, ir.right, y + text_y_offset, FreightWagonMult(i) > 1 ? STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT : STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY); y += line_height; } } SetDParam(0, feeder_share); - DrawString(left, right, y + text_y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); + DrawString(r.left, r.right, y + text_y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE); } } diff --git a/src/transparency_gui.cpp b/src/transparency_gui.cpp index 153dcb5d03f2c..479e0f8b7a6ee 100644 --- a/src/transparency_gui.cpp +++ b/src/transparency_gui.cpp @@ -52,18 +52,20 @@ class TransparenciesWindow : public Window case WID_TT_CATENARY: case WID_TT_LOADING: { uint i = widget - WID_TT_BEGIN; - if (HasBit(_transparency_lock, i)) DrawSprite(SPR_LOCK, PAL_NONE, r.left + 1, r.top + 1); + if (HasBit(_transparency_lock, i)) DrawSprite(SPR_LOCK, PAL_NONE, r.left + WidgetDimensions::scaled.fullbevel.left, r.top + WidgetDimensions::scaled.fullbevel.top); break; } - case WID_TT_BUTTONS: + case WID_TT_BUTTONS: { + const Rect fr = r.Shrink(WidgetDimensions::scaled.framerect); for (uint i = WID_TT_BEGIN; i < WID_TT_END; i++) { if (i == WID_TT_LOADING) continue; // Do not draw button for invisible loading indicators. - const NWidgetBase *wi = this->GetWidget(i); - DrawFrameRect(wi->pos_x + 1, r.top + 2, wi->pos_x + wi->current_x - 2, r.bottom - 2, COLOUR_PALE_GREEN, + const Rect wr = this->GetWidget(i)->GetCurrentRect().Shrink(WidgetDimensions::scaled.fullbevel); + DrawFrameRect(wr.left, fr.top, wr.right, fr.bottom, COLOUR_PALE_GREEN, HasBit(_invisibility_opt, i - WID_TT_BEGIN) ? FR_LOWERED : FR_NONE); } break; + } } } diff --git a/src/tree_cmd.cpp b/src/tree_cmd.cpp index 4287f92f69501..9f4ae64e233cd 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.cpp @@ -174,9 +174,6 @@ static void PlaceTree(TileIndex tile, uint32 r) if (ground != TREE_GROUND_SNOW_DESERT && ground != TREE_GROUND_ROUGH_SNOW && ground != TREE_GROUND_SHORE) { SetTreeGroundDensity(tile, (TreeGround)GB(r, 28, 1), 3); } - - /* Set the counter to a random start value */ - SetTreeCounter(tile, (TreeGround)GB(r, 24, 4)); } } @@ -250,7 +247,7 @@ void PlaceTreesRandomly() { int i, j, ht; - i = ScaleByMapSize(DEFAULT_TREE_STEPS); + i = Map::ScaleBySize(DEFAULT_TREE_STEPS); if (_game_mode == GM_EDITOR) i /= EDITOR_TREE_DIV; do { uint32 r = Random(); @@ -278,7 +275,7 @@ void PlaceTreesRandomly() /* place extra trees at rainforest area */ if (_settings_game.game_creation.landscape == LT_TROPIC) { - i = ScaleByMapSize(DEFAULT_RAINFOREST_TREE_STEPS); + i = Map::ScaleBySize(DEFAULT_RAINFOREST_TREE_STEPS); if (_game_mode == GM_EDITOR) i /= EDITOR_TREE_DIV; do { @@ -308,6 +305,7 @@ void PlaceTreesRandomly() */ uint PlaceTreeGroupAroundTile(TileIndex tile, TreeType treetype, uint radius, uint count, bool set_zone) { + assert(_game_mode == GM_EDITOR); // Due to InteractiveRandom being used in this function assert(treetype < TREE_TOYLAND + TREE_COUNT_TOYLAND); const bool allow_desert = treetype == TREE_CACTUS; uint planted = 0; @@ -364,10 +362,10 @@ void GenerateTrees() default: NOT_REACHED(); } - total = ScaleByMapSize(DEFAULT_TREE_STEPS); - if (_settings_game.game_creation.landscape == LT_TROPIC) total += ScaleByMapSize(DEFAULT_RAINFOREST_TREE_STEPS); + total = Map::ScaleBySize(DEFAULT_TREE_STEPS); + if (_settings_game.game_creation.landscape == LT_TROPIC) total += Map::ScaleBySize(DEFAULT_RAINFOREST_TREE_STEPS); total *= i; - uint num_groups = (_settings_game.game_creation.landscape != LT_TOYLAND) ? ScaleByMapSize(GB(Random(), 0, 5) + 25) : 0; + uint num_groups = (_settings_game.game_creation.landscape != LT_TOYLAND) ? Map::ScaleBySize(GB(Random(), 0, 5) + 25) : 0; total += num_groups * DEFAULT_TREE_STEPS; SetGeneratingWorldProgress(GWP_TREE, total); @@ -384,22 +382,24 @@ void GenerateTrees() * @param tile end tile of area-drag * @param start_tile start tile of area-drag of tree plantation * @param tree_to_plant tree type, TREE_INVALID means random. + * @param diagonal Whether to use the Orthogonal (false) or Diagonal (true) iterator. * @return the cost of this operation or an error */ -CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, byte tree_to_plant) +CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, byte tree_to_plant, bool diagonal) { StringID msg = INVALID_STRING_ID; CommandCost cost(EXPENSES_OTHER); - if (start_tile >= MapSize()) return CMD_ERROR; + if (start_tile >= Map::Size()) return CMD_ERROR; /* Check the tree type within the current climate */ if (tree_to_plant != TREE_INVALID && !IsInsideBS(tree_to_plant, _tree_base_by_landscape[_settings_game.game_creation.landscape], _tree_count_by_landscape[_settings_game.game_creation.landscape])) return CMD_ERROR; Company *c = (_game_mode != GM_EDITOR) ? Company::GetIfValid(_current_company) : nullptr; int limit = (c == nullptr ? INT32_MAX : GB(c->tree_limit, 16, 16)); - TileArea ta(tile, start_tile); - for (TileIndex current_tile : ta) { + std::unique_ptr iter = TileIterator::Create(tile, start_tile, diagonal); + for (; *iter != INVALID_TILE; ++(*iter)) { + TileIndex current_tile = *iter; switch (GetTileType(current_tile)) { case MP_TREES: /* no more space for trees? */ @@ -710,10 +710,14 @@ static void TileLoop_Trees(TileIndex tile) if ((_date_fract % GetPaceFactor()) != 0) return; - uint treeCounter = GetTreeCounter(tile); + /* _tick_counter is incremented by 256 between each call, so ignore lower 8 bits. + * Also, we use a simple hash to spread the updates evenly over the map. + * 11 and 9 are just some co-prime numbers for better spread. + */ + uint32 cycle = 11 * TileX(tile) + 9 * TileY(tile) + (_tick_counter >> 8); /* Handle growth of grass (under trees/on MP_TREES tiles) at every 8th processings, like it's done for grass on MP_CLEAR tiles. */ - if ((treeCounter & 7) == 7 && GetTreeGround(tile) == TREE_GROUND_GRASS) { + if ((cycle & 7) == 7 && GetTreeGround(tile) == TREE_GROUND_GRASS) { uint density = GetTreeDensity(tile); if (density < 3) { SetTreeGroundDensity(tile, TREE_GROUND_GRASS, density + 1); @@ -723,11 +727,7 @@ static void TileLoop_Trees(TileIndex tile) if (_settings_game.construction.extra_tree_placement == ETP_NO_GROWTH_NO_SPREAD) return; - if (GetTreeCounter(tile) < 15) { - AddTreeCounter(tile, 1); - return; - } - SetTreeCounter(tile, 0); + if ((cycle & 15) != 15) return; switch (GetTreeGrowth(tile)) { case 3: // regular sized tree @@ -827,7 +827,7 @@ bool DecrementTreeCounter() /* byte underflow */ byte old_trees_tick_ctr = _trees_tick_ctr; - _trees_tick_ctr -= ScaleByMapSize(1); + _trees_tick_ctr -= Map::ScaleBySize(1); return old_trees_tick_ctr <= _trees_tick_ctr; } @@ -846,12 +846,12 @@ void OnTick_Trees() /* Skip some tree ticks for map sizes below 256 * 256. 64 * 64 is 16 times smaller, so * this is the maximum number of ticks that are skipped. Number of ticks to skip is * inversely proportional to map size, so that is handled to create a mask. */ - int skip = ScaleByMapSize(16); + int skip = Map::ScaleBySize(16); if (skip < 16 && (_tick_counter & (16 / skip - 1)) != 0) return; /* place a tree at a random rainforest spot */ if (_settings_game.game_creation.landscape == LT_TROPIC) { - for (uint c = ScaleByMapSize(1); c > 0; c--) { + for (uint c = Map::ScaleBySize(1); c > 0; c--) { if ((r = Random(), tile = RandomTileSeed(r), GetTropicZone(tile) == TROPICZONE_RAINFOREST) && CanPlantTreesOnTile(tile, false) && (tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) { diff --git a/src/tree_cmd.h b/src/tree_cmd.h index 8f2199e3e8373..d730cf74ae927 100644 --- a/src/tree_cmd.h +++ b/src/tree_cmd.h @@ -12,7 +12,7 @@ #include "command_type.h" -CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, byte tree_to_plant); +CommandCost CmdPlantTree(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, byte tree_to_plant, bool diagonal); DEF_CMD_TRAIT(CMD_PLANT_TREE, CmdPlantTree, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION) diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index 0b0eeda22b3d2..5292ba1e64d77 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.cpp @@ -58,8 +58,8 @@ static Dimension GetMaxTreeSpriteSize() Dimension size, this_size; Point offset; /* Avoid to use it uninitialized */ - size.width = 32; // default width - WD_FRAMERECT_LEFT - size.height = 39; // default height - BUTTON_BOTTOM_OFFSET + size.width = ScaleGUITrad(32); // default width - WD_FRAMERECT_LEFT + size.height = ScaleGUITrad(39); // default height - BUTTON_BOTTOM_OFFSET offset.x = 0; offset.y = 0; @@ -103,7 +103,7 @@ class BuildTreesWindow : public Window if (this->tree_to_plant >= 0) { /* Activate placement */ if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); - SetObjectToPlace(SPR_CURSOR_TREE, PAL_NONE, HT_RECT, this->window_class, this->window_number); + SetObjectToPlace(SPR_CURSOR_TREE, PAL_NONE, HT_RECT | HT_DIAGONAL, this->window_class, this->window_number); this->tree_to_plant = current_tree; // SetObjectToPlace may call ResetObjectToPlace which may reset tree_to_plant to -1 } else { /* Deactivate placement */ @@ -159,8 +159,8 @@ class BuildTreesWindow : public Window if (widget >= WID_BT_TYPE_BUTTON_FIRST) { /* Ensure tree type buttons are sized after the largest tree type */ Dimension d = GetMaxTreeSpriteSize(); - size->width = d.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - size->height = d.height + WD_FRAMERECT_RIGHT + WD_FRAMERECT_BOTTOM + ScaleGUITrad(BUTTON_BOTTOM_OFFSET); // we need some more space + size->width = d.width + padding.width; + size->height = d.height + padding.height + ScaleGUITrad(BUTTON_BOTTOM_OFFSET); // we need some more space } } @@ -169,7 +169,7 @@ class BuildTreesWindow : public Window if (widget >= WID_BT_TYPE_BUTTON_FIRST) { const int index = widget - WID_BT_TYPE_BUTTON_FIRST; /* Trees "grow" in the centre on the bottom line of the buttons */ - DrawSprite(tree_sprites[index].sprite, tree_sprites[index].pal, (r.left + r.right) / 2 + WD_FRAMERECT_LEFT, r.bottom - ScaleGUITrad(BUTTON_BOTTOM_OFFSET)); + DrawSprite(tree_sprites[index].sprite, tree_sprites[index].pal, CenterBounds(r.left, r.right, 0), r.bottom - ScaleGUITrad(BUTTON_BOTTOM_OFFSET)); } } @@ -231,7 +231,7 @@ class BuildTreesWindow : public Window TileIndex tile = TileVirtXY(pt.x, pt.y); if (this->mode == PM_NORMAL) { - Command::Post(tile, tile, this->tree_to_plant); + Command::Post(tile, tile, this->tree_to_plant, false); } else { this->DoPlantForest(tile); } @@ -241,7 +241,7 @@ class BuildTreesWindow : public Window void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (_game_mode != GM_EDITOR && this->mode == PM_NORMAL && pt.x != -1 && select_proc == DDSP_PLANT_TREES) { - Command::Post(STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, start_tile, this->tree_to_plant); + Command::Post(STR_ERROR_CAN_T_PLANT_TREE_HERE, end_tile, start_tile, this->tree_to_plant, _ctrl_pressed); } } diff --git a/src/tree_map.h b/src/tree_map.h index e8f68d825d9cc..9bed461a5174c 100644 --- a/src/tree_map.h +++ b/src/tree_map.h @@ -70,10 +70,10 @@ enum TreeGround { * @return The treetype of the given tile with trees * @pre Tile t must be of type MP_TREES */ -static inline TreeType GetTreeType(TileIndex t) +static inline TreeType GetTreeType(Tile t) { assert(IsTileType(t, MP_TREES)); - return (TreeType)_m[t].m3; + return (TreeType)t.m3(); } /** @@ -85,10 +85,10 @@ static inline TreeType GetTreeType(TileIndex t) * @return The groundtype of the tile * @pre Tile must be of type MP_TREES */ -static inline TreeGround GetTreeGround(TileIndex t) +static inline TreeGround GetTreeGround(Tile t) { assert(IsTileType(t, MP_TREES)); - return (TreeGround)GB(_m[t].m2, 6, 3); + return (TreeGround)GB(t.m2(), 6, 3); } /** @@ -110,10 +110,10 @@ static inline TreeGround GetTreeGround(TileIndex t) * @pre Tile must be of type MP_TREES * @see GetTreeCount */ -static inline uint GetTreeDensity(TileIndex t) +static inline uint GetTreeDensity(Tile t) { assert(IsTileType(t, MP_TREES)); - return GB(_m[t].m2, 4, 2); + return GB(t.m2(), 4, 2); } /** @@ -127,11 +127,11 @@ static inline uint GetTreeDensity(TileIndex t) * @param d The density to save with * @pre Tile must be of type MP_TREES */ -static inline void SetTreeGroundDensity(TileIndex t, TreeGround g, uint d) +static inline void SetTreeGroundDensity(Tile t, TreeGround g, uint d) { assert(IsTileType(t, MP_TREES)); // XXX incomplete - SB(_m[t].m2, 4, 2, d); - SB(_m[t].m2, 6, 3, g); + SB(t.m2(), 4, 2, d); + SB(t.m2(), 6, 3, g); SetWaterClass(t, g == TREE_GROUND_SHORE ? WATER_CLASS_SEA : WATER_CLASS_INVALID); } @@ -146,10 +146,10 @@ static inline void SetTreeGroundDensity(TileIndex t, TreeGround g, uint d) * @return The number of trees (1-4) * @pre Tile must be of type MP_TREES */ -static inline uint GetTreeCount(TileIndex t) +static inline uint GetTreeCount(Tile t) { assert(IsTileType(t, MP_TREES)); - return GB(_m[t].m5, 6, 2) + 1; + return GB(t.m5(), 6, 2) + 1; } /** @@ -163,10 +163,10 @@ static inline uint GetTreeCount(TileIndex t) * @param c The value to add (or reduce) on the tree-count value * @pre Tile must be of type MP_TREES */ -static inline void AddTreeCount(TileIndex t, int c) +static inline void AddTreeCount(Tile t, int c) { assert(IsTileType(t, MP_TREES)); // XXX incomplete - _m[t].m5 += c << 6; + t.m5() += c << 6; } /** @@ -178,10 +178,10 @@ static inline void AddTreeCount(TileIndex t, int c) * @return The tree growth status * @pre Tile must be of type MP_TREES */ -static inline uint GetTreeGrowth(TileIndex t) +static inline uint GetTreeGrowth(Tile t) { assert(IsTileType(t, MP_TREES)); - return GB(_m[t].m5, 0, 3); + return GB(t.m5(), 0, 3); } /** @@ -193,10 +193,10 @@ static inline uint GetTreeGrowth(TileIndex t) * @param a The value to add on the tree growth status * @pre Tile must be of type MP_TREES */ -static inline void AddTreeGrowth(TileIndex t, int a) +static inline void AddTreeGrowth(Tile t, int a) { assert(IsTileType(t, MP_TREES)); // XXX incomplete - _m[t].m5 += a; + t.m5() += a; } /** @@ -209,54 +209,10 @@ static inline void AddTreeGrowth(TileIndex t, int a) * @param g The new value * @pre Tile must be of type MP_TREES */ -static inline void SetTreeGrowth(TileIndex t, uint g) +static inline void SetTreeGrowth(Tile t, uint g) { assert(IsTileType(t, MP_TREES)); // XXX incomplete - SB(_m[t].m5, 0, 3, g); -} - -/** - * Get the tick counter of a tree tile. - * - * Returns the saved tick counter of a given tile. - * - * @param t The tile to get the counter value from - * @pre Tile must be of type MP_TREES - */ -static inline uint GetTreeCounter(TileIndex t) -{ - assert(IsTileType(t, MP_TREES)); - return GB(_m[t].m2, 0, 4); -} - -/** - * Add a value on the tick counter of a tree-tile - * - * This function adds a value on the tick counter of a tree-tile. - * - * @param t The tile to add the value on - * @param a The value to add on the tick counter - * @pre Tile must be of type MP_TREES - */ -static inline void AddTreeCounter(TileIndex t, int a) -{ - assert(IsTileType(t, MP_TREES)); // XXX incomplete - _m[t].m2 += a; -} - -/** - * Set the tick counter for a tree-tile - * - * This function sets directly the tick counter for a tree-tile. - * - * @param t The tile to set the tick counter - * @param c The new tick counter value - * @pre Tile must be of type MP_TREES - */ -static inline void SetTreeCounter(TileIndex t, uint c) -{ - assert(IsTileType(t, MP_TREES)); // XXX incomplete - SB(_m[t].m2, 0, 4, c); + SB(t.m5(), 0, 3, g); } /** @@ -271,17 +227,17 @@ static inline void SetTreeCounter(TileIndex t, uint c) * @param ground the ground type * @param density the density (not the number of trees) */ -static inline void MakeTree(TileIndex t, TreeType type, uint count, uint growth, TreeGround ground, uint density) +static inline void MakeTree(Tile t, TreeType type, uint count, uint growth, TreeGround ground, uint density) { SetTileType(t, MP_TREES); SetTileOwner(t, OWNER_NONE); SetWaterClass(t, ground == TREE_GROUND_SHORE ? WATER_CLASS_SEA : WATER_CLASS_INVALID); - _m[t].m2 = ground << 6 | density << 4 | 0; - _m[t].m3 = type; - _m[t].m4 = 0 << 5 | 0 << 2; - _m[t].m5 = count << 6 | growth; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; + t.m2() = ground << 6 | density << 4 | 0; + t.m3() = type; + t.m4() = 0 << 5 | 0 << 2; + t.m5() = count << 6 | growth; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; } #endif /* TREE_MAP_H */ diff --git a/src/tunnel_map.cpp b/src/tunnel_map.cpp index 9de52358013e8..dc7c35e415c1c 100644 --- a/src/tunnel_map.cpp +++ b/src/tunnel_map.cpp @@ -67,6 +67,6 @@ bool IsTunnelInWayDir(TileIndex tile, int z, DiagDirection dir) */ bool IsTunnelInWay(TileIndex tile, int z) { - return IsTunnelInWayDir(tile, z, (TileX(tile) > (MapMaxX() / 2)) ? DIAGDIR_NE : DIAGDIR_SW) || - IsTunnelInWayDir(tile, z, (TileY(tile) > (MapMaxY() / 2)) ? DIAGDIR_NW : DIAGDIR_SE); + return IsTunnelInWayDir(tile, z, (TileX(tile) > (Map::MaxX() / 2)) ? DIAGDIR_NE : DIAGDIR_SW) || + IsTunnelInWayDir(tile, z, (TileY(tile) > (Map::MaxY() / 2)) ? DIAGDIR_NW : DIAGDIR_SE); } diff --git a/src/tunnel_map.h b/src/tunnel_map.h index c347626d556cf..757d988ac763f 100644 --- a/src/tunnel_map.h +++ b/src/tunnel_map.h @@ -20,10 +20,10 @@ * @pre IsTileType(t, MP_TUNNELBRIDGE) * @return true if and only if this tile is a tunnel (entrance) */ -static inline bool IsTunnel(TileIndex t) +static inline bool IsTunnel(Tile t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); - return !HasBit(_m[t].m5, 7); + return !HasBit(t.m5(), 7); } /** @@ -31,7 +31,7 @@ static inline bool IsTunnel(TileIndex t) * @param t the tile that might be a tunnel * @return true if and only if this tile is a tunnel (entrance) */ -static inline bool IsTunnelTile(TileIndex t) +static inline bool IsTunnelTile(Tile t) { return IsTileType(t, MP_TUNNELBRIDGE) && IsTunnel(t); } @@ -47,17 +47,17 @@ bool IsTunnelInWayDir(TileIndex tile, int z, DiagDirection dir); * @param d the direction facing out of the tunnel * @param r the road type used in the tunnel */ -static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadType road_rt, RoadType tram_rt) +static inline void MakeRoadTunnel(Tile t, Owner o, DiagDirection d, RoadType road_rt, RoadType tram_rt) { SetTileType(t, MP_TUNNELBRIDGE); SetTileOwner(t, o); - _m[t].m2 = 0; - _m[t].m3 = 0; - _m[t].m4 = 0; - _m[t].m5 = TRANSPORT_ROAD << 2 | d; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; - _me[t].m8 = 0; + t.m2() = 0; + t.m3() = 0; + t.m4() = 0; + t.m5() = TRANSPORT_ROAD << 2 | d; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; + t.m8() = 0; SetRoadOwner(t, RTT_ROAD, o); if (o != OWNER_TOWN) SetRoadOwner(t, RTT_TRAM, o); SetRoadTypes(t, road_rt, tram_rt); @@ -70,17 +70,17 @@ static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadTyp * @param d the direction facing out of the tunnel * @param r the rail type used in the tunnel */ -static inline void MakeRailTunnel(TileIndex t, Owner o, DiagDirection d, RailType r) +static inline void MakeRailTunnel(Tile t, Owner o, DiagDirection d, RailType r) { SetTileType(t, MP_TUNNELBRIDGE); SetTileOwner(t, o); - _m[t].m2 = 0; - _m[t].m3 = 0; - _m[t].m4 = 0; - _m[t].m5 = TRANSPORT_RAIL << 2 | d; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; - _me[t].m8 = 0; + t.m2() = 0; + t.m3() = 0; + t.m4() = 0; + t.m5() = TRANSPORT_RAIL << 2 | d; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; + t.m8() = 0; SetRailType(t, r); SetRoadTypes(t, INVALID_ROADTYPE, INVALID_ROADTYPE); } diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index dc345c8fee799..e9f4fb7169d8c 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -673,9 +673,9 @@ CommandCost CmdBuildTunnel(DoCommandFlag flags, TileIndex start_tile, TransportT TileIndexDiff delta = TileOffsByDiagDir(direction); DiagDirection tunnel_in_way_dir; if (DiagDirToAxis(direction) == AXIS_Y) { - tunnel_in_way_dir = (TileX(start_tile) < (MapMaxX() / 2)) ? DIAGDIR_SW : DIAGDIR_NE; + tunnel_in_way_dir = (TileX(start_tile) < (Map::MaxX() / 2)) ? DIAGDIR_SW : DIAGDIR_NE; } else { - tunnel_in_way_dir = (TileY(start_tile) < (MapMaxX() / 2)) ? DIAGDIR_SE : DIAGDIR_NW; + tunnel_in_way_dir = (TileY(start_tile) < (Map::MaxX() / 2)) ? DIAGDIR_SE : DIAGDIR_NW; } TileIndex end_tile = start_tile; @@ -862,7 +862,7 @@ static CommandCost DoClearTunnel(TileIndex tile, DoCommandFlag flags) /* Check if you are allowed to remove the tunnel owned by a town * Removal depends on difficulty settings */ - CommandCost ret = CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE); + ret = CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE); if (ret.Failed()) return ret; } @@ -943,7 +943,7 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlag flags) /* Check if you are allowed to remove the bridge owned by a town * Removal depends on difficulty settings */ - CommandCost ret = CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE); + ret = CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE); if (ret.Failed()) return ret; } @@ -968,9 +968,6 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlag flags) if (v != nullptr) FreeTrainTrackReservation(v); } - bool removetile = false; - bool removeendtile = false; - /* Update company infrastructure counts. */ if (rail) { if (Company::IsValidID(owner)) Company::Get(owner)->infrastructure.rail[GetRailType(tile)] -= len * TUNNELBRIDGE_TRACKBIT_FACTOR; @@ -980,16 +977,12 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlag flags) UpdateCompanyRoadInfrastructure(GetRoadTypeTram(tile), GetRoadOwner(tile, RTT_TRAM), -(int)(len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR)); } else { // Aqueduct if (Company::IsValidID(owner)) Company::Get(owner)->infrastructure.water -= len * TUNNELBRIDGE_TRACKBIT_FACTOR; - removetile = IsDockingTile(tile); - removeendtile = IsDockingTile(endtile); } DirtyCompanyInfrastructureWindows(owner); DoClearSquare(tile); DoClearSquare(endtile); - if (removetile) RemoveDockingTile(tile); - if (removeendtile) RemoveDockingTile(endtile); for (TileIndex c = tile + delta; c != endtile; c += delta) { /* do not let trees appear from 'nowhere' after removing bridge */ if (IsNormalRoadTile(c) && GetRoadside(c) == ROADSIDE_TREES) { @@ -1314,8 +1307,28 @@ static void DrawTile_TunnelBridge(TileInfo *ti) const RoadTypeInfo *road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt); const RoadTypeInfo *tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt); uint sprite_offset = DiagDirToAxis(tunnelbridge_direction) == AXIS_X ? 1 : 0; + bool draw_underlay = true; + + /* Road underlay takes precedence over tram */ + if (road_rti != nullptr) { + if (road_rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_TUNNEL); + if (ground != 0) { + DrawGroundSprite(ground + tunnelbridge_direction, PAL_NONE); + draw_underlay = false; + } + } + } else { + if (tram_rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(tram_rti, ti->tile, ROTSG_TUNNEL); + if (ground != 0) { + DrawGroundSprite(ground + tunnelbridge_direction, PAL_NONE); + draw_underlay = false; + } + } + } - DrawRoadOverlays(ti, PAL_NONE, road_rti, tram_rti, sprite_offset, sprite_offset); + DrawRoadOverlays(ti, PAL_NONE, road_rti, tram_rti, sprite_offset, sprite_offset, draw_underlay); /* Road catenary takes precedence over tram */ SpriteID catenary_sprite_base = 0; @@ -1744,12 +1757,16 @@ static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td) if (!IsTunnel(tile)) { uint16 spd = GetBridgeSpec(GetBridgeType(tile))->speed; + /* rail speed special-cases 0 as unlimited, hides display of limit etc. */ + if (spd == UINT16_MAX) spd = 0; if (td->rail_speed == 0 || spd < td->rail_speed) { td->rail_speed = spd; } } } else if (tt == TRANSPORT_ROAD && !IsTunnel(tile)) { uint16 spd = GetBridgeSpec(GetBridgeType(tile))->speed; + /* road speed special-cases 0 as unlimited, hides display of limit etc. */ + if (spd == UINT16_MAX) spd = 0; if (road_rt != INVALID_ROADTYPE && (td->road_speed == 0 || spd < td->road_speed)) td->road_speed = spd; if (tram_rt != INVALID_ROADTYPE && (td->tram_speed == 0 || spd < td->tram_speed)) td->tram_speed = spd; } diff --git a/src/tunnelbridge_map.h b/src/tunnelbridge_map.h index 62d3c14b2dd60..3f1779ffa635c 100644 --- a/src/tunnelbridge_map.h +++ b/src/tunnelbridge_map.h @@ -23,10 +23,10 @@ * @pre IsTileType(t, MP_TUNNELBRIDGE) * @return the above mentioned direction */ -static inline DiagDirection GetTunnelBridgeDirection(TileIndex t) +static inline DiagDirection GetTunnelBridgeDirection(Tile t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); - return (DiagDirection)GB(_m[t].m5, 0, 2); + return (DiagDirection)GB(t.m5(), 0, 2); } /** @@ -36,10 +36,10 @@ static inline DiagDirection GetTunnelBridgeDirection(TileIndex t) * @pre IsTileType(t, MP_TUNNELBRIDGE) * @return the transport type in the tunnel/bridge */ -static inline TransportType GetTunnelBridgeTransportType(TileIndex t) +static inline TransportType GetTunnelBridgeTransportType(Tile t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); - return (TransportType)GB(_m[t].m5, 2, 2); + return (TransportType)GB(t.m5(), 2, 2); } /** @@ -49,10 +49,10 @@ static inline TransportType GetTunnelBridgeTransportType(TileIndex t) * @pre IsTileType(t, MP_TUNNELBRIDGE) * @return true if and only if the tile is in a snowy/desert area */ -static inline bool HasTunnelBridgeSnowOrDesert(TileIndex t) +static inline bool HasTunnelBridgeSnowOrDesert(Tile t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); - return HasBit(_me[t].m7, 5); + return HasBit(t.m7(), 5); } /** @@ -63,10 +63,10 @@ static inline bool HasTunnelBridgeSnowOrDesert(TileIndex t) * not in snow and not in desert false * @pre IsTileType(t, MP_TUNNELBRIDGE) */ -static inline void SetTunnelBridgeSnowOrDesert(TileIndex t, bool snow_or_desert) +static inline void SetTunnelBridgeSnowOrDesert(Tile t, bool snow_or_desert) { assert(IsTileType(t, MP_TUNNELBRIDGE)); - SB(_me[t].m7, 5, 1, snow_or_desert); + SB(t.m7(), 5, 1, snow_or_desert); } /** @@ -75,7 +75,7 @@ static inline void SetTunnelBridgeSnowOrDesert(TileIndex t, bool snow_or_desert) * @pre IsTileType(t, MP_TUNNELBRIDGE) * @return other end */ -static inline TileIndex GetOtherTunnelBridgeEnd(TileIndex t) +static inline TileIndex GetOtherTunnelBridgeEnd(Tile t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); return IsTunnel(t) ? GetOtherTunnelEnd(t) : GetOtherBridgeEnd(t); @@ -88,11 +88,11 @@ static inline TileIndex GetOtherTunnelBridgeEnd(TileIndex t) * @param t the tile * @return reservation state */ -static inline bool HasTunnelBridgeReservation(TileIndex t) +static inline bool HasTunnelBridgeReservation(Tile t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); assert(GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL); - return HasBit(_m[t].m5, 4); + return HasBit(t.m5(), 4); } /** @@ -101,11 +101,11 @@ static inline bool HasTunnelBridgeReservation(TileIndex t) * @param t the tile * @param b the reservation state */ -static inline void SetTunnelBridgeReservation(TileIndex t, bool b) +static inline void SetTunnelBridgeReservation(Tile t, bool b) { assert(IsTileType(t, MP_TUNNELBRIDGE)); assert(GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL); - SB(_m[t].m5, 4, 1, b ? 1 : 0); + SB(t.m5(), 4, 1, b ? 1 : 0); } /** @@ -114,7 +114,7 @@ static inline void SetTunnelBridgeReservation(TileIndex t, bool b) * @param t the tile * @return reserved track bits */ -static inline TrackBits GetTunnelBridgeReservationTrackBits(TileIndex t) +static inline TrackBits GetTunnelBridgeReservationTrackBits(Tile t) { return HasTunnelBridgeReservation(t) ? DiagDirToDiagTrackBits(GetTunnelBridgeDirection(t)) : TRACK_BIT_NONE; } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 28fbb3ed62bb2..a7196ab700d24 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -55,6 +55,7 @@ #include "misc_cmd.h" #include "train_cmd.h" #include "vehicle_cmd.h" +#include "newgrf_roadstop.h" #include "table/strings.h" @@ -212,7 +213,7 @@ bool Vehicle::NeedsServicing() const * Note: We do this after the service-interval test. * There are a lot more reasons for autoreplace to fail than we can test here reasonably. */ bool pending_replace = false; - Money needed_money = c->settings.engine_renew_money; + Money needed_money = c->settings.engine_renew_money * GetPaceFactor(); if (needed_money > c->money) return false; for (const Vehicle *v = this; v != nullptr; v = (v->type == VEH_TRAIN) ? Train::From(v)->GetNextUnit() : nullptr) { @@ -877,7 +878,6 @@ void Vehicle::PreDestructor() DeleteVehicleOrders(this); DeleteDepotHighlightOfVehicle(this); - extern void StopGlobalFollowVehicle(const Vehicle *v); StopGlobalFollowVehicle(this); ReleaseDisastersTargetingVehicle(this->index); @@ -1080,9 +1080,9 @@ void CallVehicleTicks() int z = v->z_pos; const Company *c = Company::Get(_current_company); - SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, (Money)c->settings.engine_renew_money)); + SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, (Money)c->settings.engine_renew_money * GetPaceFactor())); CommandCost res = Command::Do(DC_EXEC, v->index); - SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, -(Money)c->settings.engine_renew_money)); + SubtractMoneyFromCompany(CommandCost(EXPENSES_NEW_VEHICLES, -(Money)c->settings.engine_renew_money * GetPaceFactor())); if (!IsLocalCompany()) continue; @@ -1405,7 +1405,7 @@ void AgeVehicle(Vehicle *v) { if (v->age < MAX_DAY) { v->age++; - if (v->IsPrimaryVehicle() && v->age == VEHICLE_PROFIT_MIN_AGE + 1) GroupStatistics::VehicleReachedProfitAge(v); + if (v->IsPrimaryVehicle() && v->age == VEHICLE_PROFIT_MIN_AGE + 1) GroupStatistics::VehicleReachedMinAge(v); } if (!v->IsPrimaryVehicle() && (v->type != VEH_TRAIN || !Train::From(v)->IsEngine())) return; @@ -2140,7 +2140,7 @@ void Vehicle::BeginLoading() { assert(IsTileType(this->tile, MP_STATION) || this->type == VEH_SHIP); - uint32 travel_time = this->current_order_time; + Ticks travel_time = _tick_counter - this->last_loading_tick; if (this->current_order.IsType(OT_GOTO_STATION) && this->current_order.GetDestination() == this->last_station_visited) { this->DeleteUnreachedImplicitOrders(); @@ -2305,6 +2305,7 @@ void Vehicle::LeaveStation() /* if the vehicle could load here or could stop with cargo loaded set the last loading station */ this->last_loading_station = this->last_station_visited; + this->last_loading_tick = _tick_counter; } else { /* if the vehicle couldn't load and had to unload or transfer everything * set the last loading station to invalid as it will leave empty. */ @@ -2329,6 +2330,14 @@ void Vehicle::LeaveStation() SetBit(Train::From(this)->flags, VRF_LEAVING_STATION); } + if (this->type == VEH_ROAD && !(this->vehstatus & VS_CRASHED)) { + /* Trigger road stop animation */ + if (IsRoadStopTile(this->tile)) { + TriggerRoadStopRandomisation(st, this->tile, RSRT_VEH_DEPARTS); + TriggerRoadStopAnimation(st, this->tile, SAT_TRAIN_DEPARTS); + } + } + this->MarkDirty(); } @@ -2453,11 +2462,9 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) return CommandCost(); } - TileIndex location; - DestinationID destination; - bool reverse; + ClosestDepot closestDepot = this->FindClosestDepot(); static const StringID no_depot[] = {STR_ERROR_UNABLE_TO_FIND_ROUTE_TO, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT, STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR}; - if (!this->FindClosestDepot(&location, &destination, &reverse)) return_cmd_error(no_depot[this->type]); + if (!closestDepot.found) return_cmd_error(no_depot[this->type]); if (flags & DC_EXEC) { if (this->current_order.IsType(OT_LOADING)) this->LeaveStation(); @@ -2467,21 +2474,20 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS); } - this->SetDestTile(location); - this->current_order.MakeGoToDepot(destination, ODTF_MANUAL); + this->SetDestTile(closestDepot.location); + this->current_order.MakeGoToDepot(closestDepot.destination, ODTF_MANUAL); if ((command & DepotCommand::Service) == DepotCommand::None) this->current_order.SetDepotActionType(ODATFB_HALT); SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP); /* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */ - if (this->type == VEH_TRAIN && (reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) { + if (this->type == VEH_TRAIN && (closestDepot.reverse ^ HasBit(Train::From(this)->flags, VRF_REVERSING))) { Command::Do(DC_EXEC, this->index, false); } if (this->type == VEH_AIRCRAFT) { Aircraft *a = Aircraft::From(this); - if (a->state == FLYING && a->targetairport != destination) { + if (a->state == FLYING && a->targetairport != closestDepot.destination) { /* The aircraft is now heading for a different hangar than the next in the orders */ - extern void AircraftNextAirportPos_and_Order(Aircraft *a); AircraftNextAirportPos_and_Order(a); } } @@ -2928,6 +2934,58 @@ bool CanVehicleUseStation(const Vehicle *v, const Station *st) return CanVehicleUseStation(v->engine_type, st); } +/** + * Get reason string why this station can't be used by the given vehicle. + * @param v The vehicle to test. + * @param st The station to test for. + * @return The string explaining why the vehicle cannot use the station. + */ +StringID GetVehicleCannotUseStationReason(const Vehicle *v, const Station *st) +{ + switch (v->type) { + case VEH_TRAIN: + return STR_ERROR_NO_RAIL_STATION; + + case VEH_ROAD: { + const RoadVehicle *rv = RoadVehicle::From(v); + RoadStop *rs = st->GetPrimaryRoadStop(rv->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK); + + StringID err = rv->IsBus() ? STR_ERROR_NO_BUS_STATION : STR_ERROR_NO_TRUCK_STATION; + + for (; rs != nullptr; rs = rs->next) { + /* Articulated vehicles cannot use bay road stops, only drive-through. Make sure the vehicle can actually use this bay stop */ + if (HasTileAnyRoadType(rs->xy, rv->compatible_roadtypes) && IsStandardRoadStopTile(rs->xy) && rv->HasArticulatedPart()) { + err = STR_ERROR_NO_STOP_ARTICULATED_VEHICLE; + continue; + } + + /* Bay stop errors take precedence, but otherwise the vehicle may not be compatible with the roadtype/tramtype of this station tile. + * We give bay stop errors precedence because they are usually a bus sent to a tram station or vice versa. */ + if (!HasTileAnyRoadType(rs->xy, rv->compatible_roadtypes) && err != STR_ERROR_NO_STOP_ARTICULATED_VEHICLE) { + err = RoadTypeIsRoad(rv->roadtype) ? STR_ERROR_NO_STOP_COMPATIBLE_ROAD_TYPE : STR_ERROR_NO_STOP_COMPATIBLE_TRAM_TYPE; + continue; + } + } + + return err; + } + + case VEH_SHIP: + return STR_ERROR_NO_DOCK; + + case VEH_AIRCRAFT: + if ((st->facilities & FACIL_AIRPORT) == 0) return STR_ERROR_NO_AIRPORT; + if (v->GetEngine()->u.air.subtype & AIR_CTOL) { + return STR_ERROR_AIRPORT_NO_PLANES; + } else { + return STR_ERROR_AIRPORT_NO_HELICOPTERS; + } + + default: + return INVALID_STRING_ID; + } +} + /** * Access the ground vehicle cache of the vehicle. * @pre The vehicle is a #GroundVehicle. @@ -3017,3 +3075,65 @@ void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8 num_vehicles) } } } + +/** + * Calculates the maximum weight of the ground vehicle when loaded. + * @return Weight in tonnes + */ +uint32 Vehicle::GetDisplayMaxWeight() const +{ + uint32 max_weight = 0; + + for (const Vehicle* u = this; u != nullptr; u = u->Next()) { + max_weight += u->GetMaxWeight(); + } + + return max_weight; +} + +/** + * Calculates the minimum power-to-weight ratio using the maximum weight of the ground vehicle + * @return power-to-weight ratio in 10ths of hp(I) per tonne + */ +uint32 Vehicle::GetDisplayMinPowerToWeight() const +{ + uint32 max_weight = GetDisplayMaxWeight(); + if (max_weight == 0) return 0; + return GetGroundVehicleCache()->cached_power * 10u / max_weight; +} + +/** + * Checks if two vehicle chains have the same list of engines. + * @param v1 First vehicle chain. + * @param v1 Second vehicle chain. + * @return True if same, false if different. + */ +bool VehiclesHaveSameEngineList(const Vehicle *v1, const Vehicle *v2) +{ + while (true) { + if (v1 == nullptr && v2 == nullptr) return true; + if (v1 == nullptr || v2 == nullptr) return false; + if (v1->GetEngine() != v2->GetEngine()) return false; + v1 = v1->GetNextVehicle(); + v2 = v2->GetNextVehicle(); + } +} + +/** + * Checks if two vehicles have the same list of orders. + * @param v1 First vehicles. + * @param v1 Second vehicles. + * @return True if same, false if different. + */ +bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2) +{ + const Order *o1 = v1->GetFirstOrder(); + const Order *o2 = v2->GetFirstOrder(); + while (true) { + if (o1 == nullptr && o2 == nullptr) return true; + if (o1 == nullptr || o2 == nullptr) return false; + if (!o1->Equals(*o2)) return false; + o1 = o1->next; + o2 = o2->next; + } +} diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 4925e8c8f5aa4..6ece6460a1ef9 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -220,6 +220,23 @@ struct RefitDesc { cargo(cargo), capacity(capacity), remaining(remaining) {} }; +/** + * Structure to return information about the closest depot location, + * and whether it could be found. + */ +struct ClosestDepot { + TileIndex location; + DestinationID destination; ///< The DestinationID as used for orders. + bool reverse; + bool found; + + ClosestDepot() : + location(INVALID_TILE), destination(0), reverse(false), found(false) {} + + ClosestDepot(TileIndex location, DestinationID destination, bool reverse = false) : + location(location), destination(destination), reverse(reverse), found(true) {} +}; + /** %Vehicle data structure. */ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist { private: @@ -316,6 +333,7 @@ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist StationID last_station_visited; ///< The last station we stopped at. StationID last_loading_station; ///< Last station the vehicle has stopped at and could possibly leave from with any cargo loaded. + uint64_t last_loading_tick; ///< Last time (relative to _tick_counter) the vehicle has stopped at a station and could possibly leave with any cargo loaded. CargoID cargo_type; ///< type of cargo this vehicle is carrying byte cargo_subtype; ///< Used for livery refits (NewGRF variations) @@ -346,6 +364,15 @@ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist mutable MutableSpriteCache sprite_cache; ///< Cache of sprites and values related to recalculating them, see #MutableSpriteCache + /** + * Calculates the weight value that this vehicle will have when fully loaded with its current cargo. + * @return Weight value in tonnes. + */ + virtual uint16 GetMaxWeight() const + { + return 0; + } + Vehicle(VehicleType type = VEH_INVALID); void PreDestructor(); @@ -443,8 +470,9 @@ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist /** * Play the sound associated with leaving the station + * @param force Should we play the sound even if sound effects are muted? (horn hotkey) */ - virtual void PlayLeaveStationSound() const {} + virtual void PlayLeaveStationSound(bool force = false) const {} /** * Whether this is the primary vehicle in the chain. @@ -487,7 +515,7 @@ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist * Check if the vehicle is a ground vehicle. * @return True iff the vehicle is a train or a road vehicle. */ - inline bool IsGroundVehicle() const + debug_inline bool IsGroundVehicle() const { return this->type == VEH_TRAIN || this->type == VEH_ROAD; } @@ -768,12 +796,9 @@ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist /** * Find the closest depot for this vehicle and tell us the location, * DestinationID and whether we should reverse. - * @param location where do we go to? - * @param destination what hangar do we go to? - * @param reverse should the vehicle be reversed? - * @return true if a depot could be found. + * @return A structure with information about the closest depot, if found. */ - virtual bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) { return false; } + virtual ClosestDepot FindClosestDepot() { return {}; } virtual void SetDestTile(TileIndex tile) { this->dest_tile = tile; } @@ -907,7 +932,7 @@ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist * Check if the vehicle is a front engine. * @return Returns true if the vehicle is a front engine. */ - inline bool IsFrontEngine() const + debug_inline bool IsFrontEngine() const { return this->IsGroundVehicle() && HasBit(this->subtype, GVSF_FRONT); } @@ -1047,6 +1072,9 @@ struct Vehicle : VehiclePool::PoolItem<&_vehicle_pool>, BaseVehicle, BaseConsist * @return an iterable ensemble of orders of a vehicle */ IterateWrapper Orders() const { return IterateWrapper(this->orders); } + + uint32 GetDisplayMaxWeight() const; + uint32 GetDisplayMinPowerToWeight() const; }; /** diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 373a92cdbf175..4c432d9eefa74 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -84,25 +84,25 @@ const StringID _send_to_depot_msg_table[] = { * @param client_id User * @return the cost of this operation + the new vehicle ID + the refitted capacity + the refitted mail capacity (aircraft) or an error */ -std::tuple CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id) +std::tuple CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id) { /* Elementary check for valid location. */ - if (!IsDepotTile(tile) || !IsTileOwner(tile, _current_company)) return { CMD_ERROR, INVALID_VEHICLE, 0, 0 }; + if (!IsDepotTile(tile) || !IsTileOwner(tile, _current_company)) return { CMD_ERROR, INVALID_VEHICLE, 0, 0, {} }; VehicleType type = GetDepotVehicleType(tile); /* Validate the engine type. */ - if (!IsEngineBuildable(eid, type, _current_company)) return { CommandCost(STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE + type), INVALID_VEHICLE, 0, 0 }; + if (!IsEngineBuildable(eid, type, _current_company)) return { CommandCost(STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE + type), INVALID_VEHICLE, 0, 0, {} }; /* Validate the cargo type. */ - if (cargo >= NUM_CARGO && cargo != CT_INVALID) return { CMD_ERROR, INVALID_VEHICLE, 0, 0 }; + if (cargo >= NUM_CARGO && cargo != CT_INVALID) return { CMD_ERROR, INVALID_VEHICLE, 0, 0, {} }; const Engine *e = Engine::Get(eid); CommandCost value(EXPENSES_NEW_VEHICLES, e->GetCost()); /* Engines without valid cargo should not be available */ CargoID default_cargo = e->GetDefaultCargoType(); - if (default_cargo == CT_INVALID) return { CMD_ERROR, INVALID_VEHICLE, 0, 0 }; + if (default_cargo == CT_INVALID) return { CMD_ERROR, INVALID_VEHICLE, 0, 0, {} }; bool refitting = cargo != CT_INVALID && cargo != default_cargo; @@ -115,13 +115,13 @@ std::tuple CmdBuildVehicle(DoCommandFlag f case VEH_AIRCRAFT: num_vehicles = e->u.air.subtype & AIR_CTOL ? 2 : 3; break; default: NOT_REACHED(); // Safe due to IsDepotTile() } - if (!Vehicle::CanAllocateItem(num_vehicles)) return { CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME), INVALID_VEHICLE, 0, 0 }; + if (!Vehicle::CanAllocateItem(num_vehicles)) return { CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME), INVALID_VEHICLE, 0, 0, {} }; /* Check whether we can allocate a unit number. Autoreplace does not allocate * an unit number as it will (always) reuse the one of the replaced vehicle * and (train) wagons don't have an unit number in any scenario. */ UnitID unit_num = (flags & DC_QUERY_COST || flags & DC_AUTOREPLACE || (type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON)) ? 0 : GetFreeUnitNumber(type); - if (unit_num == UINT16_MAX) return { CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME), INVALID_VEHICLE, 0, 0 }; + if (unit_num == UINT16_MAX) return { CommandCost(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME), INVALID_VEHICLE, 0, 0, {} }; /* If we are refitting we need to temporarily purchase the vehicle to be able to * test it. */ @@ -145,6 +145,7 @@ std::tuple CmdBuildVehicle(DoCommandFlag f VehicleID veh_id = INVALID_VEHICLE; uint refitted_capacity = 0; uint16 refitted_mail_capacity = 0; + CargoArray cargo_capacities; if (value.Succeeded()) { if (subflags & DC_EXEC) { v->unitnumber = unit_num; @@ -155,11 +156,20 @@ std::tuple CmdBuildVehicle(DoCommandFlag f if (refitting) { /* Refit only one vehicle. If we purchased an engine, it may have gained free wagons. */ CommandCost cc; - std::tie(cc, refitted_capacity, refitted_mail_capacity) = CmdRefitVehicle(flags, v->index, cargo, 0, false, false, 1); + std::tie(cc, refitted_capacity, refitted_mail_capacity, cargo_capacities) = CmdRefitVehicle(flags, v->index, cargo, 0, false, false, 1); value.AddCost(cc); } else { /* Fill in non-refitted capacities */ - refitted_capacity = e->GetDisplayDefaultCapacity(&refitted_mail_capacity); + if (e->type == VEH_TRAIN || e->type == VEH_ROAD) { + cargo_capacities = GetCapacityOfArticulatedParts(eid); + refitted_capacity = cargo_capacities[default_cargo]; + refitted_mail_capacity = 0; + } else { + refitted_capacity = e->GetDisplayDefaultCapacity(&refitted_mail_capacity); + cargo_capacities.Clear(); + cargo_capacities[default_cargo] = refitted_capacity; + cargo_capacities[CT_MAIL] = refitted_mail_capacity; + } } if (flags & DC_EXEC) { @@ -191,7 +201,7 @@ std::tuple CmdBuildVehicle(DoCommandFlag f /* Only restore if we actually did some refitting */ if (flags != subflags) RestoreRandomSeeds(saved_seeds); - return { value, veh_id, refitted_capacity, refitted_mail_capacity }; + return { value, veh_id, refitted_capacity, refitted_mail_capacity, cargo_capacities }; } /** @@ -339,12 +349,13 @@ struct RefitResult { * @param auto_refit Refitting is done as automatic refitting outside a depot. * @return Refit cost + refittet capacity + mail capacity (aircraft). */ -static std::tuple RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, CargoID new_cid, byte new_subtype, DoCommandFlag flags, bool auto_refit) +static std::tuple RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, CargoID new_cid, byte new_subtype, DoCommandFlag flags, bool auto_refit) { CommandCost cost(v->GetExpenseType(false)); uint total_capacity = 0; uint total_mail_capacity = 0; num_vehicles = num_vehicles == 0 ? UINT8_MAX : num_vehicles; + CargoArray cargo_capacities; VehicleSet vehicles_to_refit; if (!only_this) { @@ -369,7 +380,11 @@ static std::tuple RefitVehicle(Vehicle *v, bool only_ /* If the vehicle is not refittable, or does not allow automatic refitting, * count its capacity nevertheless if the cargo matches */ bool refittable = HasBit(e->info.refit_mask, new_cid) && (!auto_refit || HasBit(e->info.misc_flags, EF_AUTO_REFIT)); - if (!refittable && v->cargo_type != new_cid) continue; + if (!refittable && v->cargo_type != new_cid) { + uint amount = e->DetermineCapacity(v, nullptr); + if (amount > 0) cargo_capacities[v->cargo_type] += amount; + continue; + } /* Determine best fitting subtype if requested */ if (actual_subtype == 0xFF) { @@ -390,6 +405,9 @@ static std::tuple RefitVehicle(Vehicle *v, bool only_ /* mail_capacity will always be zero if the vehicle is not an aircraft. */ total_mail_capacity += mail_capacity; + cargo_capacities[new_cid] += amount; + cargo_capacities[CT_MAIL] += mail_capacity; + if (!refittable) continue; /* Restore the original cargo type */ @@ -437,6 +455,7 @@ static std::tuple RefitVehicle(Vehicle *v, bool only_ u->cargo_subtype = result.subtype; if (u->type == VEH_AIRCRAFT) { Vehicle *w = u->Next(); + assert(w != nullptr); w->refit_cap = std::min(w->refit_cap, result.mail_capacity); w->cargo_cap = result.mail_capacity; if (w->cargo.TotalCount() > w->refit_cap) w->cargo.Truncate(w->cargo.TotalCount() - w->refit_cap); @@ -445,7 +464,7 @@ static std::tuple RefitVehicle(Vehicle *v, bool only_ } refit_result.clear(); - return { cost, total_capacity, total_mail_capacity }; + return { cost, total_capacity, total_mail_capacity, cargo_capacities }; } /** @@ -460,42 +479,42 @@ static std::tuple RefitVehicle(Vehicle *v, bool only_ * Only used if "refit only this vehicle" is false. * @return the cost of this operation or an error */ -std::tuple CmdRefitVehicle(DoCommandFlag flags, VehicleID veh_id, CargoID new_cid, byte new_subtype, bool auto_refit, bool only_this, uint8 num_vehicles) +std::tuple CmdRefitVehicle(DoCommandFlag flags, VehicleID veh_id, CargoID new_cid, byte new_subtype, bool auto_refit, bool only_this, uint8 num_vehicles) { Vehicle *v = Vehicle::GetIfValid(veh_id); - if (v == nullptr) return { CMD_ERROR, 0, 0 }; + if (v == nullptr) return { CMD_ERROR, 0, 0, {} }; /* Don't allow disasters and sparks and such to be refitted. * We cannot check for IsPrimaryVehicle as autoreplace also refits in free wagon chains. */ - if (!IsCompanyBuildableVehicleType(v->type)) return { CMD_ERROR, 0, 0 }; + if (!IsCompanyBuildableVehicleType(v->type)) return { CMD_ERROR, 0, 0, {} }; Vehicle *front = v->First(); CommandCost ret = CheckOwnership(front->owner); - if (ret.Failed()) return { ret, 0, 0 }; + if (ret.Failed()) return { ret, 0, 0, {} }; bool free_wagon = v->type == VEH_TRAIN && Train::From(front)->IsFreeWagon(); // used by autoreplace/renew /* Don't allow shadows and such to be refitted. */ - if (v != front && (v->type == VEH_SHIP || v->type == VEH_AIRCRAFT)) return { CMD_ERROR, 0, 0 }; + if (v != front && (v->type == VEH_SHIP || v->type == VEH_AIRCRAFT)) return { CMD_ERROR, 0, 0, {} }; /* Allow auto-refitting only during loading and normal refitting only in a depot. */ if ((flags & DC_QUERY_COST) == 0 && // used by the refit GUI, including the order refit GUI. !free_wagon && // used by autoreplace/renew (!auto_refit || !front->current_order.IsType(OT_LOADING)) && // refit inside stations !front->IsStoppedInDepot()) { // refit inside depots - return { CommandCost(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type), 0, 0}; + return { CommandCost(STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT + front->type), 0, 0, {} }; } - if (front->vehstatus & VS_CRASHED) return { CommandCost(STR_ERROR_VEHICLE_IS_DESTROYED), 0, 0}; + if (front->vehstatus & VS_CRASHED) return { CommandCost(STR_ERROR_VEHICLE_IS_DESTROYED), 0, 0, {} }; /* Check cargo */ - if (new_cid >= NUM_CARGO) return { CMD_ERROR, 0, 0 }; + if (new_cid >= NUM_CARGO) return { CMD_ERROR, 0, 0, {} }; /* For ships and aircraft there is always only one. */ only_this |= front->type == VEH_SHIP || front->type == VEH_AIRCRAFT; - auto [cost, refit_capacity, mail_capacity] = RefitVehicle(v, only_this, num_vehicles, new_cid, new_subtype, flags, auto_refit); + auto [cost, refit_capacity, mail_capacity, cargo_capacities] = RefitVehicle(v, only_this, num_vehicles, new_cid, new_subtype, flags, auto_refit); if (flags & DC_EXEC) { /* Update the cached variables */ @@ -532,7 +551,7 @@ std::tuple CmdRefitVehicle(DoCommandFlag flags, Vehic v->InvalidateNewGRFCacheOfChain(); } - return { cost, refit_capacity, mail_capacity }; + return { cost, refit_capacity, mail_capacity, cargo_capacities }; } /** @@ -851,7 +870,7 @@ std::tuple CmdCloneVehicle(DoCommandFlag flags, TileInde if ((flags & DC_EXEC) && !v->IsPrimaryVehicle()) build_flags |= DC_AUTOREPLACE; CommandCost cost; - std::tie(cost, new_veh_id, std::ignore, std::ignore) = Command::Do(build_flags, tile, v->engine_type, false, CT_INVALID, INVALID_CLIENT_ID); + std::tie(cost, new_veh_id, std::ignore, std::ignore, std::ignore) = Command::Do(build_flags, tile, v->engine_type, false, CT_INVALID, INVALID_CLIENT_ID); if (cost.Failed()) { /* Can't build a part, then sell the stuff we already made; clear up the mess */ @@ -958,7 +977,7 @@ std::tuple CmdCloneVehicle(DoCommandFlag flags, TileInde if (result.Failed()) { /* The vehicle has already been bought, so now it must be sold again. */ Command::Do(flags, w_front->index, true, false, INVALID_CLIENT_ID); - return { total_cost, INVALID_VEHICLE }; + return { result, INVALID_VEHICLE }; } /* Now clone the vehicle's name, if it has one. */ diff --git a/src/vehicle_cmd.h b/src/vehicle_cmd.h index 2f203b8652acb..3f8faf5d7d6c2 100644 --- a/src/vehicle_cmd.h +++ b/src/vehicle_cmd.h @@ -14,10 +14,11 @@ #include "engine_type.h" #include "vehicle_type.h" #include "vehiclelist.h" +#include "cargo_type.h" -std::tuple CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id); +std::tuple CmdBuildVehicle(DoCommandFlag flags, TileIndex tile, EngineID eid, bool use_free_vehicles, CargoID cargo, ClientID client_id); CommandCost CmdSellVehicle(DoCommandFlag flags, VehicleID v_id, bool sell_chain, bool backup_order, ClientID client_id); -std::tuple CmdRefitVehicle(DoCommandFlag flags, VehicleID veh_id, CargoID new_cid, byte new_subtype, bool auto_refit, bool only_this, uint8 num_vehicles); +std::tuple CmdRefitVehicle(DoCommandFlag flags, VehicleID veh_id, CargoID new_cid, byte new_subtype, bool auto_refit, bool only_this, uint8 num_vehicles); CommandCost CmdSendVehicleToDepot(DoCommandFlag flags, VehicleID veh_id, DepotCommand depot_cmd, const VehicleListIdentifier &vli); CommandCost CmdChangeServiceInt(DoCommandFlag flags, VehicleID veh_id, uint16 serv_int, bool is_custom, bool is_percent); CommandCost CmdRenameVehicle(DoCommandFlag flags, VehicleID veh_id, const std::string &text); @@ -27,19 +28,19 @@ CommandCost CmdMassStartStopVehicle(DoCommandFlag flags, TileIndex tile, bool do CommandCost CmdDepotSellAllVehicles(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type); CommandCost CmdDepotMassAutoReplace(DoCommandFlag flags, TileIndex tile, VehicleType vehicle_type); -DEF_CMD_TRAIT(CMD_BUILD_VEHICLE, CmdBuildVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_SELL_VEHICLE, CmdSellVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_REFIT_VEHICLE, CmdRefitVehicle, 0, CMDT_VEHICLE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_SEND_VEHICLE_TO_DEPOT, CmdSendVehicleToDepot, 0, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_CHANGE_SERVICE_INT, CmdChangeServiceInt, 0, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_RENAME_VEHICLE, CmdRenameVehicle, 0, CMDT_OTHER_MANAGEMENT) -DEF_CMD_TRAIT(CMD_CLONE_VEHICLE, CmdCloneVehicle, CMD_NO_TEST, CMDT_VEHICLE_CONSTRUCTION) // NewGRF callbacks influence building and refitting making it impossible to correctly estimate the cost -DEF_CMD_TRAIT(CMD_START_STOP_VEHICLE, CmdStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_MASS_START_STOP, CmdMassStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT) -DEF_CMD_TRAIT(CMD_DEPOT_SELL_ALL_VEHICLES, CmdDepotSellAllVehicles, 0, CMDT_VEHICLE_CONSTRUCTION) -DEF_CMD_TRAIT(CMD_DEPOT_MASS_AUTOREPLACE, CmdDepotMassAutoReplace, 0, CMDT_VEHICLE_CONSTRUCTION) - -void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16); +DEF_CMD_TRAIT(CMD_BUILD_VEHICLE, CmdBuildVehicle, CMD_CLIENT_ID, CMDT_VEHICLE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_SELL_VEHICLE, CmdSellVehicle, CMD_CLIENT_ID | CMD_LOCATION, CMDT_VEHICLE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_REFIT_VEHICLE, CmdRefitVehicle, CMD_LOCATION, CMDT_VEHICLE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_SEND_VEHICLE_TO_DEPOT, CmdSendVehicleToDepot, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CHANGE_SERVICE_INT, CmdChangeServiceInt, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_RENAME_VEHICLE, CmdRenameVehicle, 0, CMDT_OTHER_MANAGEMENT) +DEF_CMD_TRAIT(CMD_CLONE_VEHICLE, CmdCloneVehicle, CMD_NO_TEST, CMDT_VEHICLE_CONSTRUCTION) // NewGRF callbacks influence building and refitting making it impossible to correctly estimate the cost +DEF_CMD_TRAIT(CMD_START_STOP_VEHICLE, CmdStartStopVehicle, CMD_LOCATION, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_MASS_START_STOP, CmdMassStartStopVehicle, 0, CMDT_VEHICLE_MANAGEMENT) +DEF_CMD_TRAIT(CMD_DEPOT_SELL_ALL_VEHICLES, CmdDepotSellAllVehicles, 0, CMDT_VEHICLE_CONSTRUCTION) +DEF_CMD_TRAIT(CMD_DEPOT_MASS_AUTOREPLACE, CmdDepotMassAutoReplace, 0, CMDT_VEHICLE_CONSTRUCTION) + +void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, CargoArray); void CcStartStopVehicle(Commands cmd, const CommandCost &result, VehicleID veh_id, bool); template @@ -53,4 +54,21 @@ inline EndianBufferReader &operator >>(EndianBufferReader &buffer, VehicleListId return buffer >> vli.type >> vli.vtype >> vli.company >> vli.index; } +template +inline EndianBufferWriter &operator <<(EndianBufferWriter &buffer, const CargoArray &cargo_array) +{ + for (CargoID c = 0; c < NUM_CARGO; c++) { + buffer << cargo_array[c]; + } + return buffer; +} + +inline EndianBufferReader &operator >>(EndianBufferReader &buffer, CargoArray &cargo_array) +{ + for (CargoID c = 0; c < NUM_CARGO; c++) { + buffer >> cargo_array[c]; + } + return buffer; +} + #endif /* VEHICLE_CMD_H */ diff --git a/src/vehicle_func.h b/src/vehicle_func.h index aa3a027dfb04a..0efd4fd878bbf 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.h @@ -166,6 +166,7 @@ CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits); bool CanVehicleUseStation(EngineID engine_type, const struct Station *st); bool CanVehicleUseStation(const Vehicle *v, const struct Station *st); +StringID GetVehicleCannotUseStationReason(const Vehicle *v, const Station *st); void ReleaseDisastersTargetingVehicle(VehicleID vehicle); @@ -174,4 +175,7 @@ void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8 num_vehicles); void CheckCargoCapacity(Vehicle *v); +bool VehiclesHaveSameEngineList(const Vehicle *v1, const Vehicle *v2); +bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2); + #endif /* VEHICLE_FUNC_H */ diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index bcbb84e100128..70517d8cb4311 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -41,6 +41,7 @@ #include "order_cmd.h" #include "roadveh_cmd.h" #include "train_cmd.h" +#include "hotkeys.h" #include "safeguards.h" #include "date_func.h" @@ -143,6 +144,7 @@ const StringID BaseVehicleListWindow::vehicle_depot_name[] = { BaseVehicleListWindow::BaseVehicleListWindow(WindowDesc *desc, WindowNumber wno) : Window(desc), vli(VehicleListIdentifier::UnPack(wno)) { + this->vehicle_sel = INVALID_VEHICLE; this->grouping = _grouping[vli.type][vli.vtype]; this->UpdateSortingFromGrouping(); } @@ -199,6 +201,8 @@ void BaseVehicleListWindow::BuildVehicleList() max_unitnumber = std::max(max_unitnumber, (*it)->unitnumber); } this->unitnumber_digits = CountDigitsForAllocatingSpace(max_unitnumber); + + this->FilterVehicleList(); } else { /* Sort by the primary vehicle; we just want all vehicles that share the same orders to form a contiguous range. */ std::stable_sort(this->vehicles.begin(), this->vehicles.end(), [](const Vehicle * const &u, const Vehicle * const &v) { @@ -227,6 +231,118 @@ void BaseVehicleListWindow::BuildVehicleList() this->vscroll->SetCount(static_cast(this->vehgroups.size())); } + +/** Cargo filter functions */ +/** + * Check whether a vehicle can carry a specific cargo. + * @param vehgroup The vehicle group which contains the vehicle to be checked + * @param cid The cargo what we are looking for + * @return Whether the vehicle can carry the specified cargo or not + */ +static bool CDECL CargoFilter(const GUIVehicleGroup *vehgroup, const CargoID cid) +{ + const Vehicle *v = (*vehgroup).GetSingleVehicle(); + if (cid == BaseVehicleListWindow::CF_ANY) { + return true; + } else if (cid == BaseVehicleListWindow::CF_NONE) { + for (const Vehicle *w = v; w != nullptr; w = w->Next()) { + if (w->cargo_cap > 0) { + return false; + } + } + return true; + } else if (cid == BaseVehicleListWindow::CF_FREIGHT) { + bool have_capacity = false; + for (const Vehicle *w = v; w != nullptr; w = w->Next()) { + if (w->cargo_cap > 0) { + if (IsCargoInClass(w->cargo_type, CC_PASSENGERS)) { + return false; + } else { + have_capacity = true; + } + } + } + return have_capacity; + } else { + for (const Vehicle *w = v; w != nullptr; w = w->Next()) { + if (w->cargo_cap > 0 && w->cargo_type == cid) { + return true; + } + } + return false; + } +} + +static GUIVehicleGroupList::FilterFunction * const _filter_funcs[] = { + &CargoFilter, +}; + +/** + * Set cargo filter list item index. + * @param index The index to be set + */ +void BaseVehicleListWindow::SetCargoFilterIndex(byte index) +{ + if (this->cargo_filter_criteria != index) { + this->cargo_filter_criteria = index; + /* Deactivate filter if criteria is 'Show All', activate it otherwise. */ + this->vehgroups.SetFilterState(this->cargo_filter[this->cargo_filter_criteria] != CF_ANY); + this->vehgroups.SetFilterType(0); + this->vehgroups.ForceRebuild(); + } +} + +/** + *Populate the filter list and set the cargo filter criteria. + */ +void BaseVehicleListWindow::SetCargoFilterArray() +{ + byte filter_items = 0; + + /* Add item for disabling filtering. */ + this->cargo_filter[filter_items] = CF_ANY; + this->cargo_filter_texts[filter_items] = STR_CARGO_TYPE_FILTER_ALL; + this->cargo_filter_criteria = filter_items; + filter_items++; + + /* Add item for freight (i.e. vehicles with cargo capacity and with no passenger capacity). */ + this->cargo_filter[filter_items] = CF_FREIGHT; + this->cargo_filter_texts[filter_items] = STR_CARGO_TYPE_FILTER_FREIGHT; + filter_items++; + + /* Add item for vehicles not carrying anything, e.g. train engines. */ + this->cargo_filter[filter_items] = CF_NONE; + this->cargo_filter_texts[filter_items] = STR_CARGO_TYPE_FILTER_NONE; + filter_items++; + + /* Collect available cargo types for filtering. */ + for (const auto &cs : _sorted_cargo_specs) { + this->cargo_filter[filter_items] = cs->Index(); + this->cargo_filter_texts[filter_items] = cs->name; + filter_items++; + } + + /* Terminate the filter list. */ + this->cargo_filter_texts[filter_items] = INVALID_STRING_ID; + + this->vehgroups.SetFilterFuncs(_filter_funcs); + this->vehgroups.SetFilterState(this->cargo_filter[this->cargo_filter_criteria] != CF_ANY); +} + +/** + *Filter the engine list against the currently selected cargo filter. + */ +void BaseVehicleListWindow::FilterVehicleList() +{ + this->vehgroups.Filter(this->cargo_filter[this->cargo_filter_criteria]); + if (this->vehicles.size() == 0) { + /* No vehicle passed through the filter, invalidate the previously selected vehicle */ + this->vehicle_sel = INVALID_VEHICLE; + } else if (this->vehicle_sel != INVALID_VEHICLE && std::find(this->vehicles.begin(), this->vehicles.end(), Vehicle::Get(this->vehicle_sel)) == this->vehicles.end()) { // previously selected engine didn't pass the filter, remove selection + this->vehicle_sel = INVALID_VEHICLE; + } +} + /** * Compute the size for the Action dropdown. * @param show_autoreplace If true include the autoreplace item. @@ -252,6 +368,7 @@ Dimension BaseVehicleListWindow::GetActionDropdownSize(bool show_autoreplace, bo void BaseVehicleListWindow::OnInit() { this->order_arrow_width = GetStringBoundingBox(STR_TINY_RIGHT_ARROW).width; + this->SetCargoFilterArray(); } /** @@ -426,7 +543,7 @@ typedef std::vector SubtypeList; ///< List of refit subtypes associ */ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int sel[2], uint pos, uint rows, uint delta, const Rect &r) { - uint y = r.top + WD_MATRIX_TOP; + Rect ir = r.Shrink(WidgetDimensions::scaled.matrix); uint current = 0; bool rtl = _current_text_dir == TD_RTL; @@ -434,12 +551,11 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int uint iconheight = GetSpriteSize(SPR_CIRCLE_FOLDED).height; int linecolour = _colour_gradient[COLOUR_ORANGE][4]; - int iconleft = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth : r.left + WD_MATRIX_LEFT; - int iconcenter = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth / 2 : r.left + WD_MATRIX_LEFT + iconwidth / 2; - int iconinner = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth : r.left + WD_MATRIX_LEFT + iconwidth; + int iconleft = rtl ? ir.right - iconwidth : ir.left; + int iconcenter = rtl ? ir.right - iconwidth / 2 : ir.left + iconwidth / 2; + int iconinner = rtl ? ir.right - iconwidth : ir.left + iconwidth; - int textleft = r.left + WD_MATRIX_LEFT + (rtl ? 0 : iconwidth + 4); - int textright = r.right - WD_MATRIX_RIGHT - (rtl ? iconwidth + 4 : 0); + Rect tr = ir.Indent(iconwidth + WidgetDimensions::scaled.hsep_wide, rtl); /* Draw the list of subtypes for each cargo, and find the selected refit option (by its position). */ for (uint i = 0; current < pos + rows && i < NUM_CARGO; i++) { @@ -458,12 +574,12 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int if (list[i].size() > 1) { if (refit.subtype != 0xFF) { /* Draw tree lines */ - int ycenter = y + FONT_HEIGHT_NORMAL / 2; - GfxDrawLine(iconcenter, y - WD_MATRIX_TOP, iconcenter, j == list[i].size() - 1 ? ycenter : y - WD_MATRIX_TOP + delta - 1, linecolour); + int ycenter = tr.top + FONT_HEIGHT_NORMAL / 2; + GfxDrawLine(iconcenter, tr.top - WidgetDimensions::scaled.matrix.top, iconcenter, j == list[i].size() - 1 ? ycenter : tr.top - WidgetDimensions::scaled.matrix.top + delta - 1, linecolour); GfxDrawLine(iconcenter, ycenter, iconinner, ycenter, linecolour); } else { /* Draw expand/collapse icon */ - DrawSprite(sel[0] == (int)i ? SPR_CIRCLE_UNFOLDED : SPR_CIRCLE_FOLDED, PAL_NONE, iconleft, y + (FONT_HEIGHT_NORMAL - iconheight) / 2); + DrawSprite(sel[0] == (int)i ? SPR_CIRCLE_UNFOLDED : SPR_CIRCLE_FOLDED, PAL_NONE, iconleft, tr.top + (FONT_HEIGHT_NORMAL - iconheight) / 2); } } @@ -471,9 +587,9 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int /* Get the cargo name. */ SetDParam(0, CargoSpec::Get(refit.cargo)->name); SetDParam(1, refit.string); - DrawString(textleft, textright, y, STR_JUST_STRING_STRING, colour); + DrawString(tr, STR_JUST_STRING_STRING, colour); - y += delta; + tr.top += delta; current++; } } @@ -752,7 +868,7 @@ struct RefitWindow : public Window { { switch (widget) { case WID_VR_MATRIX: - resize->height = WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM; + resize->height = FONT_HEIGHT_NORMAL + padding.height; size->height = resize->height * 8; break; @@ -761,7 +877,7 @@ struct RefitWindow : public Window { break; case WID_VR_INFO: - size->width = WD_FRAMERECT_LEFT + this->information_width + WD_FRAMERECT_RIGHT; + size->width = this->information_width + padding.height; break; } } @@ -780,7 +896,7 @@ struct RefitWindow : public Window { StringID GetCapacityString(RefitOption *option) const { assert(_current_company == _local_company); - auto [cost, refit_capacity, mail_capacity] = Command::Do(DC_QUERY_COST, this->selected_vehicle, option->cargo, option->subtype, this->auto_refit, false, this->num_vehicles); + auto [cost, refit_capacity, mail_capacity, cargo_capacities] = Command::Do(DC_QUERY_COST, this->selected_vehicle, option->cargo, option->subtype, this->auto_refit, false, this->num_vehicles); if (cost.Failed()) return INVALID_STRING_ID; @@ -821,8 +937,8 @@ struct RefitWindow : public Window { switch (widget) { case WID_VR_VEHICLE_PANEL_DISPLAY: { Vehicle *v = Vehicle::Get(this->window_number); - DrawVehicleImage(v, this->sprite_left + WD_FRAMERECT_LEFT, this->sprite_right - WD_FRAMERECT_RIGHT, - r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, EIT_IN_DETAILS, this->hscroll != nullptr ? this->hscroll->GetPosition() : 0); + DrawVehicleImage(v, {this->sprite_left, r.top, this->sprite_right, r.bottom}, + INVALID_VEHICLE, EIT_IN_DETAILS, this->hscroll != nullptr ? this->hscroll->GetPosition() : 0); /* Highlight selected vehicles. */ if (this->order != INVALID_VEH_ORDER_ID) break; @@ -835,6 +951,11 @@ struct RefitWindow : public Window { int left = INT32_MIN; int width = 0; + /* Determine top & bottom position of the highlight.*/ + const int height = ScaleSpriteTrad(12); + const int highlight_top = CenterBounds(r.top, r.bottom, height); + const int highlight_bottom = highlight_top + height - 1; + for (Train *u = Train::From(v); u != nullptr; u = u->Next()) { /* Start checking. */ const bool contained = std::find(vehicles_to_refit.begin(), vehicles_to_refit.end(), u->index) != vehicles_to_refit.end(); @@ -855,12 +976,13 @@ struct RefitWindow : public Window { left = std::max(0, left); if (_current_text_dir == TD_RTL) { - right = this->GetWidget(WID_VR_VEHICLE_PANEL_DISPLAY)->current_x - left; + right = r.Width() - left; left = right - width; } if (left != right) { - DrawFrameRect(left, r.top + WD_FRAMERECT_TOP, right, r.top + WD_FRAMERECT_TOP + ScaleGUITrad(14) - 1, COLOUR_WHITE, FR_BORDERONLY); + Rect hr = {left, highlight_top, right, highlight_bottom}; + DrawFrameRect(hr.Expand(WidgetDimensions::scaled.bevel), COLOUR_WHITE, FR_BORDERONLY); } left = INT32_MIN; @@ -886,8 +1008,7 @@ struct RefitWindow : public Window { if (this->cargo != nullptr) { StringID string = this->GetCapacityString(this->cargo); if (string != INVALID_STRING_ID) { - DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, - r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, string); + DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect), string); } } break; @@ -1102,7 +1223,7 @@ static const NWidgetPart _nested_vehicle_refit_widgets[] = { NWidget(WWT_MATRIX, COLOUR_GREY, WID_VR_MATRIX), SetMinimalSize(228, 112), SetResize(1, 14), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_VR_SCROLLBAR), NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_VR_SCROLLBAR), EndContainer(), - NWidget(WWT_PANEL, COLOUR_GREY, WID_VR_INFO), SetMinimalTextLines(2, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM), SetResize(1, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_VR_INFO), SetMinimalTextLines(2, WidgetDimensions::unscaled.framerect.Vertical()), SetResize(1, 0), EndContainer(), NWidget(NWID_HORIZONTAL), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VR_REFIT), SetFill(1, 0), SetResize(1, 0), NWidget(WWT_RESIZEBOX, COLOUR_GREY), @@ -1387,15 +1508,23 @@ static const NWidgetPart _nested_vehicle_list[] = { EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_VL_GROUP_ORDER), SetMinimalSize(81, 12), SetFill(0, 1), SetDataTip(STR_STATION_VIEW_GROUP, STR_TOOLTIP_GROUP_ORDER), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_GROUP_BY_PULLDOWN), SetMinimalSize(167, 12), SetFill(0, 1), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER), - NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetFill(1, 1), SetResize(1, 0), EndContainer(), - EndContainer(), - - NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VL_SORT_ORDER), SetMinimalSize(81, 12), SetFill(0, 1), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_SORT_BY_PULLDOWN), SetMinimalSize(167, 12), SetFill(0, 1), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA), - NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetFill(1, 1), SetResize(1, 0), EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_VL_GROUP_ORDER), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_STATION_VIEW_GROUP, STR_TOOLTIP_GROUP_ORDER), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VL_SORT_ORDER), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), + EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_GROUP_BY_PULLDOWN), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_SORT_BY_PULLDOWN), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA), + EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 1), SetResize(1, 0), EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VL_FILTER_BY_CARGO_SEL), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_FILTER_BY_CARGO), SetMinimalSize(0, 12), SetFill(0, 0), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_FILTER_CRITERIA), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 1), SetResize(1, 0), EndContainer(), + EndContainer(), + EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -1476,19 +1605,17 @@ static void DrawSmallOrderList(const Order *order, int left, int right, int y, u /** * Draws an image of a vehicle chain * @param v Front vehicle - * @param left The minimum horizontal position - * @param right The maximum horizontal position - * @param y Vertical position to draw at + * @param r Rect to draw at * @param selection Selected vehicle to draw a frame around * @param skip Number of pixels to skip at the front (for scrolling) */ -void DrawVehicleImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip) +void DrawVehicleImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip) { switch (v->type) { - case VEH_TRAIN: DrawTrainImage(Train::From(v), left, right, y, selection, image_type, skip); break; - case VEH_ROAD: DrawRoadVehImage(v, left, right, y, selection, image_type, skip); break; - case VEH_SHIP: DrawShipImage(v, left, right, y, selection, image_type); break; - case VEH_AIRCRAFT: DrawAircraftImage(v, left, right, y, selection, image_type); break; + case VEH_TRAIN: DrawTrainImage(Train::From(v), r, selection, image_type, skip); break; + case VEH_ROAD: DrawRoadVehImage(v, r, selection, image_type, skip); break; + case VEH_SHIP: DrawShipImage(v, r, selection, image_type); break; + case VEH_AIRCRAFT: DrawAircraftImage(v, r, selection, image_type); break; default: NOT_REACHED(); } } @@ -1502,9 +1629,9 @@ void DrawVehicleImage(const Vehicle *v, int left, int right, int y, VehicleID se uint GetVehicleListHeight(VehicleType type, uint divisor) { /* Name + vehicle + profit */ - uint base = ScaleGUITrad(GetVehicleHeight(type)) + 2 * FONT_HEIGHT_SMALL; + uint base = ScaleGUITrad(GetVehicleHeight(type)) + 2 * FONT_HEIGHT_SMALL + WidgetDimensions::scaled.matrix.Vertical(); /* Drawing of the 4 small orders + profit*/ - if (type >= VEH_SHIP) base = std::max(base, 5U * FONT_HEIGHT_SMALL); + if (type >= VEH_SHIP) base = std::max(base, 5U * FONT_HEIGHT_SMALL + WidgetDimensions::scaled.matrix.Vertical()); if (divisor == 1) return base; @@ -1521,25 +1648,21 @@ uint GetVehicleListHeight(VehicleType type, uint divisor) */ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int line_height, const Rect &r) const { - int left = r.left + WD_MATRIX_LEFT; - int right = r.right - WD_MATRIX_RIGHT; - int width = right - left; + Rect ir = r.WithHeight(line_height).Shrink(WidgetDimensions::scaled.matrix, RectPadding::zero); bool rtl = _current_text_dir == TD_RTL; - int text_offset = std::max(GetSpriteSize(SPR_PROFIT_LOT).width, GetDigitWidth() * this->unitnumber_digits) + WD_FRAMERECT_RIGHT; - int text_left = left + (rtl ? 0 : text_offset); - int text_right = right - (rtl ? text_offset : 0); + Dimension profit = GetSpriteSize(SPR_PROFIT_LOT); + int text_offset = std::max(profit.width, GetDigitWidth() * this->unitnumber_digits) + WidgetDimensions::scaled.hsep_normal; + Rect tr = ir.Indent(text_offset, rtl); bool show_orderlist = this->vli.vtype >= VEH_SHIP; - int orderlist_left = left + (rtl ? 0 : std::max(ScaleGUITrad(100) + text_offset, width / 2)); - int orderlist_right = right - (rtl ? std::max(ScaleGUITrad(100) + text_offset, width / 2) : 0); + Rect olr = ir.Indent(std::max(ScaleGUITrad(100) + text_offset, ir.Width() / 2), rtl); - int image_left = (rtl && show_orderlist) ? orderlist_right : text_left; - int image_right = (!rtl && show_orderlist) ? orderlist_left : text_right; + int image_left = (rtl && show_orderlist) ? olr.right : tr.left; + int image_right = (!rtl && show_orderlist) ? olr.left : tr.right; - int vehicle_button_x = rtl ? right - GetSpriteSize(SPR_PROFIT_LOT).width : left; + int vehicle_button_x = rtl ? ir.right - profit.width : ir.left; - int y = r.top; uint max = static_cast(std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size())); for (uint i = this->vscroll->GetPosition(); i < max; ++i) { @@ -1547,31 +1670,60 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int SetDParam(0, vehgroup.GetDisplayProfitThisYear()); SetDParam(1, vehgroup.GetDisplayProfitLastYear()); - DrawString(text_left, text_right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1, STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR); + DrawString(tr.left, tr.right, ir.bottom - FONT_HEIGHT_SMALL - WidgetDimensions::scaled.framerect.bottom, STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR); - DrawVehicleProfitButton(vehgroup.GetOldestVehicleAge(), vehgroup.GetDisplayProfitLastYear(), vehgroup.NumVehicles(), vehicle_button_x, y + FONT_HEIGHT_NORMAL + 3); + DrawVehicleProfitButton(vehgroup.GetOldestVehicleAge(), vehgroup.GetDisplayProfitLastYear(), vehgroup.NumVehicles(), vehicle_button_x, ir.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal); switch (this->grouping) { case GB_NONE: { const Vehicle *v = vehgroup.GetSingleVehicle(); if (HasBit(v->vehicle_flags, VF_PATHFINDER_LOST)) { - DrawSprite(SPR_WARNING_SIGN, PAL_NONE, vehicle_button_x, y + FONT_HEIGHT_NORMAL + 3 + GetSpriteSize(SPR_PROFIT_LOT).height); + DrawSprite(SPR_WARNING_SIGN, PAL_NONE, vehicle_button_x, ir.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal + profit.height); } - DrawVehicleImage(v, image_left, image_right, y + FONT_HEIGHT_SMALL - 1, selected_vehicle, EIT_IN_LIST, 0); + DrawVehicleImage(v, {image_left, ir.top, image_right, ir.bottom}, selected_vehicle, EIT_IN_LIST, 0); + + if (_settings_client.gui.show_cargo_in_vehicle_lists) { + /* Get the cargoes the vehicle can carry */ + CargoTypes vehicle_cargoes = 0; + + for (auto u = v; u != nullptr; u = u->Next()) { + if (u->cargo_cap == 0) continue; - if (!v->name.empty()) { + SetBit(vehicle_cargoes, u->cargo_type); + } + + if (!v->name.empty()) { + /* The vehicle got a name so we will print it and the cargoes */ + SetDParam(0, STR_TINY_BLACK_VEHICLE); + SetDParam(1, v->index); + SetDParam(2, STR_VEHICLE_LIST_CARGO); + SetDParam(3, vehicle_cargoes); + DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_NAME_AND_CARGO); + } else if (v->group_id != DEFAULT_GROUP) { + /* The vehicle has no name, but is member of a group, so print group name and the cargoes */ + SetDParam(0, STR_TINY_GROUP); + SetDParam(1, v->group_id); + SetDParam(2, STR_VEHICLE_LIST_CARGO); + SetDParam(3, vehicle_cargoes); + DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_NAME_AND_CARGO); + } else { + /* The vehicle has no name, and is not a member of a group, so just print the cargoes */ + SetDParam(0, vehicle_cargoes); + DrawString(tr.left, tr.right, ir.top, STR_VEHICLE_LIST_CARGO); + } + } else if (!v->name.empty()) { /* The vehicle got a name so we will print it */ SetDParam(0, v->index); - DrawString(text_left, text_right, y, STR_TINY_BLACK_VEHICLE); + DrawString(tr.left, tr.right, ir.top, STR_TINY_BLACK_VEHICLE); } else if (v->group_id != DEFAULT_GROUP) { /* The vehicle has no name, but is member of a group, so print group name */ SetDParam(0, v->group_id); - DrawString(text_left, text_right, y, STR_TINY_GROUP, TC_BLACK); + DrawString(tr.left, tr.right, ir.top, STR_TINY_GROUP, TC_BLACK); } - if (show_orderlist) DrawSmallOrderList(v, orderlist_left, orderlist_right, y, this->order_arrow_width, v->cur_real_order_index); + if (show_orderlist) DrawSmallOrderList(v, olr.left, olr.right, ir.top, this->order_arrow_width, v->cur_real_order_index); StringID str; if (v->IsChainInDepot()) { @@ -1581,7 +1733,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int } SetDParam(0, v->unitnumber); - DrawString(left, right, y + 2, str); + DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, str); break; } @@ -1589,21 +1741,21 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int assert(vehgroup.NumVehicles() > 0); for (int i = 0; i < static_cast(vehgroup.NumVehicles()); ++i) { - if (image_left + 8 * i >= image_right) break; // Break if there is no more space to draw any more vehicles anyway. - DrawVehicleImage(vehgroup.vehicles_begin[i], image_left + 8 * i, image_right, y + FONT_HEIGHT_SMALL - 1, selected_vehicle, EIT_IN_LIST, 0); + if (image_left + WidgetDimensions::scaled.hsep_wide * i >= image_right) break; // Break if there is no more space to draw any more vehicles anyway. + DrawVehicleImage(vehgroup.vehicles_begin[i], {image_left + WidgetDimensions::scaled.hsep_wide * i, ir.top, image_right, ir.bottom}, selected_vehicle, EIT_IN_LIST, 0); } - if (show_orderlist) DrawSmallOrderList((vehgroup.vehicles_begin[0])->GetFirstOrder(), orderlist_left, orderlist_right, y, this->order_arrow_width); + if (show_orderlist) DrawSmallOrderList((vehgroup.vehicles_begin[0])->GetFirstOrder(), olr.left, olr.right, ir.top, this->order_arrow_width); SetDParam(0, vehgroup.NumVehicles()); - DrawString(left, right, y + 2, STR_BLACK_COMMA); + DrawString(ir.left, ir.right, ir.top + WidgetDimensions::scaled.framerect.top, STR_BLACK_COMMA); break; default: NOT_REACHED(); } - y += line_height; + ir = ir.Translate(0, line_height); } } @@ -1666,6 +1818,8 @@ struct VehicleListWindow : public BaseVehicleListWindow { { this->CreateNestedTree(); + this->GetWidget(WID_VL_FILTER_BY_CARGO_SEL)->SetDisplayedPlane((this->vli.type == VL_SHARED_ORDERS) ? SZSP_NONE : 0); + this->vscroll = this->GetScrollbar(WID_VL_SCROLLBAR); this->BuildVehicleList(); @@ -1723,6 +1877,20 @@ struct VehicleListWindow : public BaseVehicleListWindow { break; } + case WID_VL_GROUP_BY_PULLDOWN: + size->width = GetStringListWidth(this->vehicle_group_by_names) + padding.width; + break; + + case WID_VL_SORT_BY_PULLDOWN: + size->width = GetStringListWidth(this->vehicle_group_none_sorter_names); + size->width = std::max(size->width, GetStringListWidth(this->vehicle_group_shared_orders_sorter_names)); + size->width += padding.width; + break; + + case WID_VL_FILTER_BY_CARGO: + size->width = GetStringListWidth(this->cargo_filter_texts) + padding.width; + break; + case WID_VL_MANAGE_VEHICLES_DROPDOWN: { Dimension d = this->GetActionDropdownSize(this->vli.type == VL_STANDARD, false); d.height += padding.height; @@ -1740,6 +1908,10 @@ struct VehicleListWindow : public BaseVehicleListWindow { SetDParam(0, STR_VEHICLE_LIST_AVAILABLE_TRAINS + this->vli.vtype); break; + case WID_VL_FILTER_BY_CARGO: + SetDParam(0, this->cargo_filter_texts[this->cargo_filter_criteria]); + break; + case WID_VL_CAPTION: case WID_VL_CAPTION_SHARED_ORDERS: { switch (this->vli.type) { @@ -1823,6 +1995,8 @@ struct VehicleListWindow : public BaseVehicleListWindow { /* Set text of sort by dropdown widget. */ this->GetWidget(WID_VL_SORT_BY_PULLDOWN)->widget_data = this->GetVehicleSorterNames()[this->vehgroups.SortType()]; + this->GetWidget(WID_VL_FILTER_BY_CARGO)->widget_data = this->cargo_filter_texts[this->cargo_filter_criteria]; + this->DrawWidgets(); } @@ -1849,6 +2023,10 @@ struct VehicleListWindow : public BaseVehicleListWindow { (this->vli.vtype == VEH_TRAIN || this->vli.vtype == VEH_ROAD) ? 0 : (1 << 10)); return; + case WID_VL_FILTER_BY_CARGO: // Cargo filter dropdown + ShowDropDownMenu(this, this->cargo_filter_texts, this->cargo_filter_criteria, WID_VL_FILTER_BY_CARGO, 0, 0); + break; + case WID_VL_LIST: { // Matrix to show vehicles uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_VL_LIST); if (id_v >= this->vehgroups.size()) return; // click out of list bound @@ -1869,16 +2047,16 @@ struct VehicleListWindow : public BaseVehicleListWindow { case GB_SHARED_ORDERS: { assert(vehgroup.NumVehicles() > 0); - const Vehicle *v = vehgroup.vehicles_begin[0]; - /* We do not support VehicleClicked() here since the contextual action may only make sense for individual vehicles */ - - if (_ctrl_pressed) { - ShowOrdersWindow(v); - } else { - if (vehgroup.NumVehicles() == 1) { - ShowVehicleViewWindow(v); + if (!VehicleClicked(vehgroup)) { + const Vehicle *v = vehgroup.vehicles_begin[0]; + if (_ctrl_pressed) { + ShowOrdersWindow(v); } else { - ShowVehicleListWindow(v); + if (vehgroup.NumVehicles() == 1) { + ShowVehicleViewWindow(v); + } else { + ShowVehicleListWindow(v); + } } } break; @@ -1917,6 +2095,10 @@ struct VehicleListWindow : public BaseVehicleListWindow { this->vehgroups.SetSortType(index); break; + case WID_VL_FILTER_BY_CARGO: + this->SetCargoFilterIndex(index); + break; + case WID_VL_MANAGE_VEHICLES_DROPDOWN: assert(this->vehicles.size() != 0); @@ -2109,10 +2291,10 @@ static const NWidgetPart _nested_train_vehicle_details_widgets[] = { extern int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab); -extern void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab); -extern void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y); -extern void DrawShipDetails(const Vehicle *v, int left, int right, int y); -extern void DrawAircraftDetails(const Aircraft *v, int left, int right, int y); +extern void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab); +extern void DrawRoadVehDetails(const Vehicle *v, const Rect &r); +extern void DrawShipDetails(const Vehicle *v, const Rect &r); +extern void DrawAircraftDetails(const Aircraft *v, const Rect &r); static StandardTimeUnits GetServiceIntervalTimeUnit() { return GetStandardTimeUnitFor(5 * VANILLA_DAY_TICKS); @@ -2214,13 +2396,13 @@ struct VehicleDetailsWindow : Window { uint desired_height; if (v->HasArticulatedPart()) { /* An articulated RV has its text drawn under the sprite instead of after it, hence 15 pixels extra. */ - desired_height = WD_FRAMERECT_TOP + ScaleGUITrad(15) + 3 * FONT_HEIGHT_NORMAL + 2 + WD_FRAMERECT_BOTTOM; + desired_height = ScaleGUITrad(15) + 3 * FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal * 2; /* Add space for the cargo amount for each part. */ for (const Vehicle *u = v; u != nullptr; u = u->Next()) { - if (u->cargo_cap != 0) desired_height += FONT_HEIGHT_NORMAL + 1; + if (u->cargo_cap != 0) desired_height += FONT_HEIGHT_NORMAL; } } else { - desired_height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM; + desired_height = 4 * FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal * 2; } return desired_height; } @@ -2230,7 +2412,7 @@ struct VehicleDetailsWindow : Window { switch (widget) { case WID_VD_TOP_DETAILS: { Dimension dim = { 0, 0 }; - size->height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM; + size->height = 4 * FONT_HEIGHT_NORMAL + padding.height; for (uint i = 0; i < 4; i++) SetDParamMaxValue(i, INT16_MAX); static const StringID info_strings[] = { @@ -2245,7 +2427,7 @@ struct VehicleDetailsWindow : Window { } SetDParam(0, STR_VEHICLE_INFO_AGE); dim = maxdim(dim, GetStringBoundingBox(STR_VEHICLE_INFO_AGE_RUNNING_COST_YR)); - size->width = dim.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; + size->width = dim.width + padding.width; break; } @@ -2253,15 +2435,15 @@ struct VehicleDetailsWindow : Window { const Vehicle *v = Vehicle::Get(this->window_number); switch (v->type) { case VEH_ROAD: - size->height = this->GetRoadVehDetailsHeight(v); + size->height = this->GetRoadVehDetailsHeight(v) + padding.height; break; case VEH_SHIP: - size->height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM; + size->height = 4 * FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal * 2 + padding.height; break; case VEH_AIRCRAFT: - size->height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + 4 + WD_FRAMERECT_BOTTOM; + size->height = 5 * FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal * 2 + padding.height; break; default: @@ -2271,7 +2453,7 @@ struct VehicleDetailsWindow : Window { } case WID_VD_MATRIX: - resize->height = std::max(ScaleGUITrad(14), WD_MATRIX_TOP + FONT_HEIGHT_NORMAL + WD_MATRIX_BOTTOM); + resize->height = std::max(ScaleGUITrad(14), FONT_HEIGHT_NORMAL + padding.height); size->height = 4 * resize->height; break; @@ -2281,7 +2463,7 @@ struct VehicleDetailsWindow : Window { *size = maxdim(*size, GetStringBoundingBox(*strs++)); } size->width += padding.width; - size->height = FONT_HEIGHT_NORMAL + WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM; + size->height = FONT_HEIGHT_NORMAL + padding.height; break; } @@ -2293,8 +2475,8 @@ struct VehicleDetailsWindow : Window { size->width = std::max( GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT).width, GetStringBoundingBox(GetServicingIntervalTimeUnitsStringId()).width - ) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - size->height = WD_FRAMERECT_TOP + FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM; + ) + padding.width; + size->height = FONT_HEIGHT_NORMAL + padding.height; break; } } @@ -2316,20 +2498,18 @@ struct VehicleDetailsWindow : Window { * Draw the details for the given vehicle at the position of the Details windows * * @param v current vehicle - * @param left The left most coordinate to draw - * @param right The right most coordinate to draw - * @param y The y coordinate + * @param r the Rect to draw within * @param vscroll_pos Position of scrollbar (train only) * @param vscroll_cap Number of lines currently displayed (train only) * @param det_tab Selected details tab (train only) */ - static void DrawVehicleDetails(const Vehicle *v, int left, int right, int y, int vscroll_pos, uint vscroll_cap, TrainDetailsWindowTabs det_tab) + static void DrawVehicleDetails(const Vehicle *v, const Rect &r, int vscroll_pos, uint vscroll_cap, TrainDetailsWindowTabs det_tab) { switch (v->type) { - case VEH_TRAIN: DrawTrainDetails(Train::From(v), left, right, y, vscroll_pos, vscroll_cap, det_tab); break; - case VEH_ROAD: DrawRoadVehDetails(v, left, right, y); break; - case VEH_SHIP: DrawShipDetails(v, left, right, y); break; - case VEH_AIRCRAFT: DrawAircraftDetails(Aircraft::From(v), left, right, y); break; + case VEH_TRAIN: DrawTrainDetails(Train::From(v), r, vscroll_pos, vscroll_cap, det_tab); break; + case VEH_ROAD: DrawRoadVehDetails(v, r); break; + case VEH_SHIP: DrawShipDetails(v, r); break; + case VEH_AIRCRAFT: DrawAircraftDetails(Aircraft::From(v), r); break; default: NOT_REACHED(); } } @@ -2345,15 +2525,15 @@ struct VehicleDetailsWindow : Window { switch (widget) { case WID_VD_TOP_DETAILS: { - int y = r.top + WD_FRAMERECT_TOP; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); /* Draw running cost */ SetDParam(1, v->age / DAYS_IN_LEAP_YEAR); SetDParam(0, (v->age + DAYS_IN_YEAR < v->max_age) ? STR_VEHICLE_INFO_AGE : STR_VEHICLE_INFO_AGE_RED); SetDParam(2, v->max_age / DAYS_IN_LEAP_YEAR); SetDParam(3, v->GetDisplayRunningCost()); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_AGE_RUNNING_COST_YR); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, STR_VEHICLE_INFO_AGE_RUNNING_COST_YR); + tr.top += FONT_HEIGHT_NORMAL; /* Draw max speed */ StringID string; @@ -2384,58 +2564,63 @@ struct VehicleDetailsWindow : Window { string = STR_VEHICLE_INFO_MAX_SPEED; } } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, string); - y += FONT_HEIGHT_NORMAL; + DrawString(tr, string); + tr.top += FONT_HEIGHT_NORMAL; /* Draw profit */ SetDParam(0, v->GetDisplayProfitThisYear()); SetDParam(1, v->GetDisplayProfitLastYear()); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); - y += FONT_HEIGHT_NORMAL; + if (v->IsGroundVehicle()) { + SetDParam(2, v->GetDisplayMinPowerToWeight()); + DrawString(tr, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE); + } else { + DrawString(tr, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR); + } + tr.top += FONT_HEIGHT_NORMAL; /* Draw breakdown & reliability */ SetDParam(0, ToPercent16(v->reliability)); SetDParam(1, v->breakdowns_since_last_service); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS); + DrawString(tr, STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS); break; } - case WID_VD_MATRIX: + case WID_VD_MATRIX: { /* For trains only. */ - DrawVehicleDetails(v, r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, r.top + WD_MATRIX_TOP, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->tab); + DrawVehicleDetails(v, r.Shrink(WidgetDimensions::scaled.matrix, RectPadding::zero).WithHeight(this->resize.step_height), this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->tab); break; + } case WID_VD_MIDDLE_DETAILS: { /* For other vehicles, at the place of the matrix. */ bool rtl = _current_text_dir == TD_RTL; - uint sprite_width = GetSingleVehicleWidth(v, EIT_IN_DETAILS) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; - - uint text_left = r.left + (rtl ? 0 : sprite_width); - uint text_right = r.right - (rtl ? sprite_width : 0); + uint sprite_width = GetSingleVehicleWidth(v, EIT_IN_DETAILS) + WidgetDimensions::scaled.framerect.Horizontal(); + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); /* Articulated road vehicles use a complete line. */ if (v->type == VEH_ROAD && v->HasArticulatedPart()) { - DrawVehicleImage(v, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, EIT_IN_DETAILS, 0); + DrawVehicleImage(v, tr.WithHeight(ScaleGUITrad(GetVehicleHeight(v->type)), false), INVALID_VEHICLE, EIT_IN_DETAILS, 0); } else { - uint sprite_left = rtl ? text_right : r.left; - uint sprite_right = rtl ? r.right : text_left; - - DrawVehicleImage(v, sprite_left + WD_FRAMERECT_LEFT, sprite_right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, EIT_IN_DETAILS, 0); + Rect sr = tr.WithWidth(sprite_width, rtl); + DrawVehicleImage(v, sr.WithHeight(ScaleGUITrad(GetVehicleHeight(v->type)), false), INVALID_VEHICLE, EIT_IN_DETAILS, 0); } - DrawVehicleDetails(v, text_left + WD_FRAMERECT_LEFT, text_right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, 0, 0, this->tab); + + DrawVehicleDetails(v, tr.Indent(sprite_width, rtl), 0, 0, this->tab); break; } - case WID_VD_SERVICING_INTERVAL: + case WID_VD_SERVICING_INTERVAL: { /* Draw service interval text */ + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); SetDParam(0, GetServiceIntervalInTimeUnits(v)); SetDParam(1, v->date_of_last_service); if (GetServiceIntervalTimeUnit() != StandardTimeUnits::DAYS) SetDParam(2, v->fract_of_last_service); - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + (r.bottom - r.top + 1 - FONT_HEIGHT_NORMAL) / 2, + DrawString(tr.left, r.right - WidgetDimensions::scaled.framerect.right, r.top + (r.bottom - r.top + 1 - FONT_HEIGHT_NORMAL) / 2, v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : GetServicingIntervalTimeUnitsStringId()); break; + } } } @@ -2445,7 +2630,7 @@ struct VehicleDetailsWindow : Window { const Vehicle *v = Vehicle::Get(this->window_number); if (v->type == VEH_TRAIN) { - this->DisableWidget(this->tab + WID_VD_DETAILS_CARGO_CARRIED); + this->LowerWidget(this->tab + WID_VD_DETAILS_CARGO_CARRIED); this->vscroll->SetCount(GetTrainDetailsWndVScroll(v->index, this->tab)); } @@ -2494,7 +2679,7 @@ struct VehicleDetailsWindow : Window { case WID_VD_DETAILS_TRAIN_VEHICLES: case WID_VD_DETAILS_CAPACITY_OF_EACH: case WID_VD_DETAILS_TOTAL_CARGO: - this->SetWidgetsDisabledState(false, + this->SetWidgetsLoweredState(false, WID_VD_DETAILS_CARGO_CARRIED, WID_VD_DETAILS_TRAIN_VEHICLES, WID_VD_DETAILS_CAPACITY_OF_EACH, @@ -2595,32 +2780,12 @@ static const NWidgetPart _nested_vehicle_view_widgets[] = { EndContainer(), EndContainer(), NWidget(NWID_HORIZONTAL), - NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_VV_START_STOP), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetResize(1, 0), SetFill(1, 0), + NWidget(WWT_PUSHBTN, COLOUR_GREY, WID_VV_START_STOP), SetResize(1, 0), SetFill(1, 0), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_ORDER_LOCATION), SetMinimalSize(12, 14), SetDataTip(SPR_GOTO_LOCATION, STR_VEHICLE_VIEW_ORDER_LOCATION_TOOLTIP), NWidget(WWT_RESIZEBOX, COLOUR_GREY), EndContainer(), }; -/** Vehicle view window descriptor for all vehicles but trains. */ -static WindowDesc _vehicle_view_desc( - WDP_AUTO, "view_vehicle", 250, 116, - WC_VEHICLE_VIEW, WC_NONE, - 0, - _nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets) -); - -/** - * Vehicle view window descriptor for trains. Only minimum_height and - * default_height are different for train view. - */ -static WindowDesc _train_view_desc( - WDP_AUTO, "view_vehicle_train", 250, 134, - WC_VEHICLE_VIEW, WC_NONE, - 0, - _nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets) -); - - /* Just to make sure, nobody has changed the vehicle type constants, as we are using them for array indexing in a number of places here. */ static_assert(VEH_TRAIN == 0); @@ -2791,7 +2956,7 @@ struct VehicleViewWindow : Window { } this->FinishInitNested(window_number); this->owner = v->owner; - this->GetWidget(WID_VV_VIEWPORT)->InitializeViewport(this, this->window_number | (1 << 31), _vehicle_view_zoom_levels[v->type]); + this->GetWidget(WID_VV_VIEWPORT)->InitializeViewport(this, this->window_number | (1 << 31), ScaleZoomGUI(_vehicle_view_zoom_levels[v->type])); this->GetWidget(WID_VV_START_STOP)->tool_tip = STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP + v->type; this->GetWidget(WID_VV_RENAME)->tool_tip = STR_VEHICLE_DETAILS_TRAIN_RENAME + v->type; @@ -2819,7 +2984,7 @@ struct VehicleViewWindow : Window { const Vehicle *v = Vehicle::Get(this->window_number); switch (widget) { case WID_VV_START_STOP: - size->height = std::max({size->height, GetSpriteSize(SPR_WARNING_SIGN).height, GetSpriteSize(SPR_FLAG_VEH_STOPPED).height, GetSpriteSize(SPR_FLAG_VEH_RUNNING).height}) + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM; + size->height = std::max({size->height, (uint)FONT_HEIGHT_NORMAL, GetScaledSpriteSize(SPR_WARNING_SIGN).height, GetScaledSpriteSize(SPR_FLAG_VEH_STOPPED).height, GetScaledSpriteSize(SPR_FLAG_VEH_RUNNING).height}) + padding.height; break; case WID_VV_FORCE_PROCEED: @@ -2850,6 +3015,9 @@ struct VehicleViewWindow : Window { if (v->type == VEH_TRAIN) { this->SetWidgetLoweredState(WID_VV_FORCE_PROCEED, Train::From(v)->force_proceed == TFP_SIGNAL); this->SetWidgetDisabledState(WID_VV_FORCE_PROCEED, !is_localcompany); + } + + if (v->type == VEH_TRAIN || v->type == VEH_ROAD) { this->SetWidgetDisabledState(WID_VV_TURN_AROUND, !is_localcompany); } @@ -2916,7 +3084,7 @@ struct VehicleViewWindow : Window { SetDParam(0, v->type); SetDParam(1, v->current_order.GetDestination()); SetDParam(2, v->GetDisplaySpeed()); - if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) { + if (v->current_order.GetDestination() == INVALID_DEPOT) { /* This case *only* happens when multiple nearest depot orders * follow each other (including an order list only one order: a * nearest depot order) and there are no reachable depots. @@ -2963,17 +3131,13 @@ struct VehicleViewWindow : Window { /* Draw the flag plus orders. */ bool rtl = (_current_text_dir == TD_RTL); - uint text_offset = std::max({GetSpriteSize(SPR_WARNING_SIGN).width, GetSpriteSize(SPR_FLAG_VEH_STOPPED).width, GetSpriteSize(SPR_FLAG_VEH_RUNNING).width}) + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT; - int height = r.bottom - r.top; - int text_left = r.left + (rtl ? (uint)WD_FRAMERECT_LEFT : text_offset); - int text_right = r.right - (rtl ? text_offset : (uint)WD_FRAMERECT_RIGHT); - int text_top = r.top + WD_FRAMERECT_TOP + (height - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM - FONT_HEIGHT_NORMAL) / 2; - int image = ((v->vehstatus & VS_STOPPED) != 0) ? SPR_FLAG_VEH_STOPPED : (HasBit(v->vehicle_flags, VF_PATHFINDER_LOST)) ? SPR_WARNING_SIGN : SPR_FLAG_VEH_RUNNING; - int image_left = (rtl ? text_right + 1 : r.left) + WD_IMGBTN_LEFT; - int image_top = r.top + WD_IMGBTN_TOP + (height - WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM - GetSpriteSize(image).height) / 2; - int lowered = this->IsWidgetLowered(WID_VV_START_STOP) ? 1 : 0; - DrawSprite(image, PAL_NONE, image_left + lowered, image_top + lowered); - DrawString(text_left + lowered, text_right + lowered, text_top + lowered, str, text_colour, SA_HOR_CENTER); + uint icon_width = std::max({GetScaledSpriteSize(SPR_WARNING_SIGN).width, GetScaledSpriteSize(SPR_FLAG_VEH_STOPPED).width, GetScaledSpriteSize(SPR_FLAG_VEH_RUNNING).width}); + int lowered = this->IsWidgetLowered(widget) ? WidgetDimensions::scaled.pressed : 0; + Rect tr = r.Shrink(WidgetDimensions::scaled.framerect).Translate(lowered, lowered); + SpriteID image = ((v->vehstatus & VS_STOPPED) != 0) ? SPR_FLAG_VEH_STOPPED : (HasBit(v->vehicle_flags, VF_PATHFINDER_LOST)) ? SPR_WARNING_SIGN : SPR_FLAG_VEH_RUNNING; + DrawSpriteIgnorePadding(image, PAL_NONE, tr.WithWidth(icon_width, rtl), false, SA_CENTER); + tr = tr.Indent(icon_width + WidgetDimensions::scaled.imgbtn.Horizontal(), rtl); + DrawString(tr.left, tr.right, CenterBounds(tr.top, tr.bottom, FONT_HEIGHT_NORMAL), str, text_colour, SA_HOR_CENTER); } void OnClick(Point pt, int widget, int click_count) override @@ -3009,7 +3173,7 @@ struct VehicleViewWindow : Window { if (_ctrl_pressed) { ShowExtraViewportWindow(TileVirtXY(v->x_pos, v->y_pos)); } else { - const Window *mainwindow = FindWindowById(WC_MAIN_WINDOW, 0); + const Window *mainwindow = GetMainWindow(); if (click_count > 1 && mainwindow->viewport->zoom <= ZOOM_LVL_OUT_4X) { /* main window 'follows' vehicle */ mainwindow->viewport->follow_vehicle = v->index; @@ -3063,6 +3227,20 @@ struct VehicleViewWindow : Window { } } + EventState OnHotkey(int hotkey) override + { + /* If the hotkey is not for any widget in the UI (i.e. for honking) */ + if (hotkey == WID_VV_HONK_HORN) { + const Window *mainwindow = GetMainWindow(); + const Vehicle *v = Vehicle::Get(window_number); + /* Only play the sound if we're following this vehicle */ + if (mainwindow->viewport->follow_vehicle == v->index) { + v->PlayLeaveStationSound(true); + } + } + return Window::OnHotkey(hotkey); + } + void OnQueryTextFinished(char *str) override { if (str == nullptr) return; @@ -3103,8 +3281,8 @@ struct VehicleViewWindow : Window { } /* The same system applies to widget WID_VV_REFIT_VEH and VVW_WIDGET_TURN_AROUND.*/ if (v->IsGroundVehicle()) { - PlaneSelections plane = veh_stopped ? SEL_RT_REFIT : SEL_RT_TURN_AROUND; - NWidgetStacked *nwi = this->GetWidget(WID_VV_SELECT_REFIT_TURN); + plane = veh_stopped ? SEL_RT_REFIT : SEL_RT_TURN_AROUND; + nwi = this->GetWidget(WID_VV_SELECT_REFIT_TURN); if (nwi->shown_plane + SEL_RT_BASEPLANE != plane) { this->SelectPlane(plane); this->SetWidgetDirty(WID_VV_SELECT_REFIT_TURN); @@ -3137,8 +3315,36 @@ struct VehicleViewWindow : Window { { ::ShowNewGRFInspectWindow(GetGrfSpecFeature(Vehicle::Get(this->window_number)->type), this->window_number); } + + static HotkeyList hotkeys; }; +static Hotkey vehicleview_hotkeys[] = { + Hotkey('H', "honk", WID_VV_HONK_HORN), + HOTKEY_LIST_END +}; +HotkeyList VehicleViewWindow::hotkeys("vehicleview", vehicleview_hotkeys); + +/** Vehicle view window descriptor for all vehicles but trains. */ +static WindowDesc _vehicle_view_desc( + WDP_AUTO, "view_vehicle", 250, 116, + WC_VEHICLE_VIEW, WC_NONE, + 0, + _nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets), + &VehicleViewWindow::hotkeys +); + +/** + * Vehicle view window descriptor for trains. Only minimum_height and + * default_height are different for train view. + */ +static WindowDesc _train_view_desc( + WDP_AUTO, "view_vehicle_train", 250, 134, + WC_VEHICLE_VIEW, WC_NONE, + 0, + _nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets), + &VehicleViewWindow::hotkeys +); /** Shows the vehicle view window of the given vehicle. */ void ShowVehicleViewWindow(const Vehicle *v) @@ -3162,10 +3368,37 @@ bool VehicleClicked(const Vehicle *v) return _thd.GetCallbackWnd()->OnVehicleSelect(v); } +/** + * Dispatch a "vehicle group selected" event if any window waits for it. + * @param begin iterator to the start of the range of vehicles + * @param end iterator to the end of the range of vehicles + * @return did any window accept vehicle group selection? + */ +bool VehicleClicked(VehicleList::const_iterator begin, VehicleList::const_iterator end) +{ + assert(begin != end); + if (!(_thd.place_mode & HT_VEHICLE)) return false; + + /* If there is only one vehicle in the group, act as if we clicked a single vehicle */ + if (begin + 1 == end) return _thd.GetCallbackWnd()->OnVehicleSelect(*begin); + + return _thd.GetCallbackWnd()->OnVehicleSelect(begin, end); +} + +/** + * Dispatch a "vehicle group selected" event if any window waits for it. + * @param vehgroup the GUIVehicleGroup representing the vehicle group + * @return did any window accept vehicle group selection? + */ +bool VehicleClicked(const GUIVehicleGroup &vehgroup) +{ + return VehicleClicked(vehgroup.vehicles_begin, vehgroup.vehicles_end); +} + void StopGlobalFollowVehicle(const Vehicle *v) { - Window *w = FindWindowById(WC_MAIN_WINDOW, 0); - if (w != nullptr && w->viewport->follow_vehicle == v->index) { + Window *w = GetMainWindow(); + if (w->viewport->follow_vehicle == v->index) { ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos, true); // lock the main view on the vehicle's last position w->viewport->follow_vehicle = INVALID_VEHICLE; } @@ -3178,7 +3411,7 @@ void StopGlobalFollowVehicle(const Vehicle *v) * @param result indicates completion (or not) of the operation * @param new_veh_id ID of the new vehicle. */ -void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16) +void CcBuildPrimaryVehicle(Commands cmd, const CommandCost &result, VehicleID new_veh_id, uint, uint16, CargoArray) { if (result.Failed()) return; @@ -3206,7 +3439,7 @@ int GetSingleVehicleWidth(const Vehicle *v, EngineImageType image_type) v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq); Rect rec; seq.GetBounds(&rec); - return UnScaleGUI(rec.right - rec.left + 1); + return UnScaleGUI(rec.Width()); } } @@ -3244,7 +3477,7 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type) bool is_ground_vehicle = v->IsGroundVehicle(); while (v != nullptr) { - if (total_width >= ScaleGUITrad(2 * (int)VEHICLEINFO_FULL_VEHICLE_WIDTH)) break; + if (total_width >= ScaleSpriteTrad(2 * (int)VEHICLEINFO_FULL_VEHICLE_WIDTH)) break; PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); VehicleSpriteSeq seq; @@ -3252,18 +3485,21 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type) if (rotor_seq) { GetCustomRotorSprite(Aircraft::From(v), image_type, &seq); if (!seq.IsValid()) seq.Set(SPR_ROTOR_STOPPED); - y_offset = - ScaleGUITrad(5); + y_offset = -ScaleSpriteTrad(5); } else { v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq); } if (_cursor.sprite_count + seq.count > lengthof(_cursor.sprite_seq)) break; + int x_offs = 0; + if (v->type == VEH_TRAIN) x_offs = Train::From(v)->GetCursorImageOffset(); + for (uint i = 0; i < seq.count; ++i) { PaletteID pal2 = (v->vehstatus & VS_CRASHED) || !seq.seq[i].pal ? pal : seq.seq[i].pal; _cursor.sprite_seq[_cursor.sprite_count].sprite = seq.seq[i].sprite; _cursor.sprite_seq[_cursor.sprite_count].pal = pal2; - _cursor.sprite_pos[_cursor.sprite_count].x = rtl ? -total_width : total_width; + _cursor.sprite_pos[_cursor.sprite_count].x = rtl ? (-total_width + x_offs) : (total_width + x_offs); _cursor.sprite_pos[_cursor.sprite_count].y = y_offset; _cursor.sprite_count++; } @@ -3279,7 +3515,7 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type) if (is_ground_vehicle) { /* Center trains and road vehicles on the front vehicle */ - int offs = (ScaleGUITrad(VEHICLEINFO_FULL_VEHICLE_WIDTH) - total_width) / 2; + int offs = (ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH) - total_width) / 2; if (rtl) offs = -offs; for (uint i = 0; i < _cursor.sprite_count; ++i) { _cursor.sprite_pos[i].x += offs; diff --git a/src/vehicle_gui.h b/src/vehicle_gui.h index f4c044393a32d..3a4786fca640e 100644 --- a/src/vehicle_gui.h +++ b/src/vehicle_gui.h @@ -12,6 +12,8 @@ #include "window_type.h" #include "vehicle_type.h" +#include "vehicle_gui_base.h" +#include "vehiclelist.h" #include "order_type.h" #include "station_type.h" #include "engine_type.h" @@ -41,14 +43,17 @@ struct TestedEngineDetails { CargoID cargo; ///< Cargo type uint capacity; ///< Cargo capacity uint16 mail_capacity; ///< Mail capacity if available + CargoArray all_capacities; ///< Capacities for all cargoes + + void FillDefaultCapacities(const Engine *e); }; int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, TestedEngineDetails &te); -void DrawTrainImage(const Train *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip, VehicleID drag_dest = INVALID_VEHICLE); -void DrawRoadVehImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip = 0); -void DrawShipImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type); -void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type); +void DrawTrainImage(const Train *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip, VehicleID drag_dest = INVALID_VEHICLE); +void DrawRoadVehImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip = 0); +void DrawShipImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type); +void DrawAircraftImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type); void ShowBuildVehicleWindow(TileIndex tile, VehicleType type); @@ -102,11 +107,14 @@ static inline WindowClass GetWindowClassForVehicleType(VehicleType vt) /* Unified window procedure */ void ShowVehicleViewWindow(const Vehicle *v); bool VehicleClicked(const Vehicle *v); +bool VehicleClicked(VehicleList::const_iterator begin, VehicleList::const_iterator end); +bool VehicleClicked(const GUIVehicleGroup &vehgroup); void StartStopVehicle(const Vehicle *v, bool texteffect); Vehicle *CheckClickOnVehicle(const struct Viewport *vp, int x, int y); +void StopGlobalFollowVehicle(const Vehicle *v); -void DrawVehicleImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip); +void DrawVehicleImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip); void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type); #endif /* VEHICLE_GUI_H */ diff --git a/src/vehicle_gui_base.h b/src/vehicle_gui_base.h index d724bc3433566..73f2159d396f2 100644 --- a/src/vehicle_gui_base.h +++ b/src/vehicle_gui_base.h @@ -11,6 +11,7 @@ #define VEHICLE_GUI_BASE_H #include "core/smallvec_type.hpp" +#include "cargo_type.h" #include "date_type.h" #include "economy_type.h" #include "sortlist_type.h" @@ -22,7 +23,7 @@ #include #include -typedef GUIList GUIVehicleList; +typedef GUIList GUIVehicleList; struct GUIVehicleGroup { VehicleList::const_iterator vehicles_begin; ///< Pointer to beginning element of this vehicle group. @@ -65,7 +66,7 @@ struct GUIVehicleGroup { } }; -typedef GUIList GUIVehicleGroupList; +typedef GUIList GUIVehicleGroupList; struct BaseVehicleListWindow : public Window { @@ -76,14 +77,25 @@ struct BaseVehicleListWindow : public Window { GB_END, }; - GroupBy grouping; ///< How we want to group the list. - VehicleList vehicles; ///< List of vehicles. This is the buffer for `vehgroups` to point into; if this is structurally modified, `vehgroups` must be rebuilt. - GUIVehicleGroupList vehgroups; ///< List of (groups of) vehicles. This stores iterators of `vehicles`, and should be rebuilt if `vehicles` is structurally changed. - Listing *sorting; ///< Pointer to the vehicle type related sorting. - byte unitnumber_digits; ///< The number of digits of the highest unit number. + /** Special cargo filter criteria */ + enum CargoFilterSpecialType { + CF_NONE = CT_INVALID, ///< Show only vehicles which do not carry cargo (e.g. train engines) + CF_ANY = CT_NO_REFIT, ///< Show all vehicles independent of carried cargo (i.e. no filtering) + CF_FREIGHT = CT_AUTO_REFIT, ///< Show only vehicles which carry any freight (non-passenger) cargo + }; + + GroupBy grouping; ///< How we want to group the list. + VehicleList vehicles; ///< List of vehicles. This is the buffer for `vehgroups` to point into; if this is structurally modified, `vehgroups` must be rebuilt. + GUIVehicleGroupList vehgroups; ///< List of (groups of) vehicles. This stores iterators of `vehicles`, and should be rebuilt if `vehicles` is structurally changed. + Listing *sorting; ///< Pointer to the vehicle type related sorting. + byte unitnumber_digits; ///< The number of digits of the highest unit number. Scrollbar *vscroll; - VehicleListIdentifier vli; ///< Identifier of the vehicle list we want to currently show. - uint order_arrow_width; ///< Width of the arrow in the small order list. + VehicleListIdentifier vli; ///< Identifier of the vehicle list we want to currently show. + VehicleID vehicle_sel; ///< Selected vehicle + CargoID cargo_filter[NUM_CARGO + 3]; ///< Available cargo filters; CargoID or CF_ANY or CF_FREIGHT or CF_NONE + StringID cargo_filter_texts[NUM_CARGO + 4]; ///< Texts for filter_cargo, terminated by INVALID_STRING_ID + byte cargo_filter_criteria; ///< Selected cargo filter index + uint order_arrow_width; ///< Width of the arrow in the small order list. typedef GUIVehicleGroupList::SortFunction VehicleGroupSortFunction; typedef GUIVehicleList::SortFunction VehicleIndividualSortFunction; @@ -113,6 +125,9 @@ struct BaseVehicleListWindow : public Window { void UpdateVehicleGroupBy(GroupBy group_by); void SortVehicleList(); void BuildVehicleList(); + void SetCargoFilterIndex(byte index); + void SetCargoFilterArray(); + void FilterVehicleList(); Dimension GetActionDropdownSize(bool show_autoreplace, bool show_group); DropDownList BuildActionDropdownList(bool show_autoreplace, bool show_group); diff --git a/src/video/allegro_v.cpp b/src/video/allegro_v.cpp index 3a0a4beb01bf2..84c55492fbd13 100644 --- a/src/video/allegro_v.cpp +++ b/src/video/allegro_v.cpp @@ -204,7 +204,7 @@ static bool CreateMainSurface(uint w, uint h) _screen.dst_ptr = _allegro_screen->line[0]; /* Initialise the screen so we don't blit garbage to the screen */ - memset(_screen.dst_ptr, 0, _screen.height * _screen.pitch); + memset(_screen.dst_ptr, 0, static_cast(_screen.height) * _screen.pitch); /* Set the mouse at the place where we expect it */ poll_mouse(); @@ -467,13 +467,9 @@ void VideoDriver_Allegro::InputLoop() _ctrl_pressed = !!(key_shifts & KB_CTRL_FLAG); _shift_pressed = !!(key_shifts & KB_SHIFT_FLAG); -#if defined(_DEBUG) - this->fast_forward_key_pressed = _shift_pressed; -#else /* Speedup when pressing tab, except when using ALT+TAB * to switch to another application. */ this->fast_forward_key_pressed = key[KEY_TAB] && (key_shifts & KB_ALT_FLAG) == 0; -#endif /* Determine which directional keys are down. */ _dirkeys = diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm index 0636f2cc0fe48..ca8df1831159a 100644 --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -484,11 +484,7 @@ _ctrl_pressed = (cur_mods & ( _settings_client.gui.right_mouse_btn_emulation != RMBE_CONTROL ? NSEventModifierFlagControl : NSEventModifierFlagCommand)) != 0; _shift_pressed = (cur_mods & NSEventModifierFlagShift) != 0; -#if defined(_DEBUG) - this->fast_forward_key_pressed = _shift_pressed; -#else this->fast_forward_key_pressed = _tab_is_down; -#endif if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged(); } diff --git a/src/video/cocoa/cocoa_wnd.mm b/src/video/cocoa/cocoa_wnd.mm index 1876ee27f0064..d4fc5b292e41b 100644 --- a/src/video/cocoa/cocoa_wnd.mm +++ b/src/video/cocoa/cocoa_wnd.mm @@ -1269,11 +1269,15 @@ - (void)windowDidEnterFullScreen:(NSNotification *)aNotification /** Screen the window is on changed. */ - (void)windowDidChangeBackingProperties:(NSNotification *)notification { + bool did_adjust = AdjustGUIZoom(true); + /* Reallocate screen buffer if necessary. */ driver->AllocateBackingStore(); + + if (did_adjust) ReInitAllWindows(true); } -/** Presentation options to use for fullsreen mode. */ +/** Presentation options to use for full screen mode. */ - (NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions { return NSApplicationPresentationFullScreen | NSApplicationPresentationHideMenuBar | NSApplicationPresentationHideDock; diff --git a/src/video/dedicated_v.cpp b/src/video/dedicated_v.cpp index 75f173544ec4f..99dc5ee691d24 100644 --- a/src/video/dedicated_v.cpp +++ b/src/video/dedicated_v.cpp @@ -139,7 +139,7 @@ const char *VideoDriver_Dedicated::Start(const StringList &parm) this->UpdateAutoResolution(); int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth(); - _dedicated_video_mem = (bpp == 0) ? nullptr : MallocT(_cur_resolution.width * _cur_resolution.height * (bpp / 8)); + _dedicated_video_mem = (bpp == 0) ? nullptr : MallocT(static_cast(_cur_resolution.width) * _cur_resolution.height * (bpp / 8)); _screen.width = _screen.pitch = _cur_resolution.width; _screen.height = _cur_resolution.height; @@ -251,17 +251,6 @@ void VideoDriver_Dedicated::MainLoop() /* If SwitchMode is SM_LOAD_GAME, it means that the user used the '-g' options */ if (_switch_mode != SM_LOAD_GAME) { StartNewGameWithoutGUI(GENERATE_NEW_SEED); - } else { - /* First we need to test if the savegame can be loaded, else we will end up playing the - * intro game... */ - if (SaveOrLoad(_file_to_saveload.name, _file_to_saveload.file_op, _file_to_saveload.detail_ftype, BASE_DIR) == SL_ERROR) { - /* Loading failed, pop out.. */ - Debug(net, 0, "Loading requested map failed; closing server."); - return; - } else { - /* We can load this game, so go ahead */ - _switch_mode = SM_LOAD_GAME; - } } this->is_game_threaded = false; diff --git a/src/video/opengl.cpp b/src/video/opengl.cpp index 01ef24c555f27..ae46fe78f02ce 100644 --- a/src/video/opengl.cpp +++ b/src/video/opengl.cpp @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * 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. @@ -920,6 +918,7 @@ bool OpenGLBackend::Resize(int w, int h, bool force) int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth(); int pitch = Align(w, 4); + size_t line_pixel_count = static_cast(pitch) * h; _glViewport(0, 0, w, h); @@ -930,27 +929,27 @@ bool OpenGLBackend::Resize(int w, int h, bool force) _glDeleteBuffers(1, &this->vid_pbo); _glGenBuffers(1, &this->vid_pbo); _glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo); - _glBufferStorage(GL_PIXEL_UNPACK_BUFFER, pitch * h * bpp / 8, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT); + _glBufferStorage(GL_PIXEL_UNPACK_BUFFER, line_pixel_count * bpp / 8, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT); } else { /* Re-allocate video buffer texture and backing store. */ _glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vid_pbo); - _glBufferData(GL_PIXEL_UNPACK_BUFFER, pitch * h * bpp / 8, nullptr, GL_DYNAMIC_DRAW); + _glBufferData(GL_PIXEL_UNPACK_BUFFER, line_pixel_count * bpp / 8, nullptr, GL_DYNAMIC_DRAW); } if (bpp == 32) { /* Initialize backing store alpha to opaque for 32bpp modes. */ Colour black(0, 0, 0); if (_glClearBufferSubData != nullptr) { - _glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_RGBA8, 0, pitch * h * bpp / 8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &black.data); + _glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_RGBA8, 0, line_pixel_count * bpp / 8, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &black.data); } else { - ClearPixelBuffer(pitch * h, black.data); + ClearPixelBuffer(line_pixel_count, black.data); } } else if (bpp == 8) { if (_glClearBufferSubData != nullptr) { byte b = 0; - _glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, pitch * h, GL_RED, GL_UNSIGNED_BYTE, &b); + _glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, line_pixel_count, GL_RED, GL_UNSIGNED_BYTE, &b); } else { - ClearPixelBuffer(pitch * h, 0); + ClearPixelBuffer(line_pixel_count, 0); } } @@ -974,18 +973,18 @@ bool OpenGLBackend::Resize(int w, int h, bool force) _glDeleteBuffers(1, &this->anim_pbo); _glGenBuffers(1, &this->anim_pbo); _glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo); - _glBufferStorage(GL_PIXEL_UNPACK_BUFFER, pitch * h, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT); + _glBufferStorage(GL_PIXEL_UNPACK_BUFFER, line_pixel_count, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_CLIENT_STORAGE_BIT); } else { _glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo); - _glBufferData(GL_PIXEL_UNPACK_BUFFER, pitch * h, nullptr, GL_DYNAMIC_DRAW); + _glBufferData(GL_PIXEL_UNPACK_BUFFER, line_pixel_count, nullptr, GL_DYNAMIC_DRAW); } /* Initialize buffer as 0 == no remap. */ if (_glClearBufferSubData != nullptr) { byte b = 0; - _glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, pitch * h, GL_RED, GL_UNSIGNED_BYTE, &b); + _glClearBufferSubData(GL_PIXEL_UNPACK_BUFFER, GL_R8, 0, line_pixel_count, GL_RED, GL_UNSIGNED_BYTE, &b); } else { - ClearPixelBuffer(pitch * h, 0); + ClearPixelBuffer(line_pixel_count, 0); } _glBindTexture(GL_TEXTURE_2D, this->anim_texture); @@ -1121,8 +1120,8 @@ void OpenGLBackend::PopulateCursorCache() if (!this->cursor_cache.Contains(sprite)) { Sprite *old = this->cursor_cache.Insert(sprite, (Sprite *)GetRawSprite(sprite, ST_NORMAL, &SimpleSpriteAlloc, this)); if (old != nullptr) { - OpenGLSprite *sprite = (OpenGLSprite *)old->data; - sprite->~OpenGLSprite(); + OpenGLSprite *gl_sprite = (OpenGLSprite *)old->data; + gl_sprite->~OpenGLSprite(); free(old); } } @@ -1193,7 +1192,7 @@ uint8 *OpenGLBackend::GetAnimBuffer() this->anim_buffer = _glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE); } else if (this->anim_buffer == nullptr) { _glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->anim_pbo); - this->anim_buffer = _glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, _screen.pitch * _screen.height, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + this->anim_buffer = _glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, static_cast(_screen.pitch) * _screen.height, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); } return (uint8 *)this->anim_buffer; @@ -1493,8 +1492,9 @@ void OpenGLSprite::Update(uint width, uint height, uint level, const SpriteLoade if (this->tex[TEX_RGBA] != 0) { /* Unpack pixel data */ - Colour *rgba = buf_rgba.Allocate(width * height); - for (size_t i = 0; i < width * height; i++) { + size_t size = static_cast(width) * height; + Colour *rgba = buf_rgba.Allocate(size); + for (size_t i = 0; i < size; i++) { rgba[i].r = data[i].r; rgba[i].g = data[i].g; rgba[i].b = data[i].b; @@ -1507,7 +1507,7 @@ void OpenGLSprite::Update(uint width, uint height, uint level, const SpriteLoade if (this->tex[TEX_REMAP] != 0) { /* Unpack and align pixel data. */ - int pitch = Align(width, 4); + size_t pitch = Align(width, 4); uint8 *pal = buf_pal.Allocate(pitch * height); const SpriteLoader::CommonPixel *row = data; diff --git a/src/video/opengl.h b/src/video/opengl.h index b1d9080ba7845..0cdb89035a20d 100644 --- a/src/video/opengl.h +++ b/src/video/opengl.h @@ -1,5 +1,3 @@ -/* $Id$ */ - /* * 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. @@ -50,16 +48,16 @@ class OpenGLBackend : public ZeroedMemoryAllocator, SpriteEncoder { GLuint remap_program; ///< Shader program for blending and rendering a RGBA + remap texture. GLint remap_sprite_loc; ///< Uniform location for sprite parameters. - GLint remap_screen_loc; ///< Uniform location for screen size; - GLint remap_zoom_loc; ///< Uniform location for sprite zoom; - GLint remap_rgb_loc; ///< Uniform location for RGB mode flag; + GLint remap_screen_loc; ///< Uniform location for screen size. + GLint remap_zoom_loc; ///< Uniform location for sprite zoom. + GLint remap_rgb_loc; ///< Uniform location for RGB mode flag. GLuint sprite_program; ///< Shader program for blending and rendering a sprite to the video buffer. GLint sprite_sprite_loc; ///< Uniform location for sprite parameters. - GLint sprite_screen_loc; ///< Uniform location for screen size; - GLint sprite_zoom_loc; ///< Uniform location for sprite zoom; - GLint sprite_rgb_loc; ///< Uniform location for RGB mode flag; - GLint sprite_crash_loc; ///< Uniform location for crash remap mode flag; + GLint sprite_screen_loc; ///< Uniform location for screen size. + GLint sprite_zoom_loc; ///< Uniform location for sprite zoom. + GLint sprite_rgb_loc; ///< Uniform location for RGB mode flag. + GLint sprite_crash_loc; ///< Uniform location for crash remap mode flag. LRUCache cursor_cache; ///< Cache of encoded cursor sprites. PaletteID last_sprite_pal = (PaletteID)-1; ///< Last uploaded remap palette. diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp index 5f6950a8e19f8..6f6cb51561721 100644 --- a/src/video/sdl2_v.cpp +++ b/src/video/sdl2_v.cpp @@ -577,13 +577,9 @@ void VideoDriver_SDL_Base::InputLoop() _ctrl_pressed = !!(mod & KMOD_CTRL); _shift_pressed = !!(mod & KMOD_SHIFT); -#if defined(_DEBUG) - this->fast_forward_key_pressed = _shift_pressed; -#else /* Speedup when pressing tab, except when using ALT+TAB * to switch to another application. */ this->fast_forward_key_pressed = keys[SDL_SCANCODE_TAB] && (mod & KMOD_ALT) == 0; -#endif /* defined(_DEBUG) */ /* Determine which directional keys are down. */ _dirkeys = @@ -648,12 +644,11 @@ bool VideoDriver_SDL_Base::ChangeResolution(int w, int h) bool VideoDriver_SDL_Base::ToggleFullscreen(bool fullscreen) { + /* Remember current window size */ int w, h; + SDL_GetWindowSize(this->sdl_window, &w, &h); - /* Remember current window size */ if (fullscreen) { - SDL_GetWindowSize(this->sdl_window, &w, &h); - /* Find fullscreen window size */ SDL_DisplayMode dm; if (SDL_GetCurrentDisplayMode(0, &dm) < 0) { diff --git a/src/video/sdl2_v.h b/src/video/sdl2_v.h index a2298c44e9696..9b70eafd9c0c0 100644 --- a/src/video/sdl2_v.h +++ b/src/video/sdl2_v.h @@ -17,7 +17,7 @@ /** The SDL video driver. */ class VideoDriver_SDL_Base : public VideoDriver { public: - VideoDriver_SDL_Base() : sdl_window(nullptr), buffer_locked(false), driver_info(this->GetName()) {} + VideoDriver_SDL_Base() : sdl_window(nullptr), buffer_locked(false) {} const char *Start(const StringList ¶m) override; @@ -41,8 +41,6 @@ class VideoDriver_SDL_Base : public VideoDriver { std::vector GetListOfMonitorRefreshRates() override; - const char *GetName() const override { return "sdl"; } - const char *GetInfoString() const override { return this->driver_info.c_str(); } protected: diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp index 1b180d3b8babc..667b7381458cd 100644 --- a/src/video/sdl_v.cpp +++ b/src/video/sdl_v.cpp @@ -624,13 +624,9 @@ void VideoDriver_SDL::InputLoop() _ctrl_pressed = !!(mod & KMOD_CTRL); _shift_pressed = !!(mod & KMOD_SHIFT); -#if defined(_DEBUG) - this->fast_forward_key_pressed = _shift_pressed; -#else /* Speedup when pressing tab, except when using ALT+TAB * to switch to another application. */ this->fast_forward_key_pressed = keys[SDLK_TAB] && (mod & KMOD_ALT) == 0; -#endif /* defined(_DEBUG) */ /* Determine which directional keys are down. */ _dirkeys = diff --git a/src/video/video_driver.hpp b/src/video/video_driver.hpp index 6ef06c45f6dce..b81ec6e2fb922 100644 --- a/src/video/video_driver.hpp +++ b/src/video/video_driver.hpp @@ -167,15 +167,13 @@ class VideoDriver : public Driver { } /** - * Get a suggested default GUI zoom taking screen DPI into account. + * Get a suggested default GUI scale taking screen DPI into account. */ - virtual ZoomLevel GetSuggestedUIZoom() + virtual int GetSuggestedUIScale() { float dpi_scale = this->GetDPIScale(); - if (dpi_scale >= 3.0f) return ZOOM_LVL_NORMAL; - if (dpi_scale >= 1.5f) return ZOOM_LVL_OUT_2X; - return ZOOM_LVL_OUT_4X; + return Clamp(dpi_scale * 100, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE); } virtual const char *GetInfoString() const diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 44368b2249be1..07743255c6d43 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -38,6 +38,10 @@ #define PM_QS_INPUT 0x20000 #endif +#ifndef WM_DPICHANGED +#define WM_DPICHANGED 0x02E0 +#endif + bool _window_maximize; static Dimension _bck_resolution; DWORD _imm_props; @@ -670,6 +674,24 @@ LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) return TRUE; } + case WM_DPICHANGED: { + auto did_adjust = AdjustGUIZoom(true); + + /* Resize the window to match the new DPI setting. */ + RECT *prcNewWindow = (RECT *)lParam; + SetWindowPos(hwnd, + NULL, + prcNewWindow->left, + prcNewWindow->top, + prcNewWindow->right - prcNewWindow->left, + prcNewWindow->bottom - prcNewWindow->top, + SWP_NOZORDER | SWP_NOACTIVATE); + + if (did_adjust) ReInitAllWindows(true); + + return 0; + } + /* needed for wheel */ #if !defined(WM_MOUSEWHEEL) # define WM_MOUSEWHEEL 0x020A @@ -822,13 +844,9 @@ void VideoDriver_Win32Base::InputLoop() _ctrl_pressed = this->has_focus && GetAsyncKeyState(VK_CONTROL) < 0; _shift_pressed = this->has_focus && GetAsyncKeyState(VK_SHIFT) < 0; -#if defined(_DEBUG) - this->fast_forward_key_pressed = _shift_pressed; -#else /* Speedup when pressing tab, except when using ALT+TAB * to switch to another application. */ this->fast_forward_key_pressed = this->has_focus && GetAsyncKeyState(VK_TAB) < 0 && GetAsyncKeyState(VK_MENU) >= 0; -#endif /* Determine which directional keys are down. */ if (this->has_focus) { diff --git a/src/viewport.cpp b/src/viewport.cpp index 3819266c54bc4..dd5e469085537 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -61,6 +61,7 @@ */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "landscape.h" #include "viewport_func.h" #include "station_base.h" @@ -134,6 +135,7 @@ struct ChildScreenSpriteToDraw { const SubSprite *sub; ///< only draw a rectangular part of the sprite int32 x; int32 y; + bool relative; int next; ///< next child to draw (-1 at the end) }; @@ -185,7 +187,7 @@ static bool MarkViewportDirty(const Viewport *vp, int left, int top, int right, static ViewportDrawer _vd; TileHighlightData _thd; -static TileInfo *_cur_ti; +static TileInfo _cur_ti; bool _draw_bounding_boxes = false; bool _draw_dirty_blocks = false; uint _dirty_block_colour = 0; @@ -261,8 +263,8 @@ void InitializeWindowViewport(Window *w, int x, int y, vp->overlay = nullptr; w->viewport = vp; - vp->virtual_left = 0; // pt.x; - vp->virtual_top = 0; // pt.y; + vp->virtual_left = 0; + vp->virtual_top = 0; } static Point _vp_move_offs; @@ -537,7 +539,7 @@ static void AddChildSpriteToFoundation(SpriteID image, PaletteID pal, const SubS int *old_child = _vd.last_child; _vd.last_child = _vd.last_foundation_child[foundation_part]; - AddChildSpriteScreen(image, pal, offs.x + extra_offs_x, offs.y + extra_offs_y, false, sub, false); + AddChildSpriteScreen(image, pal, offs.x + extra_offs_x, offs.y + extra_offs_y, false, sub, false, false); /* Switch back to last ChildSprite list */ _vd.last_child = old_child; @@ -565,7 +567,7 @@ void DrawGroundSpriteAt(SpriteID image, PaletteID pal, int32 x, int32 y, int z, Point pt = RemapCoords(x, y, z); AddChildSpriteToFoundation(image, pal, sub, _vd.foundation_part, pt.x + extra_offs_x * ZOOM_LVL_BASE, pt.y + extra_offs_y * ZOOM_LVL_BASE); } else { - AddTileSpriteToDraw(image, pal, _cur_ti->x + x, _cur_ti->y + y, _cur_ti->z + z, sub, extra_offs_x * ZOOM_LVL_BASE, extra_offs_y * ZOOM_LVL_BASE); + AddTileSpriteToDraw(image, pal, _cur_ti.x + x, _cur_ti.y + y, _cur_ti.z + z, sub, extra_offs_x * ZOOM_LVL_BASE, extra_offs_y * ZOOM_LVL_BASE); } } @@ -816,8 +818,10 @@ bool IsInsideRotatedRectangle(int x, int y) * @param y sprite y-offset (screen coordinates) relative to parent sprite. * @param transparent if true, switch the palette between the provided palette and the transparent palette, * @param sub Only draw a part of the sprite. + * @param scale if true, scale offsets to base zoom level. + * @param relative if true, draw sprite relative to parent sprite offsets. */ -void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent, const SubSprite *sub, bool scale) +void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent, const SubSprite *sub, bool scale, bool relative) { assert((image & SPRITE_MASK) < MAX_SPRITES); @@ -838,6 +842,7 @@ void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool tran cs.sub = sub; cs.x = scale ? x * ZOOM_LVL_BASE : x; cs.y = scale ? y * ZOOM_LVL_BASE : y; + cs.relative = relative; cs.next = -1; /* Append the sprite to the active ChildSprite list. @@ -872,16 +877,18 @@ static void AddStringToDraw(int x, int y, StringID string, uint64 params_1, uint * @param ti TileInfo Tile that is being drawn * @param z_offset Z offset relative to the groundsprite. Only used for the sprite position, not for sprite sorting. * @param foundation_part Foundation part the sprite belongs to. + * @param extra_offs_x Pixel X offset for the sprite position. + * @param extra_offs_y Pixel Y offset for the sprite position. */ -static void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part) +static void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part, int extra_offs_x = 0, int extra_offs_y = 0) { /* FIXME: This is not totally valid for some autorail highlights that extend over the edges of the tile. */ if (_vd.foundation[foundation_part] == -1) { /* draw on real ground */ - AddTileSpriteToDraw(image, pal, ti->x, ti->y, ti->z + z_offset); + AddTileSpriteToDraw(image, pal, ti->x, ti->y, ti->z + z_offset, nullptr, extra_offs_x, extra_offs_y); } else { /* draw on top of foundation */ - AddChildSpriteToFoundation(image, pal, nullptr, foundation_part, 0, -z_offset * ZOOM_LVL_BASE); + AddChildSpriteToFoundation(image, pal, nullptr, foundation_part, extra_offs_x, extra_offs_y - z_offset * ZOOM_LVL_BASE); } } @@ -1213,26 +1220,24 @@ static void ViewportAddLandscape() assert(row == tilecoord.y + tilecoord.x); TileType tile_type; - TileInfo tile_info; - _cur_ti = &tile_info; - tile_info.x = tilecoord.x * TILE_SIZE; // FIXME tile_info should use signed integers - tile_info.y = tilecoord.y * TILE_SIZE; - - if (IsInsideBS(tilecoord.x, 0, MapSizeX()) && IsInsideBS(tilecoord.y, 0, MapSizeY())) { - /* This includes the south border at MapMaxX / MapMaxY. When terraforming we still draw tile selections there. */ - tile_info.tile = TileXY(tilecoord.x, tilecoord.y); - tile_type = GetTileType(tile_info.tile); + _cur_ti.x = tilecoord.x * TILE_SIZE; + _cur_ti.y = tilecoord.y * TILE_SIZE; + + if (IsInsideBS(tilecoord.x, 0, Map::SizeX()) && IsInsideBS(tilecoord.y, 0, Map::SizeY())) { + /* This includes the south border at Map::MaxX / Map::MaxY. When terraforming we still draw tile selections there. */ + _cur_ti.tile = TileXY(tilecoord.x, tilecoord.y); + tile_type = GetTileType(_cur_ti.tile); } else { - tile_info.tile = INVALID_TILE; + _cur_ti.tile = INVALID_TILE; tile_type = MP_VOID; } if (tile_type != MP_VOID) { /* We are inside the map => paint landscape. */ - tile_info.tileh = GetTilePixelSlope(tile_info.tile, &tile_info.z); + _cur_ti.tileh = GetTilePixelSlope(_cur_ti.tile, &_cur_ti.z); } else { /* We are outside the map => paint black. */ - tile_info.tileh = GetTilePixelSlopeOutsideMap(tilecoord.x, tilecoord.y, &tile_info.z); + _cur_ti.tileh = GetTilePixelSlopeOutsideMap(tilecoord.x, tilecoord.y, &_cur_ti.z); } int viewport_y = GetViewportY(tilecoord); @@ -1251,10 +1256,10 @@ static void ViewportAddLandscape() /* Is tile with buildings visible? */ if (min_visible_height < MAX_TILE_EXTENT_TOP) tile_visible = true; - if (IsBridgeAbove(tile_info.tile)) { + if (IsBridgeAbove(_cur_ti.tile)) { /* Is the bridge visible? */ - TileIndex bridge_tile = GetNorthernBridgeEnd(tile_info.tile); - int bridge_height = ZOOM_LVL_BASE * (GetBridgePixelHeight(bridge_tile) - TilePixelHeight(tile_info.tile)); + TileIndex bridge_tile = GetNorthernBridgeEnd(_cur_ti.tile); + int bridge_height = ZOOM_LVL_BASE * (GetBridgePixelHeight(bridge_tile) - TilePixelHeight(_cur_ti.tile)); if (min_visible_height < bridge_height + MAX_TILE_EXTENT_TOP) tile_visible = true; } @@ -1275,8 +1280,8 @@ static void ViewportAddLandscape() _vd.last_foundation_child[0] = nullptr; _vd.last_foundation_child[1] = nullptr; - _tile_type_procs[tile_type]->draw_tile_proc(&tile_info); - if (tile_info.tile != INVALID_TILE) DrawTileSelection(&tile_info); + _tile_type_procs[tile_type]->draw_tile_proc(&_cur_ti); + if (_cur_ti.tile != INVALID_TILE) DrawTileSelection(&_cur_ti); } } } @@ -1301,7 +1306,7 @@ void ViewportAddString(const DrawPixelInfo *dpi, ZoomLevel small_from, const Vie int right = left + dpi->width; int bottom = top + dpi->height; - int sign_height = ScaleByZoom(VPSM_TOP + FONT_HEIGHT_NORMAL + VPSM_BOTTOM, dpi->zoom); + int sign_height = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.fullbevel.bottom, dpi->zoom); int sign_half_width = ScaleByZoom((small ? sign->width_small : sign->width_normal) / 2, dpi->zoom); if (bottom < sign->top || @@ -1317,7 +1322,7 @@ void ViewportAddString(const DrawPixelInfo *dpi, ZoomLevel small_from, const Vie int shadow_offset = 0; if (string_small_shadow != STR_NULL) { shadow_offset = 4; - AddStringToDraw(sign->center - sign_half_width + shadow_offset, sign->top, string_small_shadow, params_1, params_2, INVALID_COLOUR, sign->width_small); + AddStringToDraw(sign->center - sign_half_width + shadow_offset, sign->top, string_small_shadow, params_1, params_2, INVALID_COLOUR, sign->width_small | 0x8000); } AddStringToDraw(sign->center - sign_half_width, sign->top - shadow_offset, string_small, params_1, params_2, colour, sign->width_small | 0x8000); @@ -1329,8 +1334,8 @@ static Rect ExpandRectWithViewportSignMargins(Rect r, ZoomLevel zoom) /* Pessimistically always use normal font, but also assume small font is never larger in either dimension */ const int fh = FONT_HEIGHT_NORMAL; const int max_tw = _viewport_sign_maxwidth / 2 + 1; - const int expand_y = ScaleByZoom(VPSM_TOP + fh + VPSM_BOTTOM, zoom); - const int expand_x = ScaleByZoom(VPSM_LEFT + max_tw + VPSM_RIGHT, zoom); + const int expand_y = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + fh + WidgetDimensions::scaled.fullbevel.bottom, zoom); + const int expand_x = ScaleByZoom(WidgetDimensions::scaled.fullbevel.left + max_tw + WidgetDimensions::scaled.fullbevel.right, zoom); r.left -= expand_x; r.right += expand_x; @@ -1351,9 +1356,6 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi) bool show_signs = HasBit(_display_opt, DO_SHOW_SIGNS) && !IsInvisibilitySet(TO_SIGNS); bool show_competitors = HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS); - const BaseStation *st; - const Sign *si; - /* Collect all the items first and draw afterwards, to ensure layering */ std::vector stations; std::vector towns; @@ -1361,34 +1363,36 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi) _viewport_sign_kdtree.FindContained(search_rect.left, search_rect.top, search_rect.right, search_rect.bottom, [&](const ViewportSignKdtreeItem & item) { switch (item.type) { - case ViewportSignKdtreeItem::VKI_STATION: + case ViewportSignKdtreeItem::VKI_STATION: { if (!show_stations) break; - st = BaseStation::Get(item.id.station); + const BaseStation *st = BaseStation::Get(item.id.station); /* Don't draw if station is owned by another company and competitor station names are hidden. Stations owned by none are never ignored. */ if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break; stations.push_back(st); break; + } - case ViewportSignKdtreeItem::VKI_WAYPOINT: + case ViewportSignKdtreeItem::VKI_WAYPOINT: { if (!show_waypoints) break; - st = BaseStation::Get(item.id.station); + const BaseStation *st = BaseStation::Get(item.id.station); /* Don't draw if station is owned by another company and competitor station names are hidden. Stations owned by none are never ignored. */ if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break; stations.push_back(st); break; + } case ViewportSignKdtreeItem::VKI_TOWN: if (!show_towns) break; towns.push_back(Town::Get(item.id.town)); break; - case ViewportSignKdtreeItem::VKI_SIGN: + case ViewportSignKdtreeItem::VKI_SIGN: { if (!show_signs) break; - si = Sign::Get(item.id.sign); + const Sign *si = Sign::Get(item.id.sign); /* Don't draw if sign is owned by another company and competitor signs should be hidden. * Note: It is intentional that also signs owned by OWNER_NONE are hidden. Bankrupt @@ -1397,6 +1401,7 @@ static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi) signs.push_back(si); break; + } default: NOT_REACHED(); @@ -1451,14 +1456,14 @@ void ViewportSign::UpdatePosition(int center, int top, StringID str, StringID st char buffer[DRAW_STRING_BUFFER]; GetString(buffer, str, lastof(buffer)); - this->width_normal = VPSM_LEFT + Align(GetStringBoundingBox(buffer).width, 2) + VPSM_RIGHT; + this->width_normal = WidgetDimensions::scaled.fullbevel.left + Align(GetStringBoundingBox(buffer).width, 2) + WidgetDimensions::scaled.fullbevel.right; this->center = center; /* zoomed out version */ if (str_small != STR_NULL) { GetString(buffer, str_small, lastof(buffer)); } - this->width_small = VPSM_LEFT + Align(GetStringBoundingBox(buffer, FS_SMALL).width, 2) + VPSM_RIGHT; + this->width_small = WidgetDimensions::scaled.fullbevel.left + Align(GetStringBoundingBox(buffer, FS_SMALL).width, 2) + WidgetDimensions::scaled.fullbevel.right; this->MarkDirty(); } @@ -1478,7 +1483,7 @@ void ViewportSign::MarkDirty(ZoomLevel maxzoom) const zoomlevels[zoom].left = this->center - ScaleByZoom(this->width_normal / 2 + 1, zoom); zoomlevels[zoom].top = this->top - ScaleByZoom(1, zoom); zoomlevels[zoom].right = this->center + ScaleByZoom(this->width_normal / 2 + 1, zoom); - zoomlevels[zoom].bottom = this->top + ScaleByZoom(VPSM_TOP + FONT_HEIGHT_NORMAL + VPSM_BOTTOM + 1, zoom); + zoomlevels[zoom].bottom = this->top + ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.fullbevel.bottom + 1, zoom); } for (const Window *w : Window::Iterate()) { @@ -1634,7 +1639,11 @@ static void ViewportDrawParentSprites(const ParentSpriteToSortVector *psd, const while (child_idx >= 0) { const ChildScreenSpriteToDraw *cs = csstdv->data() + child_idx; child_idx = cs->next; - DrawSpriteViewport(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y, cs->sub); + if (cs->relative) { + DrawSpriteViewport(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y, cs->sub); + } else { + DrawSpriteViewport(cs->image, cs->pal, ps->x + cs->x, ps->y + cs->y, cs->sub); + } } } } @@ -1688,7 +1697,7 @@ static void ViewportDrawStrings(ZoomLevel zoom, const StringSpriteToDrawVector * int w = GB(ss.width, 0, 15); int x = UnScaleByZoom(ss.x, zoom); int y = UnScaleByZoom(ss.y, zoom); - int h = VPSM_TOP + (small ? FONT_HEIGHT_SMALL : FONT_HEIGHT_NORMAL) + VPSM_BOTTOM; + int h = WidgetDimensions::scaled.fullbevel.top + (small ? FONT_HEIGHT_SMALL : FONT_HEIGHT_NORMAL) + WidgetDimensions::scaled.fullbevel.bottom; SetDParam(0, ss.params[0]); SetDParam(1, ss.params[1]); @@ -1706,21 +1715,18 @@ static void ViewportDrawStrings(ZoomLevel zoom, const StringSpriteToDrawVector * /* Draw the rectangle if 'transparent station signs' is off, * or if we are drawing a general text sign (STR_WHITE_SIGN). */ DrawFrameRect( - x, y, x + w, y + h, ss.colour, + x, y, x + w - 1, y + h - 1, ss.colour, IsTransparencySet(TO_SIGNS) ? FR_TRANSPARENT : FR_NONE ); } } - DrawString(x + VPSM_LEFT, x + w - 1 - VPSM_RIGHT, y + VPSM_TOP, ss.string, colour, SA_HOR_CENTER); + DrawString(x + WidgetDimensions::scaled.fullbevel.left, x + w - 1 - WidgetDimensions::scaled.fullbevel.right, y + WidgetDimensions::scaled.fullbevel.top, ss.string, colour, SA_HOR_CENTER, false, small ? FS_SMALL : FS_NORMAL); } } void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom) { - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &_vd.dpi; - _vd.dpi.zoom = vp->zoom; int mask = ScaleByZoom(-1, vp->zoom); @@ -1730,13 +1736,14 @@ void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom _vd.dpi.height = (bottom - top) & mask; _vd.dpi.left = left & mask; _vd.dpi.top = top & mask; - _vd.dpi.pitch = old_dpi->pitch; + _vd.dpi.pitch = _cur_dpi->pitch; _vd.last_child = nullptr; int x = UnScaleByZoom(_vd.dpi.left - (vp->virtual_left & mask), vp->zoom) + vp->left; int y = UnScaleByZoom(_vd.dpi.top - (vp->virtual_top & mask), vp->zoom) + vp->top; - _vd.dpi.dst_ptr = BlitterFactory::GetCurrentBlitter()->MoveTo(old_dpi->dst_ptr, x - old_dpi->left, y - old_dpi->top); + _vd.dpi.dst_ptr = BlitterFactory::GetCurrentBlitter()->MoveTo(_cur_dpi->dst_ptr, x - _cur_dpi->left, y - _cur_dpi->top); + AutoRestoreBackup dpi_backup(_cur_dpi, &_vd.dpi); ViewportAddLandscape(); ViewportAddVehicles(&_vd.dpi); @@ -1778,8 +1785,6 @@ void ViewportDoDraw(const Viewport *vp, int left, int top, int right, int bottom ViewportDrawStrings(zoom, &_vd.string_sprites_to_draw); } - _cur_dpi = old_dpi; - _vd.string_sprites_to_draw.clear(); _vd.tile_sprites_to_draw.clear(); _vd.parent_sprites_to_draw.clear(); @@ -1882,7 +1887,7 @@ void UpdateViewportPosition(Window *w) bool update_overlay = false; if (delta_x != 0 || delta_y != 0) { if (_settings_client.gui.smooth_scroll) { - int max_scroll = ScaleByMapSize1D(512 * ZOOM_LVL_BASE); + int max_scroll = Map::ScaleBySize1D(512 * ZOOM_LVL_BASE); /* Not at our desired position yet... */ w->viewport->scrollpos_x += Clamp(DivAwayFromZero(delta_x, 4), -max_scroll, max_scroll); w->viewport->scrollpos_y += Clamp(DivAwayFromZero(delta_y, 4), -max_scroll, max_scroll); @@ -2024,11 +2029,11 @@ static void SetSelectionTilesDirty() assert(x_size >= 0); assert(y_size >= 0); - int x_end = Clamp(x_start + x_size, 0, MapSizeX() * TILE_SIZE - TILE_SIZE); - int y_end = Clamp(y_start + y_size, 0, MapSizeY() * TILE_SIZE - TILE_SIZE); + int x_end = Clamp(x_start + x_size, 0, Map::SizeX() * TILE_SIZE - TILE_SIZE); + int y_end = Clamp(y_start + y_size, 0, Map::SizeY() * TILE_SIZE - TILE_SIZE); - x_start = Clamp(x_start, 0, MapSizeX() * TILE_SIZE - TILE_SIZE); - y_start = Clamp(y_start, 0, MapSizeY() * TILE_SIZE - TILE_SIZE); + x_start = Clamp(x_start, 0, Map::SizeX() * TILE_SIZE - TILE_SIZE); + y_start = Clamp(y_start, 0, Map::SizeY() * TILE_SIZE - TILE_SIZE); /* make sure everything is multiple of TILE_SIZE */ assert((x_end | y_end | x_start | y_start) % TILE_SIZE == 0); @@ -2104,7 +2109,7 @@ static void SetSelectionTilesDirty() uint x = (_thd.pos.x + (a + b) / 2) / TILE_SIZE; uint y = (_thd.pos.y + (a - b) / 2) / TILE_SIZE; - if (x < MapMaxX() && y < MapMaxY()) { + if (x < Map::MaxX() && y < Map::MaxY()) { MarkTileDirtyByTile(TileXY(x, y)); } } @@ -2131,7 +2136,7 @@ static bool CheckClickOnViewportSign(const Viewport *vp, int x, int y, const Vie { bool small = (vp->zoom >= ZOOM_LVL_OUT_16X); int sign_half_width = ScaleByZoom((small ? sign->width_small : sign->width_normal) / 2, vp->zoom); - int sign_height = ScaleByZoom(VPSM_TOP + (small ? FONT_HEIGHT_SMALL : FONT_HEIGHT_NORMAL) + VPSM_BOTTOM, vp->zoom); + int sign_height = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + (small ? FONT_HEIGHT_SMALL : FONT_HEIGHT_NORMAL) + WidgetDimensions::scaled.fullbevel.bottom, vp->zoom); return y >= sign->top && y < sign->top + sign_height && x >= sign->center - sign_half_width && x < sign->center + sign_half_width; @@ -2401,8 +2406,8 @@ bool ScrollWindowTo(int x, int y, int z, Window *w, bool instant) { /* The slope cannot be acquired outside of the map, so make sure we are always within the map. */ if (z == -1) { - if ( x >= 0 && x <= (int)MapSizeX() * (int)TILE_SIZE - 1 - && y >= 0 && y <= (int)MapSizeY() * (int)TILE_SIZE - 1) { + if ( x >= 0 && x <= (int)Map::SizeX() * (int)TILE_SIZE - 1 + && y >= 0 && y <= (int)Map::SizeY() * (int)TILE_SIZE - 1) { z = GetSlopePixelZ(x, y); } else { z = TileHeightOutsideMap(x / (int)TILE_SIZE, y / (int)TILE_SIZE); @@ -2971,9 +2976,9 @@ static void CalcRaildirsDrawstyle(int x, int y, int method) /* Make sure we do not overflow the map! */ CheckUnderflow(x, y, 1); CheckUnderflow(y, x, 1); - CheckOverflow(x, y, (MapMaxX() - 1) * TILE_SIZE, 1); - CheckOverflow(y, x, (MapMaxY() - 1) * TILE_SIZE, 1); - assert(x >= 0 && y >= 0 && x <= (int)(MapMaxX() * TILE_SIZE) && y <= (int)(MapMaxY() * TILE_SIZE)); + CheckOverflow(x, y, (Map::MaxX() - 1) * TILE_SIZE, 1); + CheckOverflow(y, x, (Map::MaxY() - 1) * TILE_SIZE, 1); + assert(x >= 0 && y >= 0 && x <= (int)(Map::MaxX() * TILE_SIZE) && y <= (int)(Map::MaxY() * TILE_SIZE)); } break; @@ -3006,9 +3011,9 @@ static void CalcRaildirsDrawstyle(int x, int y, int method) /* Make sure we do not overflow the map! */ CheckUnderflow(x, y, -1); CheckUnderflow(y, x, -1); - CheckOverflow(x, y, (MapMaxX() - 1) * TILE_SIZE, -1); - CheckOverflow(y, x, (MapMaxY() - 1) * TILE_SIZE, -1); - assert(x >= 0 && y >= 0 && x <= (int)(MapMaxX() * TILE_SIZE) && y <= (int)(MapMaxY() * TILE_SIZE)); + CheckOverflow(x, y, (Map::MaxX() - 1) * TILE_SIZE, -1); + CheckOverflow(y, x, (Map::MaxY() - 1) * TILE_SIZE, -1); + assert(x >= 0 && y >= 0 && x <= (int)(Map::MaxX() * TILE_SIZE) && y <= (int)(Map::MaxY() * TILE_SIZE)); } break; @@ -3430,7 +3435,7 @@ Point GetViewportStationMiddle(const Viewport *vp, const Station *st) { int x = TileX(st->xy) * TILE_SIZE; int y = TileY(st->xy) * TILE_SIZE; - int z = GetSlopePixelZ(Clamp(x, 0, MapSizeX() * TILE_SIZE - 1), Clamp(y, 0, MapSizeY() * TILE_SIZE - 1)); + int z = GetSlopePixelZ(Clamp(x, 0, Map::SizeX() * TILE_SIZE - 1), Clamp(y, 0, Map::SizeY() * TILE_SIZE - 1)); Point p = RemapCoords(x, y, z); p.x = UnScaleByZoom(p.x - vp->virtual_left, vp->zoom) + vp->left; diff --git a/src/viewport_func.h b/src/viewport_func.h index e60df4d31ed97..20bf5837c18fb 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.h @@ -31,6 +31,7 @@ bool MarkAllViewportsDirty(int left, int top, int right, int bottom); bool DoZoomInOutWindow(ZoomStateChange how, Window *w); void ZoomInOrOutToCursorWindow(bool in, Window * w); +void ConstrainAllViewportsZoom(); Point GetTileZoomCenterWindow(bool in, Window * w); void FixTitleGameZoom(int zoom_adjust = 0); void HandleZoomMessage(Window *w, const Viewport *vp, byte widget_zoom_in, byte widget_zoom_out); @@ -51,7 +52,7 @@ void OffsetGroundSprite(int x, int y); void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub = nullptr, int extra_offs_x = 0, int extra_offs_y = 0); void DrawGroundSpriteAt(SpriteID image, PaletteID pal, int32 x, int32 y, int z, const SubSprite *sub = nullptr, int extra_offs_x = 0, int extra_offs_y = 0); void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, int h, int dz, int z, bool transparent = false, int bb_offset_x = 0, int bb_offset_y = 0, int bb_offset_z = 0, const SubSprite *sub = nullptr); -void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent = false, const SubSprite *sub = nullptr, bool scale = true); +void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent = false, const SubSprite *sub = nullptr, bool scale = true, bool relative = true); void ViewportAddString(const DrawPixelInfo *dpi, ZoomLevel small_from, const ViewportSign *sign, StringID string_normal, StringID string_small, StringID string_small_shadow, uint64 params_1, uint64 params_2 = 0, Colours colour = INVALID_COLOUR); diff --git a/src/viewport_gui.cpp b/src/viewport_gui.cpp index 5047f04f3f4e1..df670cc15299e 100644 --- a/src/viewport_gui.cpp +++ b/src/viewport_gui.cpp @@ -57,13 +57,13 @@ class ExtraViewportWindow : public Window { this->InitNested(window_number); NWidgetViewport *nvp = this->GetWidget(WID_EV_VIEWPORT); - nvp->InitializeViewport(this, 0, ZOOM_LVL_VIEWPORT); - if (_settings_client.gui.zoom_min == ZOOM_LVL_VIEWPORT) this->DisableWidget(WID_EV_ZOOM_IN); + nvp->InitializeViewport(this, 0, ScaleZoomGUI(ZOOM_LVL_VIEWPORT)); + if (_settings_client.gui.zoom_min == viewport->zoom) this->DisableWidget(WID_EV_ZOOM_IN); Point pt; if (tile == INVALID_TILE) { /* No tile? Use center of main viewport. */ - const Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + const Window *w = GetMainWindow(); /* center on same place as main window (zoom is maximum, no adjustment needed) */ pt.x = w->viewport->scrollpos_x + w->viewport->virtual_width / 2; @@ -95,7 +95,7 @@ class ExtraViewportWindow : public Window { case WID_EV_ZOOM_OUT: DoZoomInOutWindow(ZOOM_OUT, this); break; case WID_EV_MAIN_TO_VIEW: { // location button (move main view to same spot as this view) 'Paste Location' - Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + Window *w = GetMainWindow(); int x = this->viewport->scrollpos_x; // Where is the main looking at int y = this->viewport->scrollpos_y; @@ -107,7 +107,7 @@ class ExtraViewportWindow : public Window { } case WID_EV_VIEW_TO_MAIN: { // inverse location button (move this view to same spot as main view) 'Copy Location' - const Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + const Window *w = GetMainWindow(); int x = w->viewport->scrollpos_x; int y = w->viewport->scrollpos_y; diff --git a/src/viewport_sprite_sorter_sse4.cpp b/src/viewport_sprite_sorter_sse4.cpp index fc7eb49e4056d..3272645e5bf67 100644 --- a/src/viewport_sprite_sorter_sse4.cpp +++ b/src/viewport_sprite_sorter_sse4.cpp @@ -26,6 +26,7 @@ # define LOAD_128 _mm_loadu_si128 #endif +GNU_TARGET("sse4.1") void ViewportSortParentSpritesSSE41(ParentSpriteToSortVector *psdv) { if (psdv->size() < 2) return; diff --git a/src/viewport_type.h b/src/viewport_type.h index a317734b6171f..52005144034b0 100644 --- a/src/viewport_type.h +++ b/src/viewport_type.h @@ -34,14 +34,6 @@ struct Viewport { LinkGraphOverlay *overlay; }; -/** Margins for the viewport sign */ -enum ViewportSignMargin { - VPSM_LEFT = 1, ///< Left margin - VPSM_RIGHT = 1, ///< Right margin - VPSM_TOP = 1, ///< Top margin - VPSM_BOTTOM = 1, ///< Bottom margin -}; - /** Location information about a sign as seen on the viewport */ struct ViewportSign { int32 center; ///< The center position of the sign @@ -123,6 +115,7 @@ enum ViewportDragDropSelectionProcess { DDSP_CREATE_RIVER, ///< Create rivers DDSP_PLANT_TREES, ///< Plant trees DDSP_BUILD_BRIDGE, ///< Bridge placement + DDSP_BUILD_OBJECT, ///< Build an object /* Rail specific actions */ DDSP_PLACE_RAIL, ///< Rail placement diff --git a/src/void_cmd.cpp b/src/void_cmd.cpp index cf159d69cc0b7..f5716e3f8d7ad 100644 --- a/src/void_cmd.cpp +++ b/src/void_cmd.cpp @@ -12,6 +12,7 @@ #include "command_func.h" #include "viewport_func.h" #include "slope_func.h" +#include "water.h" #include "table/strings.h" #include "table/sprites.h" @@ -53,7 +54,8 @@ static void GetTileDesc_Void(TileIndex tile, TileDesc *td) static void TileLoop_Void(TileIndex tile) { - /* not used */ + /* Floods adjacent edge tile to prevent maps without water. */ + TileLoop_Water(tile); } static void ChangeTileOwner_Void(TileIndex tile, Owner old_owner, Owner new_owner) diff --git a/src/void_map.h b/src/void_map.h index 415e0a580369b..de658585c18fb 100644 --- a/src/void_map.h +++ b/src/void_map.h @@ -16,17 +16,17 @@ * Make a nice void tile ;) * @param t the tile to make void */ -static inline void MakeVoid(TileIndex t) +static inline void MakeVoid(Tile t) { SetTileType(t, MP_VOID); SetTileHeight(t, 0); - _m[t].m1 = 0; - _m[t].m2 = 0; - _m[t].m3 = 0; - _m[t].m4 = 0; - _m[t].m5 = 0; - _me[t].m6 = 0; - _me[t].m7 = 0; + t.m1() = 0; + t.m2() = 0; + t.m3() = 0; + t.m4() = 0; + t.m5() = 0; + t.m6() = 0; + t.m7() = 0; } #endif /* VOID_MAP_H */ diff --git a/src/walltime_func.h b/src/walltime_func.h index f070d8e2b9bce..216a726662a56 100644 --- a/src/walltime_func.h +++ b/src/walltime_func.h @@ -65,7 +65,7 @@ struct Time { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-nonliteral" #endif /* _MSC_VER */ - return strftime(buffer, last - buffer, format, &time_struct); + return strftime(buffer, last - buffer + 1, format, &time_struct); #ifndef _MSC_VER #pragma GCC diagnostic pop #endif /* _MSC_VER */ diff --git a/src/water.h b/src/water.h index 27c3339c1852e..379c13ef725c4 100644 --- a/src/water.h +++ b/src/water.h @@ -39,6 +39,7 @@ void MakeWaterKeepingClass(TileIndex tile, Owner o); void CheckForDockingTile(TileIndex t); bool RiverModifyDesertZone(TileIndex tile, void *data); +void MakeRiverAndModifyDesertZoneAround(TileIndex tile); static const uint RIVER_OFFSET_DESERT_DISTANCE = 5; ///< Circular tile search radius to create non-desert around a river tile. bool IsWateredTile(TileIndex tile, Direction from); diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 211e89b4a0d43..759afbdc4f1b8 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -136,11 +136,14 @@ CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis) Depot *depot = new Depot(tile); depot->build_date = _date; - if (wc1 == WATER_CLASS_CANAL || wc2 == WATER_CLASS_CANAL) { - /* Update infrastructure counts after the unconditional clear earlier. */ - Company::Get(_current_company)->infrastructure.water += wc1 == WATER_CLASS_CANAL && wc2 == WATER_CLASS_CANAL ? 2 : 1; - } - Company::Get(_current_company)->infrastructure.water += 2 * LOCK_DEPOT_TILE_FACTOR; + uint new_water_infra = 2 * LOCK_DEPOT_TILE_FACTOR; + /* Update infrastructure counts after the tile clears earlier. + * Clearing object tiles may result in water tiles which are already accounted for in the water infrastructure total. + * See: MakeWaterKeepingClass() */ + if (wc1 == WATER_CLASS_CANAL && !(HasTileWaterClass(tile) && GetWaterClass(tile) == WATER_CLASS_CANAL && IsTileOwner(tile, _current_company))) new_water_infra++; + if (wc2 == WATER_CLASS_CANAL && !(HasTileWaterClass(tile2) && GetWaterClass(tile2) == WATER_CLASS_CANAL && IsTileOwner(tile2, _current_company))) new_water_infra++; + + Company::Get(_current_company)->infrastructure.water += new_water_infra; DirtyCompanyInfrastructureWindows(_current_company); MakeShipDepot(tile, _current_company, depot->index, DEPOT_PART_NORTH, axis, wc1); @@ -155,7 +158,7 @@ CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis) return cost; } -bool IsPossibleDockingTile(TileIndex t) +bool IsPossibleDockingTile(Tile t) { assert(IsValidTile(t)); switch (GetTileType(t)) { @@ -264,7 +267,7 @@ static CommandCost RemoveShipDepot(TileIndex tile, DoCommandFlag flags) /* do not check for ship on tile when company goes bankrupt */ if (!(flags & DC_BANKRUPT)) { - CommandCost ret = EnsureNoVehicleOnGround(tile); + ret = EnsureNoVehicleOnGround(tile); if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile2); if (ret.Failed()) return ret; } @@ -427,6 +430,18 @@ bool RiverModifyDesertZone(TileIndex tile, void *) return false; } +/** + * Make a river tile and remove desert directly around it. + * @param tile The tile to change into river and create non-desert around + */ +void MakeRiverAndModifyDesertZoneAround(TileIndex tile) { + MakeRiver(tile, Random()); + MarkTileDirtyByTile(tile); + + /* Remove desert directly around the river tile. */ + CircularTileSearch(&tile, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr); +} + /** * Build a piece of canal. * @param flags type of operation @@ -438,26 +453,14 @@ bool RiverModifyDesertZone(TileIndex tile, void *) */ CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal) { - if (start_tile >= MapSize() || !IsValidWaterClass(wc)) return CMD_ERROR; + if (start_tile >= Map::Size() || !IsValidWaterClass(wc)) return CMD_ERROR; /* Outside of the editor you can only build canals, not oceans */ if (wc != WATER_CLASS_CANAL && _game_mode != GM_EDITOR) return CMD_ERROR; - /* Outside the editor you can only drag canals, and not areas */ - if (_game_mode != GM_EDITOR) { - TileArea ta(tile, start_tile); - if (ta.w != 1 && ta.h != 1) return CMD_ERROR; - } - CommandCost cost(EXPENSES_CONSTRUCTION); - std::unique_ptr iter; - if (diagonal) { - iter = std::make_unique(tile, start_tile); - } else { - iter = std::make_unique(tile, start_tile); - } - + std::unique_ptr iter = TileIterator::Create(tile, start_tile, diagonal); for (; *iter != INVALID_TILE; ++(*iter)) { TileIndex current_tile = *iter; CommandCost ret; @@ -528,8 +531,8 @@ static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags) Money base_cost = IsCanal(tile) ? _price[PR_CLEAR_CANAL] : _price[PR_CLEAR_WATER]; /* Make sure freeform edges are allowed or it's not an edge tile. */ - if (!_settings_game.construction.freeform_edges && (!IsInsideMM(TileX(tile), 1, MapMaxX() - 1) || - !IsInsideMM(TileY(tile), 1, MapMaxY() - 1))) { + if (!_settings_game.construction.freeform_edges && (!IsInsideMM(TileX(tile), 1, Map::MaxX() - 1) || + !IsInsideMM(TileY(tile), 1, Map::MaxY() - 1))) { return_cmd_error(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP); } @@ -539,7 +542,7 @@ static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags) Owner owner = GetTileOwner(tile); if (owner != OWNER_WATER && owner != OWNER_NONE) { - CommandCost ret = CheckTileOwnership(tile); + ret = CheckTileOwnership(tile); if (ret.Failed()) return ret; } @@ -548,10 +551,8 @@ static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags) Company::Get(owner)->infrastructure.water--; DirtyCompanyInfrastructureWindows(owner); } - bool remove = IsDockingTile(tile); DoClearSquare(tile); MarkCanalsAndRiversAroundDirty(tile); - if (remove) RemoveDockingTile(tile); } return CommandCost(EXPENSES_CONSTRUCTION, base_cost); @@ -565,10 +566,8 @@ static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags) if (ret.Failed()) return ret; if (flags & DC_EXEC) { - bool remove = IsDockingTile(tile); DoClearSquare(tile); MarkCanalsAndRiversAroundDirty(tile); - if (remove) RemoveDockingTile(tile); } if (IsSlopeWithOneCornerRaised(slope)) { return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_WATER]); @@ -1093,6 +1092,9 @@ FloodingBehaviour GetFloodingBehaviour(TileIndex tile) case MP_TREES: return (GetTreeGround(tile) == TREE_GROUND_SHORE ? FLOOD_DRYUP : FLOOD_NONE); + case MP_VOID: + return FLOOD_ACTIVE; + default: return FLOOD_NONE; } @@ -1244,7 +1246,7 @@ void TileLoop_Water(TileIndex tile) Slope slope_here = GetFoundationSlope(tile) & ~SLOPE_HALFTILE_MASK & ~SLOPE_STEEP; for (uint dir : SetBitIterator(_flood_from_dirs[slope_here])) { TileIndex dest = tile + TileOffsByDir((Direction)dir); - if (!IsValidTile(dest)) continue; + if (dest >= Map::Size()) continue; FloodingBehaviour dest_behaviour = GetFloodingBehaviour(dest); if ((dest_behaviour == FLOOD_ACTIVE) || (dest_behaviour == FLOOD_PASSIVE)) return; @@ -1261,7 +1263,7 @@ void ConvertGroundTilesIntoWaterTiles() { int z; - for (TileIndex tile = 0; tile < MapSize(); ++tile) { + for (TileIndex tile = 0; tile < Map::Size(); ++tile) { Slope slope = GetTileSlope(tile, &z); if (IsTileType(tile, MP_CLEAR) && z == 0) { /* Make both water for tiles at level 0 @@ -1283,7 +1285,7 @@ void ConvertGroundTilesIntoWaterTiles() for (uint dir : SetBitIterator(_flood_from_dirs[slope & ~SLOPE_STEEP])) { TileIndex dest = TileAddByDir(tile, (Direction)dir); Slope slope_dest = GetTileSlope(dest) & ~SLOPE_STEEP; - if (slope_dest == SLOPE_FLAT || IsSlopeWithOneCornerRaised(slope_dest)) { + if (slope_dest == SLOPE_FLAT || IsSlopeWithOneCornerRaised(slope_dest) || IsTileType(dest, MP_VOID)) { MakeShore(tile); break; } diff --git a/src/water_map.h b/src/water_map.h index ff2c38a7bcd51..97808d176b745 100644 --- a/src/water_map.h +++ b/src/water_map.h @@ -78,19 +78,19 @@ enum LockPart { LOCK_PART_UPPER = 2, ///< Upper part of a lock. }; -bool IsPossibleDockingTile(TileIndex t); +bool IsPossibleDockingTile(Tile t); /** * Get the water tile type at a tile. * @param t Water tile to query. * @return Water tile type at the tile. */ -static inline WaterTileType GetWaterTileType(TileIndex t) +static inline WaterTileType GetWaterTileType(Tile t) { assert(IsTileType(t, MP_WATER)); - switch (GB(_m[t].m5, WBL_TYPE_BEGIN, WBL_TYPE_COUNT)) { - case WBL_TYPE_NORMAL: return HasBit(_m[t].m5, WBL_COAST_FLAG) ? WATER_TILE_COAST : WATER_TILE_CLEAR; + switch (GB(t.m5(), WBL_TYPE_BEGIN, WBL_TYPE_COUNT)) { + case WBL_TYPE_NORMAL: return HasBit(t.m5(), WBL_COAST_FLAG) ? WATER_TILE_COAST : WATER_TILE_CLEAR; case WBL_TYPE_LOCK: return WATER_TILE_LOCK; case WBL_TYPE_DEPOT: return WATER_TILE_DEPOT; default: NOT_REACHED(); @@ -103,7 +103,7 @@ static inline WaterTileType GetWaterTileType(TileIndex t) * @param t Tile to query. * @return True if the tiletype has a waterclass. */ -static inline bool HasTileWaterClass(TileIndex t) +static inline bool HasTileWaterClass(Tile t) { return IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY) || IsTileType(t, MP_OBJECT) || IsTileType(t, MP_TREES); } @@ -114,10 +114,10 @@ static inline bool HasTileWaterClass(TileIndex t) * @pre IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY) || IsTileType(t, MP_OBJECT) * @return Water class at the tile. */ -static inline WaterClass GetWaterClass(TileIndex t) +static inline WaterClass GetWaterClass(Tile t) { assert(HasTileWaterClass(t)); - return (WaterClass)GB(_m[t].m1, 5, 2); + return (WaterClass)GB(t.m1(), 5, 2); } /** @@ -126,10 +126,10 @@ static inline WaterClass GetWaterClass(TileIndex t) * @param wc New water class. * @pre IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY) || IsTileType(t, MP_OBJECT) */ -static inline void SetWaterClass(TileIndex t, WaterClass wc) +static inline void SetWaterClass(Tile t, WaterClass wc) { assert(HasTileWaterClass(t)); - SB(_m[t].m1, 5, 2, wc); + SB(t.m1(), 5, 2, wc); } /** @@ -138,7 +138,7 @@ static inline void SetWaterClass(TileIndex t, WaterClass wc) * @pre IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY) || IsTileType(t, MP_OBJECT) * @return true iff on water */ -static inline bool IsTileOnWater(TileIndex t) +static inline bool IsTileOnWater(Tile t) { return (GetWaterClass(t) != WATER_CLASS_INVALID); } @@ -149,7 +149,7 @@ static inline bool IsTileOnWater(TileIndex t) * @return \c true if any type of clear water like ocean, river, or canal. * @pre IsTileType(t, MP_WATER) */ -static inline bool IsWater(TileIndex t) +static inline bool IsWater(Tile t) { return GetWaterTileType(t) == WATER_TILE_CLEAR; } @@ -160,7 +160,7 @@ static inline bool IsWater(TileIndex t) * @return \c true if it is a sea water tile. * @pre IsTileType(t, MP_WATER) */ -static inline bool IsSea(TileIndex t) +static inline bool IsSea(Tile t) { return IsWater(t) && GetWaterClass(t) == WATER_CLASS_SEA; } @@ -171,7 +171,7 @@ static inline bool IsSea(TileIndex t) * @return \c true if it is a canal tile. * @pre IsTileType(t, MP_WATER) */ -static inline bool IsCanal(TileIndex t) +static inline bool IsCanal(Tile t) { return IsWater(t) && GetWaterClass(t) == WATER_CLASS_CANAL; } @@ -182,7 +182,7 @@ static inline bool IsCanal(TileIndex t) * @return \c true if it is a river water tile. * @pre IsTileType(t, MP_WATER) */ -static inline bool IsRiver(TileIndex t) +static inline bool IsRiver(Tile t) { return IsWater(t) && GetWaterClass(t) == WATER_CLASS_RIVER; } @@ -192,7 +192,7 @@ static inline bool IsRiver(TileIndex t) * @param t Tile to query. * @return \c true if it is a plain water tile. */ -static inline bool IsWaterTile(TileIndex t) +static inline bool IsWaterTile(Tile t) { return IsTileType(t, MP_WATER) && IsWater(t); } @@ -203,7 +203,7 @@ static inline bool IsWaterTile(TileIndex t) * @return \c true if it is a sea water tile. * @pre IsTileType(t, MP_WATER) */ -static inline bool IsCoast(TileIndex t) +static inline bool IsCoast(Tile t) { return GetWaterTileType(t) == WATER_TILE_COAST; } @@ -213,7 +213,7 @@ static inline bool IsCoast(TileIndex t) * @param t Tile to query. * @return \c true if it is a coast. */ -static inline bool IsCoastTile(TileIndex t) +static inline bool IsCoastTile(Tile t) { return (IsTileType(t, MP_WATER) && IsCoast(t)) || (IsTileType(t, MP_TREES) && GetWaterClass(t) != WATER_CLASS_INVALID); } @@ -224,7 +224,7 @@ static inline bool IsCoastTile(TileIndex t) * @return \c true if it is a ship depot tile. * @pre IsTileType(t, MP_WATER) */ -static inline bool IsShipDepot(TileIndex t) +static inline bool IsShipDepot(Tile t) { return GetWaterTileType(t) == WATER_TILE_DEPOT; } @@ -234,7 +234,7 @@ static inline bool IsShipDepot(TileIndex t) * @param t Tile to query. * @return \c true if it is a ship depot tile. */ -static inline bool IsShipDepotTile(TileIndex t) +static inline bool IsShipDepotTile(Tile t) { return IsTileType(t, MP_WATER) && IsShipDepot(t); } @@ -245,10 +245,10 @@ static inline bool IsShipDepotTile(TileIndex t) * @return Axis of the depot. * @pre IsShipDepotTile(t) */ -static inline Axis GetShipDepotAxis(TileIndex t) +static inline Axis GetShipDepotAxis(Tile t) { assert(IsShipDepotTile(t)); - return (Axis)GB(_m[t].m5, WBL_DEPOT_AXIS, 1); + return (Axis)GB(t.m5(), WBL_DEPOT_AXIS, 1); } /** @@ -257,10 +257,10 @@ static inline Axis GetShipDepotAxis(TileIndex t) * @return Part of the depot. * @pre IsShipDepotTile(t) */ -static inline DepotPart GetShipDepotPart(TileIndex t) +static inline DepotPart GetShipDepotPart(Tile t) { assert(IsShipDepotTile(t)); - return (DepotPart)GB(_m[t].m5, WBL_DEPOT_PART, 1); + return (DepotPart)GB(t.m5(), WBL_DEPOT_PART, 1); } /** @@ -269,7 +269,7 @@ static inline DepotPart GetShipDepotPart(TileIndex t) * @return Direction of the depot. * @pre IsShipDepotTile(t) */ -static inline DiagDirection GetShipDepotDirection(TileIndex t) +static inline DiagDirection GetShipDepotDirection(Tile t) { return XYNSToDiagDir(GetShipDepotAxis(t), GetShipDepotPart(t)); } @@ -280,9 +280,9 @@ static inline DiagDirection GetShipDepotDirection(TileIndex t) * @return Tile containing the other section of the depot. * @pre IsShipDepotTile(t) */ -static inline TileIndex GetOtherShipDepotTile(TileIndex t) +static inline TileIndex GetOtherShipDepotTile(Tile t) { - return t + (GetShipDepotPart(t) != DEPOT_PART_NORTH ? -1 : 1) * (GetShipDepotAxis(t) != AXIS_X ? TileDiffXY(0, 1) : TileDiffXY(1, 0)); + return TileIndex(t) + (GetShipDepotPart(t) != DEPOT_PART_NORTH ? -1 : 1) * (GetShipDepotAxis(t) != AXIS_X ? TileDiffXY(0, 1) : TileDiffXY(1, 0)); } /** @@ -291,12 +291,12 @@ static inline TileIndex GetOtherShipDepotTile(TileIndex t) * @return The northern tile of the depot. * @pre IsShipDepotTile(t) */ -static inline TileIndex GetShipDepotNorthTile(TileIndex t) +static inline TileIndex GetShipDepotNorthTile(Tile t) { assert(IsShipDepot(t)); TileIndex tile2 = GetOtherShipDepotTile(t); - return t < tile2 ? t : tile2; + return t < tile2 ? TileIndex(t) : tile2; } /** @@ -305,7 +305,7 @@ static inline TileIndex GetShipDepotNorthTile(TileIndex t) * @return \c true if it is a water lock tile. * @pre IsTileType(t, MP_WATER) */ -static inline bool IsLock(TileIndex t) +static inline bool IsLock(Tile t) { return GetWaterTileType(t) == WATER_TILE_LOCK; } @@ -316,10 +316,10 @@ static inline bool IsLock(TileIndex t) * @return Direction of the lock. * @pre IsTileType(t, MP_WATER) && IsLock(t) */ -static inline DiagDirection GetLockDirection(TileIndex t) +static inline DiagDirection GetLockDirection(Tile t) { assert(IsLock(t)); - return (DiagDirection)GB(_m[t].m5, WBL_LOCK_ORIENT_BEGIN, WBL_LOCK_ORIENT_COUNT); + return (DiagDirection)GB(t.m5(), WBL_LOCK_ORIENT_BEGIN, WBL_LOCK_ORIENT_COUNT); } /** @@ -328,10 +328,10 @@ static inline DiagDirection GetLockDirection(TileIndex t) * @return The part. * @pre IsTileType(t, MP_WATER) && IsLock(t) */ -static inline byte GetLockPart(TileIndex t) +static inline byte GetLockPart(Tile t) { assert(IsLock(t)); - return GB(_m[t].m5, WBL_LOCK_PART_BEGIN, WBL_LOCK_PART_COUNT); + return GB(t.m5(), WBL_LOCK_PART_BEGIN, WBL_LOCK_PART_COUNT); } /** @@ -340,10 +340,10 @@ static inline byte GetLockPart(TileIndex t) * @return Random bits of the tile. * @pre IsTileType(t, MP_WATER) */ -static inline byte GetWaterTileRandomBits(TileIndex t) +static inline byte GetWaterTileRandomBits(Tile t) { assert(IsTileType(t, MP_WATER)); - return _m[t].m4; + return t.m4(); } /** @@ -352,7 +352,7 @@ static inline byte GetWaterTileRandomBits(TileIndex t) * @return true iff the tile has water at the ground. * @note Coast tiles are not considered waterish, even if there is water on a halftile. */ -static inline bool HasTileWaterGround(TileIndex t) +static inline bool HasTileWaterGround(Tile t) { return HasTileWaterClass(t) && IsTileOnWater(t) && !IsCoastTile(t); } @@ -363,19 +363,19 @@ static inline bool HasTileWaterGround(TileIndex t) * @param t the tile * @param b the docking tile state */ -static inline void SetDockingTile(TileIndex t, bool b) +static inline void SetDockingTile(Tile t, bool b) { assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_RAILWAY) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE)); - SB(_m[t].m1, 7, 1, b ? 1 : 0); + SB(t.m1(), 7, 1, b ? 1 : 0); } /** * Checks whether the tile is marked as a dockling tile. * @return true iff the tile is marked as a docking tile. */ -static inline bool IsDockingTile(TileIndex t) +static inline bool IsDockingTile(Tile t) { - return (IsTileType(t, MP_WATER) || IsTileType(t, MP_RAILWAY) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE)) && HasBit(_m[t].m1, 7); + return (IsTileType(t, MP_WATER) || IsTileType(t, MP_RAILWAY) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE)) && HasBit(t.m1(), 7); } @@ -383,18 +383,18 @@ static inline bool IsDockingTile(TileIndex t) * Helper function to make a coast tile. * @param t The tile to change into water */ -static inline void MakeShore(TileIndex t) +static inline void MakeShore(Tile t) { SetTileType(t, MP_WATER); SetTileOwner(t, OWNER_WATER); SetWaterClass(t, WATER_CLASS_SEA); SetDockingTile(t, false); - _m[t].m2 = 0; - _m[t].m3 = 0; - _m[t].m4 = 0; - _m[t].m5 = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN | 1 << WBL_COAST_FLAG; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; + t.m2() = 0; + t.m3() = 0; + t.m4() = 0; + t.m5() = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN | 1 << WBL_COAST_FLAG; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; } /** @@ -404,25 +404,25 @@ static inline void MakeShore(TileIndex t) * @param wc The class of water the tile has to be * @param random_bits Eventual random bits to be set for this tile */ -static inline void MakeWater(TileIndex t, Owner o, WaterClass wc, uint8 random_bits) +static inline void MakeWater(Tile t, Owner o, WaterClass wc, uint8 random_bits) { SetTileType(t, MP_WATER); SetTileOwner(t, o); SetWaterClass(t, wc); SetDockingTile(t, false); - _m[t].m2 = 0; - _m[t].m3 = 0; - _m[t].m4 = random_bits; - _m[t].m5 = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; + t.m2() = 0; + t.m3() = 0; + t.m4() = random_bits; + t.m5() = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; } /** * Make a sea tile. * @param t The tile to change into sea */ -static inline void MakeSea(TileIndex t) +static inline void MakeSea(Tile t) { MakeWater(t, OWNER_WATER, WATER_CLASS_SEA, 0); } @@ -432,7 +432,7 @@ static inline void MakeSea(TileIndex t) * @param t The tile to change into river * @param random_bits Random bits to be set for this tile */ -static inline void MakeRiver(TileIndex t, uint8 random_bits) +static inline void MakeRiver(Tile t, uint8 random_bits) { MakeWater(t, OWNER_WATER, WATER_CLASS_RIVER, random_bits); } @@ -443,7 +443,7 @@ static inline void MakeRiver(TileIndex t, uint8 random_bits) * @param o The owner of the canal * @param random_bits Random bits to be set for this tile */ -static inline void MakeCanal(TileIndex t, Owner o, uint8 random_bits) +static inline void MakeCanal(Tile t, Owner o, uint8 random_bits) { assert(o != OWNER_WATER); MakeWater(t, o, WATER_CLASS_CANAL, random_bits); @@ -458,18 +458,18 @@ static inline void MakeCanal(TileIndex t, Owner o, uint8 random_bits) * @param a Axis of the depot. * @param original_water_class Original water class. */ -static inline void MakeShipDepot(TileIndex t, Owner o, DepotID did, DepotPart part, Axis a, WaterClass original_water_class) +static inline void MakeShipDepot(Tile t, Owner o, DepotID did, DepotPart part, Axis a, WaterClass original_water_class) { SetTileType(t, MP_WATER); SetTileOwner(t, o); SetWaterClass(t, original_water_class); SetDockingTile(t, false); - _m[t].m2 = did; - _m[t].m3 = 0; - _m[t].m4 = 0; - _m[t].m5 = WBL_TYPE_DEPOT << WBL_TYPE_BEGIN | part << WBL_DEPOT_PART | a << WBL_DEPOT_AXIS; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; + t.m2() = did; + t.m3() = 0; + t.m4() = 0; + t.m5() = WBL_TYPE_DEPOT << WBL_TYPE_BEGIN | part << WBL_DEPOT_PART | a << WBL_DEPOT_AXIS; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; } /** @@ -481,18 +481,18 @@ static inline void MakeShipDepot(TileIndex t, Owner o, DepotID did, DepotPart pa * @param original_water_class Original water class. * @see MakeLock */ -static inline void MakeLockTile(TileIndex t, Owner o, LockPart part, DiagDirection dir, WaterClass original_water_class) +static inline void MakeLockTile(Tile t, Owner o, LockPart part, DiagDirection dir, WaterClass original_water_class) { SetTileType(t, MP_WATER); SetTileOwner(t, o); SetWaterClass(t, original_water_class); SetDockingTile(t, false); - _m[t].m2 = 0; - _m[t].m3 = 0; - _m[t].m4 = 0; - _m[t].m5 = WBL_TYPE_LOCK << WBL_TYPE_BEGIN | part << WBL_LOCK_PART_BEGIN | dir << WBL_LOCK_ORIENT_BEGIN; - SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = 0; + t.m2() = 0; + t.m3() = 0; + t.m4() = 0; + t.m5() = WBL_TYPE_LOCK << WBL_TYPE_BEGIN | part << WBL_LOCK_PART_BEGIN | dir << WBL_LOCK_ORIENT_BEGIN; + SB(t.m6(), 2, 4, 0); + t.m7() = 0; } /** @@ -504,15 +504,17 @@ static inline void MakeLockTile(TileIndex t, Owner o, LockPart part, DiagDirecti * @param wc_upper Original water class of the upper part. * @param wc_middle Original water class of the middle part. */ -static inline void MakeLock(TileIndex t, Owner o, DiagDirection d, WaterClass wc_lower, WaterClass wc_upper, WaterClass wc_middle) +static inline void MakeLock(Tile t, Owner o, DiagDirection d, WaterClass wc_lower, WaterClass wc_upper, WaterClass wc_middle) { TileIndexDiff delta = TileOffsByDiagDir(d); + Tile lower_tile = TileIndex(t) - delta; + Tile upper_tile = TileIndex(t) + delta; /* Keep the current waterclass and owner for the tiles. * It allows to restore them after the lock is deleted */ MakeLockTile(t, o, LOCK_PART_MIDDLE, d, wc_middle); - MakeLockTile(t - delta, IsWaterTile(t - delta) ? GetTileOwner(t - delta) : o, LOCK_PART_LOWER, d, wc_lower); - MakeLockTile(t + delta, IsWaterTile(t + delta) ? GetTileOwner(t + delta) : o, LOCK_PART_UPPER, d, wc_upper); + MakeLockTile(lower_tile, IsWaterTile(lower_tile) ? GetTileOwner(lower_tile) : o, LOCK_PART_LOWER, d, wc_lower); + MakeLockTile(upper_tile, IsWaterTile(upper_tile) ? GetTileOwner(upper_tile) : o, LOCK_PART_UPPER, d, wc_upper); } #endif /* WATER_MAP_H */ diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index da37a8b15aa7e..b04a570d2b4d7 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -191,6 +191,21 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis if (distant_join && (!_settings_game.station.distant_join_stations || !Waypoint::IsValidID(station_to_join))) return CMD_ERROR; + TileArea new_location(start_tile, width, height); + + /* only AddCost for non-existing waypoints */ + CommandCost cost(EXPENSES_CONSTRUCTION); + bool success = false; + for (TileIndex cur_tile : new_location) { + if (!IsRailWaypointTile(cur_tile)) { + cost.AddCost(_price[PR_BUILD_WAYPOINT_RAIL]); + success = true; + } + } + if (!success) { + return_cmd_error(STR_ERROR_ALREADY_BUILT); + } + /* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */ StationID est = INVALID_STATION; @@ -203,7 +218,6 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis } Waypoint *wp = nullptr; - TileArea new_location(start_tile, width, height); CommandCost ret = FindJoiningWaypoint(est, station_to_join, adjacent, new_location, &wp); if (ret.Failed()) return ret; @@ -217,11 +231,11 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis /* check if we want to expand an already existing waypoint? */ if (wp->train_station.tile != INVALID_TILE) { - CommandCost ret = CanExpandRailStation(wp, new_location, axis); + ret = CanExpandRailStation(wp, new_location, axis); if (ret.Failed()) return ret; } - CommandCost ret = wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TEST); + ret = wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TEST); if (ret.Failed()) return ret; } else { /* allocate and initialize new waypoint */ @@ -279,7 +293,7 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlag flags, TileIndex start_tile, Axis DirtyCompanyInfrastructureWindows(wp->owner); } - return CommandCost(EXPENSES_CONSTRUCTION, count * _price[PR_BUILD_WAYPOINT_RAIL]); + return cost; } /** diff --git a/src/waypoint_gui.cpp b/src/waypoint_gui.cpp index 4fca572242ec7..0d688b49d9665 100644 --- a/src/waypoint_gui.cpp +++ b/src/waypoint_gui.cpp @@ -27,6 +27,7 @@ #include "table/strings.h" #include "safeguards.h" +#include "zoom_func.h" /** GUI for accessing waypoints and buoys. */ struct WaypointWindow : Window { @@ -70,7 +71,7 @@ struct WaypointWindow : Window { this->flags |= WF_DISABLE_VP_SCROLL; NWidgetViewport *nvp = this->GetWidget(WID_W_VIEWPORT); - nvp->InitializeViewport(this, this->GetCenterTile(), ZOOM_LVL_VIEWPORT); + nvp->InitializeViewport(this, this->GetCenterTile(), ScaleZoomGUI(ZOOM_LVL_VIEWPORT)); this->OnInvalidateData(0); } diff --git a/src/widget.cpp b/src/widget.cpp index abd413ca28a39..6f679e2f47fbe 100644 --- a/src/widget.cpp +++ b/src/widget.cpp @@ -8,6 +8,7 @@ /** @file widget.cpp Handling of the default/simple widgets. */ #include "stdafx.h" +#include "core/backup_type.hpp" #include "company_func.h" #include "window_gui.h" #include "viewport_func.h" @@ -24,6 +25,211 @@ #include "safeguards.h" +/** Distances used in drawing widgets. */ +enum WidgetDrawDistances { + /* WWT_IMGBTN(_2) */ + WD_IMGBTN_LEFT = 1, ///< Left offset of the image in the button. + WD_IMGBTN_RIGHT = 2, ///< Right offset of the image in the button. + WD_IMGBTN_TOP = 1, ///< Top offset of image in the button. + WD_IMGBTN_BOTTOM = 2, ///< Bottom offset of image in the button. + + /* WWT_INSET */ + WD_INSET_LEFT = 2, ///< Left offset of string. + WD_INSET_RIGHT = 2, ///< Right offset of string. + WD_INSET_TOP = 1, ///< Top offset of string. + + WD_VSCROLLBAR_LEFT = 2, ///< Left offset of vertical scrollbar. + WD_VSCROLLBAR_RIGHT = 2, ///< Right offset of vertical scrollbar. + WD_VSCROLLBAR_TOP = 3, ///< Top offset of vertical scrollbar. + WD_VSCROLLBAR_BOTTOM = 3, ///< Bottom offset of vertical scrollbar. + + WD_HSCROLLBAR_LEFT = 3, ///< Left offset of horizontal scrollbar. + WD_HSCROLLBAR_RIGHT = 3, ///< Right offset of horizontal scrollbar. + WD_HSCROLLBAR_TOP = 2, ///< Top offset of horizontal scrollbar. + WD_HSCROLLBAR_BOTTOM = 2, ///< Bottom offset of horizontal scrollbar. + + /* Size of the pure frame bevel without any padding. */ + WD_BEVEL_LEFT = 1, ///< Width of left bevel border. + WD_BEVEL_RIGHT = 1, ///< Width of right bevel border. + WD_BEVEL_TOP = 1, ///< Height of top bevel border. + WD_BEVEL_BOTTOM = 1, ///< Height of bottom bevel border. + + /* FrameRect widgets, all text buttons, panel, editbox */ + WD_FRAMERECT_LEFT = 2, ///< Offset at left to draw the frame rectangular area + WD_FRAMERECT_RIGHT = 2, ///< Offset at right to draw the frame rectangular area + WD_FRAMERECT_TOP = 1, ///< Offset at top to draw the frame rectangular area + WD_FRAMERECT_BOTTOM = 1, ///< Offset at bottom to draw the frame rectangular area + + /* WWT_FRAME */ + WD_FRAMETEXT_LEFT = 6, ///< Left offset of the text of the frame. + WD_FRAMETEXT_RIGHT = 6, ///< Right offset of the text of the frame. + WD_FRAMETEXT_TOP = 6, ///< Top offset of the text of the frame + WD_FRAMETEXT_BOTTOM = 6, ///< Bottom offset of the text of the frame + + /* WWT_MATRIX */ + WD_MATRIX_LEFT = 2, ///< Offset at left of a matrix cell. + WD_MATRIX_RIGHT = 2, ///< Offset at right of a matrix cell. + WD_MATRIX_TOP = 3, ///< Offset at top of a matrix cell. + WD_MATRIX_BOTTOM = 1, ///< Offset at bottom of a matrix cell. + + /* WWT_SHADEBOX */ + WD_SHADEBOX_WIDTH = 12, ///< Width of a standard shade box widget. + WD_SHADEBOX_LEFT = 2, ///< Left offset of shade sprite. + WD_SHADEBOX_RIGHT = 2, ///< Right offset of shade sprite. + WD_SHADEBOX_TOP = 3, ///< Top offset of shade sprite. + WD_SHADEBOX_BOTTOM = 3, ///< Bottom offset of shade sprite. + + /* WWT_STICKYBOX */ + WD_STICKYBOX_WIDTH = 12, ///< Width of a standard sticky box widget. + WD_STICKYBOX_LEFT = 2, ///< Left offset of sticky sprite. + WD_STICKYBOX_RIGHT = 2, ///< Right offset of sticky sprite. + WD_STICKYBOX_TOP = 3, ///< Top offset of sticky sprite. + WD_STICKYBOX_BOTTOM = 3, ///< Bottom offset of sticky sprite. + + /* WWT_DEBUGBOX */ + WD_DEBUGBOX_WIDTH = 12, ///< Width of a standard debug box widget. + WD_DEBUGBOX_LEFT = 2, ///< Left offset of debug sprite. + WD_DEBUGBOX_RIGHT = 2, ///< Right offset of debug sprite. + WD_DEBUGBOX_TOP = 3, ///< Top offset of debug sprite. + WD_DEBUGBOX_BOTTOM = 3, ///< Bottom offset of debug sprite. + + /* WWT_DEFSIZEBOX */ + WD_DEFSIZEBOX_WIDTH = 12, ///< Width of a standard defsize box widget. + WD_DEFSIZEBOX_LEFT = 2, ///< Left offset of defsize sprite. + WD_DEFSIZEBOX_RIGHT = 2, ///< Right offset of defsize sprite. + WD_DEFSIZEBOX_TOP = 3, ///< Top offset of defsize sprite. + WD_DEFSIZEBOX_BOTTOM = 3, ///< Bottom offset of defsize sprite. + + /* WWT_RESIZEBOX */ + WD_RESIZEBOX_WIDTH = 12, ///< Width of a resize box widget. + WD_RESIZEBOX_LEFT = 2, ///< Left offset of resize sprite. + WD_RESIZEBOX_RIGHT = 2, ///< Right offset of resize sprite. + WD_RESIZEBOX_TOP = 2, ///< Top offset of resize sprite. + WD_RESIZEBOX_BOTTOM = 2, ///< Bottom offset of resize sprite. + + /* WWT_CLOSEBOX */ + WD_CLOSEBOX_WIDTH = 11, ///< Width of a close box widget. + WD_CLOSEBOX_LEFT = 2, ///< Left offset of closebox string. + WD_CLOSEBOX_RIGHT = 1, ///< Right offset of closebox string. + WD_CLOSEBOX_TOP = 2, ///< Top offset of closebox string. + WD_CLOSEBOX_BOTTOM = 2, ///< Bottom offset of closebox string. + + /* WWT_CAPTION */ + WD_CAPTION_HEIGHT = 14, ///< Height of a title bar. + WD_CAPTIONTEXT_LEFT = 2, ///< Offset of the caption text at the left. + WD_CAPTIONTEXT_RIGHT = 2, ///< Offset of the caption text at the right. + WD_CAPTIONTEXT_TOP = 2, ///< Offset of the caption text at the top. + WD_CAPTIONTEXT_BOTTOM = 2, ///< Offset of the caption text at the bottom. + + /* Dropdown widget. */ + WD_DROPDOWN_HEIGHT = 12, ///< Height of a drop down widget. + WD_DROPDOWNTEXT_LEFT = 2, ///< Left offset of the dropdown widget string. + WD_DROPDOWNTEXT_RIGHT = 2, ///< Right offset of the dropdown widget string. + WD_DROPDOWNTEXT_TOP = 1, ///< Top offset of the dropdown widget string. + WD_DROPDOWNTEXT_BOTTOM = 1, ///< Bottom offset of the dropdown widget string. + + WD_PAR_VSEP_NORMAL = 2, ///< Normal amount of vertical space between two paragraphs of text. + WD_PAR_VSEP_WIDE = 8, ///< Large amount of vertical space between two paragraphs of text. +}; + +const WidgetDimensions WidgetDimensions::unscaled = { + {WD_IMGBTN_LEFT, WD_IMGBTN_TOP, WD_IMGBTN_RIGHT, WD_IMGBTN_BOTTOM}, ///< imgbtn + {WD_INSET_LEFT, WD_INSET_TOP, WD_INSET_RIGHT, WD_BEVEL_BOTTOM}, ///< inset + {WD_VSCROLLBAR_LEFT, WD_VSCROLLBAR_TOP, WD_VSCROLLBAR_RIGHT, WD_VSCROLLBAR_BOTTOM}, ///< vscrollbar + {WD_HSCROLLBAR_LEFT, WD_HSCROLLBAR_TOP, WD_HSCROLLBAR_RIGHT, WD_HSCROLLBAR_BOTTOM}, ///< hscrollbar + {WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM}, ///< bevel + {WD_BEVEL_LEFT, WD_BEVEL_TOP, WD_BEVEL_RIGHT, WD_BEVEL_BOTTOM}, ///< fullbevel + {WD_FRAMERECT_LEFT, WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM}, ///< framerect + {WD_FRAMETEXT_LEFT, WD_FRAMETEXT_TOP, WD_FRAMETEXT_RIGHT, WD_FRAMETEXT_BOTTOM}, ///< frametext + {WD_MATRIX_LEFT, WD_MATRIX_TOP, WD_MATRIX_RIGHT, WD_MATRIX_BOTTOM}, ///< matrix + {WD_SHADEBOX_LEFT, WD_SHADEBOX_TOP, WD_SHADEBOX_RIGHT, WD_SHADEBOX_BOTTOM}, ///< shadebox + {WD_STICKYBOX_LEFT, WD_STICKYBOX_TOP, WD_STICKYBOX_RIGHT, WD_STICKYBOX_BOTTOM}, ///< stickybox + {WD_DEBUGBOX_LEFT, WD_DEBUGBOX_TOP, WD_DEBUGBOX_RIGHT, WD_DEBUGBOX_BOTTOM}, ///< debugbox + {WD_DEFSIZEBOX_LEFT, WD_DEFSIZEBOX_TOP, WD_DEFSIZEBOX_RIGHT, WD_DEFSIZEBOX_BOTTOM}, ///< defsizebox + {WD_RESIZEBOX_LEFT, WD_RESIZEBOX_TOP, WD_RESIZEBOX_RIGHT, WD_RESIZEBOX_BOTTOM}, ///< resizebox + {WD_CLOSEBOX_LEFT, WD_CLOSEBOX_TOP, WD_CLOSEBOX_RIGHT, WD_CLOSEBOX_BOTTOM}, ///< closebox + {WD_CAPTIONTEXT_LEFT, WD_CAPTIONTEXT_TOP, WD_CAPTIONTEXT_RIGHT, WD_CAPTIONTEXT_BOTTOM}, ///< captiontext + {WD_DROPDOWNTEXT_LEFT, WD_DROPDOWNTEXT_TOP, WD_DROPDOWNTEXT_RIGHT, WD_DROPDOWNTEXT_BOTTOM}, ///< dropdowntext + {20, 10, 20, 10}, ///< modalpopup + 1, ///< pressed + WD_PAR_VSEP_NORMAL, ///< vsep_normal + WD_PAR_VSEP_WIDE, ///< vsep_wide + 2, ///< hsep_normal + 6, ///< hsep_wide + 10, ///< hsep_indent +}; + +WidgetDimensions WidgetDimensions::scaled = {}; + +/** + * Scale a RectPadding to GUI zoom level. + * @param r RectPadding at ZOOM_LVL_BASE (traditional "normal" interface size). + * @return RectPadding at #ZOOM_LVL_GUI (current interface size). + */ +static inline RectPadding ScaleGUITrad(const RectPadding &r) +{ + return {(uint8)ScaleGUITrad(r.left), (uint8)ScaleGUITrad(r.top), (uint8)ScaleGUITrad(r.right), (uint8)ScaleGUITrad(r.bottom)}; +} + +/** + * Scale a Dimension to GUI zoom level. + * @param d Dimension at ZOOM_LVL_BASE (traditional "normal" interface size). + * @return Dimension at #ZOOM_LVL_GUI (current interface size). + */ +static inline Dimension ScaleGUITrad(const Dimension &dim) +{ + return {(uint)ScaleGUITrad(dim.width), (uint)ScaleGUITrad(dim.height)}; +} + +/** + * Scale sprite size for GUI. + * Offset is ignored. + */ +Dimension GetScaledSpriteSize(SpriteID sprid) +{ + Point offset; + Dimension d = GetSpriteSize(sprid, &offset, ZOOM_LVL_OUT_4X); + d.width -= offset.x; + d.height -= offset.y; + return ScaleGUITrad(d); +} + +/** + * Set up pre-scaled versions of Widget Dimensions. + */ +void SetupWidgetDimensions() +{ + WidgetDimensions::scaled.imgbtn = ScaleGUITrad(WidgetDimensions::unscaled.imgbtn); + WidgetDimensions::scaled.inset = ScaleGUITrad(WidgetDimensions::unscaled.inset); + WidgetDimensions::scaled.vscrollbar = ScaleGUITrad(WidgetDimensions::unscaled.vscrollbar); + WidgetDimensions::scaled.hscrollbar = ScaleGUITrad(WidgetDimensions::unscaled.hscrollbar); + if (_settings_client.gui.scale_bevels) { + WidgetDimensions::scaled.bevel = ScaleGUITrad(WidgetDimensions::unscaled.bevel); + } else { + WidgetDimensions::scaled.bevel = WidgetDimensions::unscaled.bevel; + } + WidgetDimensions::scaled.fullbevel = ScaleGUITrad(WidgetDimensions::unscaled.fullbevel); + WidgetDimensions::scaled.framerect = ScaleGUITrad(WidgetDimensions::unscaled.framerect); + WidgetDimensions::scaled.frametext = ScaleGUITrad(WidgetDimensions::unscaled.frametext); + WidgetDimensions::scaled.matrix = ScaleGUITrad(WidgetDimensions::unscaled.matrix); + WidgetDimensions::scaled.shadebox = ScaleGUITrad(WidgetDimensions::unscaled.shadebox); + WidgetDimensions::scaled.stickybox = ScaleGUITrad(WidgetDimensions::unscaled.stickybox); + WidgetDimensions::scaled.debugbox = ScaleGUITrad(WidgetDimensions::unscaled.debugbox); + WidgetDimensions::scaled.defsizebox = ScaleGUITrad(WidgetDimensions::unscaled.defsizebox); + WidgetDimensions::scaled.resizebox = ScaleGUITrad(WidgetDimensions::unscaled.resizebox); + WidgetDimensions::scaled.closebox = ScaleGUITrad(WidgetDimensions::unscaled.closebox); + WidgetDimensions::scaled.captiontext = ScaleGUITrad(WidgetDimensions::unscaled.captiontext); + WidgetDimensions::scaled.dropdowntext = ScaleGUITrad(WidgetDimensions::unscaled.dropdowntext); + WidgetDimensions::scaled.modalpopup = ScaleGUITrad(WidgetDimensions::unscaled.modalpopup); + + WidgetDimensions::scaled.pressed = ScaleGUITrad(WidgetDimensions::unscaled.pressed); + WidgetDimensions::scaled.vsep_normal = ScaleGUITrad(WidgetDimensions::unscaled.vsep_normal); + WidgetDimensions::scaled.vsep_wide = ScaleGUITrad(WidgetDimensions::unscaled.vsep_wide); + WidgetDimensions::scaled.hsep_normal = ScaleGUITrad(WidgetDimensions::unscaled.hsep_normal); + WidgetDimensions::scaled.hsep_wide = ScaleGUITrad(WidgetDimensions::unscaled.hsep_wide); + WidgetDimensions::scaled.hsep_indent = ScaleGUITrad(WidgetDimensions::unscaled.hsep_indent); +} + /** * Calculate x and y coordinates for an aligned object within a window. * @param r Rectangle of the widget to be drawn in. @@ -39,13 +245,13 @@ static inline Point GetAlignedPosition(const Rect &r, const Dimension &d, String switch (align & SA_HOR_MASK) { case SA_LEFT: p.x = r.left; break; case SA_HOR_CENTER: p.x = CenterBounds(r.left, r.right, d.width); break; - case SA_RIGHT: p.x = r.right - d.width; break; + case SA_RIGHT: p.x = r.right + 1 - d.width; break; default: NOT_REACHED(); } switch (align & SA_VERT_MASK) { case SA_TOP: p.y = r.top; break; case SA_VERT_CENTER: p.y = CenterBounds(r.top, r.bottom, d.height); break; - case SA_BOTTOM: p.y = r.bottom - d.height; break; + case SA_BOTTOM: p.y = r.bottom + 1 - d.height; break; default: NOT_REACHED(); } return p; @@ -220,25 +426,40 @@ void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, Fra } else { uint interior; + Rect outer = {left, top, right, bottom}; // Outside rectangle + Rect inner = outer.Shrink(WidgetDimensions::scaled.bevel); // Inside rectangle + if (flags & FR_LOWERED) { - GfxFillRect(left, top, left, bottom, dark); - GfxFillRect(left + WD_BEVEL_LEFT, top, right, top, dark); - GfxFillRect(right, top + WD_BEVEL_TOP, right, bottom - WD_BEVEL_BOTTOM, light); - GfxFillRect(left + WD_BEVEL_LEFT, bottom, right, bottom, light); + GfxFillRect(outer.left, outer.top, inner.left - 1, outer.bottom, dark); // Left + GfxFillRect(inner.left, outer.top, outer.right, inner.top - 1, dark); // Top + GfxFillRect(inner.right + 1, inner.top, outer.right, inner.bottom, light); // Right + GfxFillRect(inner.left, inner.bottom + 1, outer.right, outer.bottom, light); // Bottom interior = (flags & FR_DARKENED ? medium_dark : medium_light); } else { - GfxFillRect(left, top, left, bottom - WD_BEVEL_BOTTOM, light); - GfxFillRect(left + WD_BEVEL_LEFT, top, right - WD_BEVEL_RIGHT, top, light); - GfxFillRect(right, top, right, bottom - WD_BEVEL_BOTTOM, dark); - GfxFillRect(left, bottom, right, bottom, dark); + GfxFillRect(outer.left, outer.top, inner.left - 1, inner.bottom, light); // Left + GfxFillRect(inner.left, outer.top, inner.right, inner.top - 1, light); // Top + GfxFillRect(inner.right + 1, outer.top, outer.right, inner.bottom, dark); // Right + GfxFillRect(outer.left, inner.bottom + 1, outer.right, outer.bottom, dark); // Bottom interior = medium_dark; } if (!(flags & FR_BORDERONLY)) { - GfxFillRect(left + WD_BEVEL_LEFT, top + WD_BEVEL_TOP, right - WD_BEVEL_RIGHT, bottom - WD_BEVEL_BOTTOM, interior); + GfxFillRect(inner.left, inner.top, inner.right, inner.bottom, interior); // Inner } } } +void DrawSpriteIgnorePadding(SpriteID img, PaletteID pal, const Rect &r, bool clicked, StringAlignment align) +{ + Point offset; + Dimension d = GetSpriteSize(img, &offset); + d.width -= offset.x; + d.height -= offset.y; + + Point p = GetAlignedPosition(r, d, align); + int o = clicked ? WidgetDimensions::scaled.pressed : 0; + DrawSprite(img, pal, p.x + o - offset.x, p.y + o - offset.y); +} + /** * Draw an image button. * @param r Rectangle of the button. @@ -254,9 +475,7 @@ static inline void DrawImageButtons(const Rect &r, WidgetType type, Colours colo DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE); if ((type & WWT_MASK) == WWT_IMGBTN_2 && clicked) img++; // Show different image when clicked for #WWT_IMGBTN_2. - Dimension d = GetSpriteSize(img); - Point p = GetAlignedPosition(r, d, align); - DrawSprite(img, PAL_NONE, p.x + clicked, p.y + clicked); + DrawSpriteIgnorePadding(img, PAL_NONE, r, clicked, align); } /** @@ -274,7 +493,8 @@ static inline void DrawLabel(const Rect &r, WidgetType type, bool clicked, TextC if ((type & WWT_MASK) == WWT_TEXTBTN_2 && clicked) str++; Dimension d = GetStringBoundingBox(str); Point p = GetAlignedPosition(r, d, align); - DrawString(r.left + clicked, r.right + clicked, p.y + clicked, str, colour, align); + int o = clicked ? WidgetDimensions::scaled.pressed : 0; + DrawString(r.left + o, r.right + o, p.y + o, str, colour, align); } /** @@ -302,7 +522,7 @@ static inline void DrawText(const Rect &r, TextColour colour, StringID str, Stri static inline void DrawInset(const Rect &r, Colours colour, TextColour text_colour, StringID str, StringAlignment align) { DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_LOWERED | FR_DARKENED); - if (str != STR_NULL) DrawString(r.left + WD_INSET_LEFT, r.right - WD_INSET_RIGHT, r.top + WD_INSET_TOP, str, text_colour, align); + if (str != STR_NULL) DrawString(r.Shrink(WidgetDimensions::scaled.inset), str, text_colour, align); } /** @@ -322,18 +542,18 @@ static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint1 int column_width; // Width of a single column in the matrix. if (num_columns == 0) { column_width = resize_x; - num_columns = (r.right - r.left + 1) / column_width; + num_columns = r.Width() / column_width; } else { - column_width = (r.right - r.left + 1) / num_columns; + column_width = r.Width() / num_columns; } int num_rows = GB(data, MAT_ROW_START, MAT_ROW_BITS); // Upper 8 bits of the widget data: Number of rows in the matrix. int row_height; // Height of a single row in the matrix. if (num_rows == 0) { row_height = resize_y; - num_rows = (r.bottom - r.top + 1) / row_height; + num_rows = r.Height() / row_height; } else { - row_height = (r.bottom - r.top + 1) / num_rows; + row_height = r.Height() / num_rows; } int col = _colour_gradient[colour & 0xF][6]; @@ -341,13 +561,13 @@ static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint1 int x = r.left; for (int ctr = num_columns; ctr > 1; ctr--) { x += column_width; - GfxFillRect(x, r.top + 1, x, r.bottom - 1, col); + GfxFillRect(x, r.top + WidgetDimensions::scaled.bevel.top, x + WidgetDimensions::scaled.bevel.left - 1, r.bottom - WidgetDimensions::scaled.bevel.bottom, col); } x = r.top; for (int ctr = num_rows; ctr > 1; ctr--) { x += row_height; - GfxFillRect(r.left + 1, x, r.right - 1, x, col); + GfxFillRect(r.left + WidgetDimensions::scaled.bevel.left, x, r.right - WidgetDimensions::scaled.bevel.right, x + WidgetDimensions::scaled.bevel.top - 1, col); } col = _colour_gradient[colour & 0xF][4]; @@ -355,13 +575,13 @@ static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint1 x = r.left - 1; for (int ctr = num_columns; ctr > 1; ctr--) { x += column_width; - GfxFillRect(x, r.top + 1, x, r.bottom - 1, col); + GfxFillRect(x - WidgetDimensions::scaled.bevel.right + 1, r.top + WidgetDimensions::scaled.bevel.top, x, r.bottom - WidgetDimensions::scaled.bevel.bottom, col); } x = r.top - 1; for (int ctr = num_rows; ctr > 1; ctr--) { x += row_height; - GfxFillRect(r.left + 1, x, r.right - 1, x, col); + GfxFillRect(r.left + WidgetDimensions::scaled.bevel.left, x - WidgetDimensions::scaled.bevel.bottom + 1, r.right - WidgetDimensions::scaled.bevel.right, x, col); } } @@ -376,15 +596,11 @@ static inline void DrawMatrix(const Rect &r, Colours colour, bool clicked, uint1 */ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_clicked, bool bar_dragged, bool down_clicked, const Scrollbar *scrollbar) { - int centre = (r.right - r.left) / 2; int height = NWidgetScrollbar::GetVerticalDimension().height; /* draw up/down buttons */ - DrawFrameRect(r.left, r.top, r.right, r.top + height - 1, colour, (up_clicked) ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_UP, PAL_NONE, r.left + 1 + up_clicked, r.top + 1 + up_clicked); - - DrawFrameRect(r.left, r.bottom - (height - 1), r.right, r.bottom, colour, (down_clicked) ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.left + 1 + down_clicked, r.bottom - (height - 2) + down_clicked); + DrawImageButtons(r.WithHeight(height, false), NWID_VSCROLLBAR, colour, up_clicked, SPR_ARROW_UP, SA_CENTER); + DrawImageButtons(r.WithHeight(height, true), NWID_VSCROLLBAR, colour, down_clicked, SPR_ARROW_DOWN, SA_CENTER); int c1 = _colour_gradient[colour & 0xF][3]; int c2 = _colour_gradient[colour & 0xF][7]; @@ -393,11 +609,17 @@ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_ GfxFillRect(r.left, r.top + height, r.right, r.bottom - height, c2); GfxFillRect(r.left, r.top + height, r.right, r.bottom - height, c1, FILLRECT_CHECKER); + /* track positions. These fractions are based on original 1x dimensions, but scale better. */ + int left = r.left + r.Width() * 3 / 11; /* left track is positioned 3/11ths from the left */ + int right = r.left + r.Width() * 8 / 11; /* right track is positioned 8/11ths from the left */ + const uint8 bl = WidgetDimensions::scaled.bevel.left; + const uint8 br = WidgetDimensions::scaled.bevel.right; + /* draw shaded lines */ - GfxFillRect(r.left + centre - 3, r.top + height, r.left + centre - 3, r.bottom - height, c1); - GfxFillRect(r.left + centre - 2, r.top + height, r.left + centre - 2, r.bottom - height, c2); - GfxFillRect(r.left + centre + 2, r.top + height, r.left + centre + 2, r.bottom - height, c1); - GfxFillRect(r.left + centre + 3, r.top + height, r.left + centre + 3, r.bottom - height, c2); + GfxFillRect(left - bl, r.top + height, left - 1, r.bottom - height, c1); + GfxFillRect(left, r.top + height, left + br - 1, r.bottom - height, c2); + GfxFillRect(right - bl, r.top + height, right - 1, r.bottom - height, c1); + GfxFillRect(right, r.top + height, right + br - 1, r.bottom - height, c2); Point pt = HandleScrollbarHittest(scrollbar, r.top, r.bottom, false); DrawFrameRect(r.left, pt.x, r.right, pt.y, colour, bar_dragged ? FR_LOWERED : FR_NONE); @@ -414,14 +636,10 @@ static inline void DrawVerticalScrollbar(const Rect &r, Colours colour, bool up_ */ static inline void DrawHorizontalScrollbar(const Rect &r, Colours colour, bool left_clicked, bool bar_dragged, bool right_clicked, const Scrollbar *scrollbar) { - int centre = (r.bottom - r.top) / 2; int width = NWidgetScrollbar::GetHorizontalDimension().width; - DrawFrameRect(r.left, r.top, r.left + width - 1, r.bottom, colour, left_clicked ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_LEFT, PAL_NONE, r.left + 1 + left_clicked, r.top + 1 + left_clicked); - - DrawFrameRect(r.right - (width - 1), r.top, r.right, r.bottom, colour, right_clicked ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_RIGHT, PAL_NONE, r.right - (width - 2) + right_clicked, r.top + 1 + right_clicked); + DrawImageButtons(r.WithWidth(width, false), NWID_HSCROLLBAR, colour, left_clicked, SPR_ARROW_LEFT, SA_CENTER); + DrawImageButtons(r.WithWidth(width, true), NWID_HSCROLLBAR, colour, right_clicked, SPR_ARROW_RIGHT, SA_CENTER); int c1 = _colour_gradient[colour & 0xF][3]; int c2 = _colour_gradient[colour & 0xF][7]; @@ -430,11 +648,17 @@ static inline void DrawHorizontalScrollbar(const Rect &r, Colours colour, bool l GfxFillRect(r.left + width, r.top, r.right - width, r.bottom, c2); GfxFillRect(r.left + width, r.top, r.right - width, r.bottom, c1, FILLRECT_CHECKER); + /* track positions. These fractions are based on original 1x dimensions, but scale better. */ + int top = r.top + r.Height() * 3 / 11; /* top track is positioned 3/11ths from the top */ + int bottom = r.top + r.Height() * 8 / 11; /* bottom track is positioned 8/11ths from the top */ + const uint8 bt = WidgetDimensions::scaled.bevel.top; + const uint8 bb = WidgetDimensions::scaled.bevel.bottom; + /* draw shaded lines */ - GfxFillRect(r.left + width, r.top + centre - 3, r.right - width, r.top + centre - 3, c1); - GfxFillRect(r.left + width, r.top + centre - 2, r.right - width, r.top + centre - 2, c2); - GfxFillRect(r.left + width, r.top + centre + 2, r.right - width, r.top + centre + 2, c1); - GfxFillRect(r.left + width, r.top + centre + 3, r.right - width, r.top + centre + 3, c2); + GfxFillRect(r.left + width, top - bt, r.right - width, top - 1, c1); + GfxFillRect(r.left + width, top, r.right - width, top + bb - 1, c2); + GfxFillRect(r.left + width, bottom - bt, r.right - width, bottom - 1, c1); + GfxFillRect(r.left + width, bottom, r.right - width, bottom + bb - 1, c2); /* draw actual scrollbar */ Point pt = HandleScrollbarHittest(scrollbar, r.left, r.right, true); @@ -453,44 +677,47 @@ static inline void DrawFrame(const Rect &r, Colours colour, TextColour text_colo { int x2 = r.left; // by default the left side is the left side of the widget - if (str != STR_NULL) x2 = DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top, str, text_colour, align); + if (str != STR_NULL) x2 = DrawString(r.left + WidgetDimensions::scaled.frametext.left, r.right - WidgetDimensions::scaled.frametext.right, r.top, str, text_colour, align); int c1 = _colour_gradient[colour][3]; int c2 = _colour_gradient[colour][7]; /* If the frame has text, adjust the top bar to fit half-way through */ - int dy1 = 4; - if (str != STR_NULL) dy1 = FONT_HEIGHT_NORMAL / 2 - 1; - int dy2 = dy1 + 1; + Rect inner = r.Shrink(ScaleGUITrad(1)); + if (str != STR_NULL) inner.top = r.top + FONT_HEIGHT_NORMAL / 2; + + Rect outer = inner.Expand(WidgetDimensions::scaled.bevel); + Rect inside = inner.Shrink(WidgetDimensions::scaled.bevel); if (_current_text_dir == TD_LTR) { /* Line from upper left corner to start of text */ - GfxFillRect(r.left, r.top + dy1, r.left + 4, r.top + dy1, c1); - GfxFillRect(r.left + 1, r.top + dy2, r.left + 4, r.top + dy2, c2); + GfxFillRect(outer.left, outer.top, r.left + WidgetDimensions::scaled.frametext.left - WidgetDimensions::scaled.bevel.left - 1, inner.top - 1, c1); + GfxFillRect(inner.left, inner.top, r.left + WidgetDimensions::scaled.frametext.left - WidgetDimensions::scaled.bevel.left - 1, inside.top - 1, c2); /* Line from end of text to upper right corner */ - GfxFillRect(x2, r.top + dy1, r.right - 1, r.top + dy1, c1); - GfxFillRect(x2, r.top + dy2, r.right - 2, r.top + dy2, c2); + GfxFillRect(x2 + WidgetDimensions::scaled.bevel.right, outer.top, inner.right, inner.top - 1, c1); + GfxFillRect(x2 + WidgetDimensions::scaled.bevel.right, inner.top, inside.right, inside.top - 1, c2); } else { /* Line from upper left corner to start of text */ - GfxFillRect(r.left, r.top + dy1, x2 - 2, r.top + dy1, c1); - GfxFillRect(r.left + 1, r.top + dy2, x2 - 2, r.top + dy2, c2); + GfxFillRect(outer.left, outer.top, x2 - WidgetDimensions::scaled.bevel.left - 1, inner.top - 1, c1); + GfxFillRect(inner.left, inner.top, x2 - WidgetDimensions::scaled.bevel.left - 1, inside.top - 1, c2); /* Line from end of text to upper right corner */ - GfxFillRect(r.right - 5, r.top + dy1, r.right - 1, r.top + dy1, c1); - GfxFillRect(r.right - 5, r.top + dy2, r.right - 2, r.top + dy2, c2); + GfxFillRect(r.right - WidgetDimensions::scaled.frametext.right + WidgetDimensions::scaled.bevel.right, outer.top, inner.right, inner.top - 1, c1); + GfxFillRect(r.right - WidgetDimensions::scaled.frametext.right + WidgetDimensions::scaled.bevel.right, inner.top, inside.right, inside.top - 1, c2); } /* Line from upper left corner to bottom left corner */ - GfxFillRect(r.left, r.top + dy2, r.left, r.bottom - 1, c1); - GfxFillRect(r.left + 1, r.top + dy2 + 1, r.left + 1, r.bottom - 2, c2); + GfxFillRect(outer.left, inner.top, inner.left - 1, inner.bottom, c1); + GfxFillRect(inner.left, inside.top, inside.left - 1, inside.bottom, c2); /* Line from upper right corner to bottom right corner */ - GfxFillRect(r.right - 1, r.top + dy2, r.right - 1, r.bottom - 2, c1); - GfxFillRect(r.right, r.top + dy1, r.right, r.bottom - 1, c2); + GfxFillRect(inside.right + 1, inner.top, inner.right, inside.bottom, c1); + GfxFillRect(inner.right + 1, outer.top, outer.right, inner.bottom, c2); - GfxFillRect(r.left + 1, r.bottom - 1, r.right - 1, r.bottom - 1, c1); - GfxFillRect(r.left, r.bottom, r.right, r.bottom, c2); + /* Line from bottom left corner to bottom right corner */ + GfxFillRect(inner.left, inside.bottom + 1, inner.right, inner.bottom, c1); + GfxFillRect(outer.left, inner.bottom + 1, outer.right, outer.bottom, c2); } /** @@ -547,28 +774,23 @@ static inline void DrawDebugBox(const Rect &r, Colours colour, bool clicked) static inline void DrawResizeBox(const Rect &r, Colours colour, bool at_left, bool clicked) { DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, (clicked) ? FR_LOWERED : FR_NONE); - if (at_left) { - Dimension d = GetSpriteSize(SPR_WINDOW_RESIZE_LEFT); - DrawSprite(SPR_WINDOW_RESIZE_LEFT, PAL_NONE, r.left + WD_RESIZEBOX_RIGHT + clicked, - r.bottom + 1 - WD_RESIZEBOX_BOTTOM - d.height + clicked); - } else { - Dimension d = GetSpriteSize(SPR_WINDOW_RESIZE_RIGHT); - DrawSprite(SPR_WINDOW_RESIZE_RIGHT, PAL_NONE, r.right + 1 - WD_RESIZEBOX_RIGHT - d.width + clicked, - r.bottom + 1 - WD_RESIZEBOX_BOTTOM - d.height + clicked); - } + DrawSpriteIgnorePadding(at_left ? SPR_WINDOW_RESIZE_LEFT : SPR_WINDOW_RESIZE_RIGHT, PAL_NONE, r.Shrink(ScaleGUITrad(2)), clicked, at_left ? (SA_LEFT | SA_BOTTOM | SA_FORCE) : (SA_RIGHT | SA_BOTTOM | SA_FORCE)); } /** * Draw a close box. - * @param r Rectangle of the box. + * @param r Rectangle of the box.` * @param colour Colour of the close box. */ static inline void DrawCloseBox(const Rect &r, Colours colour) { if (colour != COLOUR_WHITE) DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_NONE); - Dimension d = GetSpriteSize(SPR_CLOSEBOX); - int s = UnScaleGUI(1); /* Offset to account for shadow of SPR_CLOSEBOX */ - DrawSprite(SPR_CLOSEBOX, (colour != COLOUR_WHITE ? TC_BLACK : TC_SILVER) | (1 << PALETTE_TEXT_RECOLOUR), CenterBounds(r.left, r.right, d.width - s), CenterBounds(r.top, r.bottom, d.height - s)); + Point offset; + Dimension d = GetSpriteSize(SPR_CLOSEBOX, &offset); + d.width -= offset.x; + d.height -= offset.y; + int s = ScaleSpriteTrad(1); /* Offset to account for shadow of SPR_CLOSEBOX */ + DrawSprite(SPR_CLOSEBOX, (colour != COLOUR_WHITE ? TC_BLACK : TC_SILVER) | (1U << PALETTE_TEXT_RECOLOUR), CenterBounds(r.left, r.right, d.width - s) - offset.x, CenterBounds(r.top, r.bottom, d.height - s) - offset.y); } /** @@ -584,17 +806,18 @@ void DrawCaption(const Rect &r, Colours colour, Owner owner, TextColour text_col { bool company_owned = owner < MAX_COMPANIES; - DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, FR_BORDERONLY); - DrawFrameRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, colour, company_owned ? FR_LOWERED | FR_DARKENED | FR_BORDERONLY : FR_LOWERED | FR_DARKENED); + DrawFrameRect(r, colour, FR_BORDERONLY); + Rect ir = r.Shrink(WidgetDimensions::scaled.bevel); + DrawFrameRect(ir, colour, company_owned ? FR_LOWERED | FR_DARKENED | FR_BORDERONLY : FR_LOWERED | FR_DARKENED); if (company_owned) { - GfxFillRect(r.left + 2, r.top + 2, r.right - 2, r.bottom - 2, _colour_gradient[_company_colours[owner]][4]); + GfxFillRect(ir.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[_company_colours[owner]][4]); } if (str != STR_NULL) { Dimension d = GetStringBoundingBox(str); Point p = GetAlignedPosition(r, d, align); - DrawString(r.left + WD_CAPTIONTEXT_LEFT, r.right - WD_CAPTIONTEXT_RIGHT, p.y, str, text_colour, align); + DrawString(r.left + WidgetDimensions::scaled.captiontext.left, r.right - WidgetDimensions::scaled.captiontext.left, p.y, str, text_colour, align); } } @@ -611,22 +834,22 @@ void DrawCaption(const Rect &r, Colours colour, Owner owner, TextColour text_col */ static inline void DrawButtonDropdown(const Rect &r, Colours colour, bool clicked_button, bool clicked_dropdown, StringID str, StringAlignment align) { - int text_offset = std::max(0, ((int)(r.bottom - r.top + 1) - FONT_HEIGHT_NORMAL) / 2); // Offset for rendering the text vertically centered - int dd_width = NWidgetLeaf::dropdown_dimension.width; - int dd_height = NWidgetLeaf::dropdown_dimension.height; - int image_offset = std::max(0, ((int)(r.bottom - r.top + 1) - dd_height) / 2); if (_current_text_dir == TD_LTR) { DrawFrameRect(r.left, r.top, r.right - dd_width, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE); - DrawFrameRect(r.right + 1 - dd_width, r.top, r.right, r.bottom, colour, clicked_dropdown ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.right - (dd_width - 2) + clicked_dropdown, r.top + image_offset + clicked_dropdown); - if (str != STR_NULL) DrawString(r.left + WD_DROPDOWNTEXT_LEFT + clicked_button, r.right - dd_width - WD_DROPDOWNTEXT_RIGHT + clicked_button, r.top + text_offset + clicked_button, str, TC_BLACK, align); + DrawImageButtons(r.WithWidth(dd_width, true), WWT_DROPDOWN, colour, clicked_dropdown, SPR_ARROW_DOWN, SA_CENTER); + if (str != STR_NULL) { + int o = clicked_button ? WidgetDimensions::scaled.pressed : 0; + DrawString(r.left + WidgetDimensions::scaled.dropdowntext.left + o, r.right - dd_width - WidgetDimensions::scaled.dropdowntext.right + o, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL) + o, str, TC_BLACK, align); + } } else { DrawFrameRect(r.left + dd_width, r.top, r.right, r.bottom, colour, clicked_button ? FR_LOWERED : FR_NONE); - DrawFrameRect(r.left, r.top, r.left + dd_width - 1, r.bottom, colour, clicked_dropdown ? FR_LOWERED : FR_NONE); - DrawSprite(SPR_ARROW_DOWN, PAL_NONE, r.left + 1 + clicked_dropdown, r.top + image_offset + clicked_dropdown); - if (str != STR_NULL) DrawString(r.left + dd_width + WD_DROPDOWNTEXT_LEFT + clicked_button, r.right - WD_DROPDOWNTEXT_RIGHT + clicked_button, r.top + text_offset + clicked_button, str, TC_BLACK, align); + DrawImageButtons(r.WithWidth(dd_width, false), WWT_DROPDOWN, colour, clicked_dropdown, SPR_ARROW_DOWN, SA_CENTER); + if (str != STR_NULL) { + int o = clicked_button ? WidgetDimensions::scaled.pressed : 0; + DrawString(r.left + dd_width + WidgetDimensions::scaled.dropdowntext.left + o, r.right - WidgetDimensions::scaled.dropdowntext.right + o, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL) + o, str, TC_BLACK, align); + } } } @@ -647,17 +870,15 @@ void Window::DrawWidgets() const const NWidgetBase *widget = this->GetWidget(i); if (widget == nullptr || !widget->IsHighlighted()) continue; - int left = widget->pos_x; - int top = widget->pos_y; - int right = left + widget->current_x - 1; - int bottom = top + widget->current_y - 1; + Rect outer = widget->GetCurrentRect(); + Rect inner = outer.Shrink(WidgetDimensions::scaled.bevel).Expand(1); int colour = _string_colourmap[_window_highlight_colour ? widget->GetHighlightColour() : TC_WHITE]; - GfxFillRect(left, top, left, bottom - WD_BEVEL_BOTTOM, colour); - GfxFillRect(left + WD_BEVEL_LEFT, top, right - WD_BEVEL_RIGHT, top, colour); - GfxFillRect(right, top, right, bottom - WD_BEVEL_BOTTOM, colour); - GfxFillRect(left, bottom, right, bottom, colour); + GfxFillRect(outer.left, outer.top, inner.left, inner.bottom, colour); + GfxFillRect(inner.left + 1, outer.top, inner.right - 1, inner.top, colour); + GfxFillRect(inner.right, outer.top, outer.right, inner.bottom, colour); + GfxFillRect(outer.left + 1, inner.bottom, outer.right - 1, outer.bottom, colour); } } } @@ -672,15 +893,12 @@ void Window::DrawSortButtonState(int widget, SortButtonState state) const if (state == SBS_OFF) return; assert(this->nested_array != nullptr); - const NWidgetBase *nwid = this->GetWidget(widget); + Rect r = this->GetWidget(widget)->GetCurrentRect(); /* Sort button uses the same sprites as vertical scrollbar */ Dimension dim = NWidgetScrollbar::GetVerticalDimension(); - int offset = this->IsWidgetLowered(widget) ? 1 : 0; - int x = offset + nwid->pos_x + (_current_text_dir == TD_LTR ? nwid->current_x - dim.width : 0); - int y = offset + nwid->pos_y + (nwid->current_y - dim.height) / 2; - DrawSprite(state == SBS_DOWN ? SPR_ARROW_DOWN : SPR_ARROW_UP, PAL_NONE, x, y); + DrawSpriteIgnorePadding(state == SBS_DOWN ? SPR_ARROW_DOWN : SPR_ARROW_UP, PAL_NONE, r.WithWidth(dim.width, _current_text_dir == TD_LTR), this->IsWidgetLowered(widget), SA_CENTER); } /** @@ -831,10 +1049,7 @@ NWidgetBase *NWidgetBase::GetWidgetOfType(WidgetType tp) void NWidgetBase::AdjustPaddingForZoom() { - this->padding_top = ScaleGUITrad(this->uz_padding_top); - this->padding_right = ScaleGUITrad(this->uz_padding_right); - this->padding_bottom = ScaleGUITrad(this->uz_padding_bottom); - this->padding_left = ScaleGUITrad(this->uz_padding_left); + this->padding = ScaleGUITrad(this->uz_padding); } /** @@ -886,7 +1101,7 @@ void NWidgetResizeBase::SetMinimalSizeAbsolute(uint min_x, uint min_y) /** * Set minimal text lines for the widget. * @param min_lines Number of text lines of the widget. - * @param spacing Extra spacing (eg WD_FRAMERECT_TOP + _BOTTOM) of the widget. + * @param spacing Extra unscaled spacing (eg WidgetDimensions::unscaled.framerect.Vertical()) of the widget. * @param size Font size of text. */ void NWidgetResizeBase::SetMinimalTextLines(uint8 min_lines, uint8 spacing, FontSize size) @@ -940,7 +1155,7 @@ NWidgetCore::NWidgetCore(WidgetType tp, Colours colour, uint fill_x, uint fill_y this->widget_data = widget_data; this->tool_tip = tool_tip; this->scrollbar_index = -1; - this->text_colour = TC_FROMSTRING; + this->text_colour = TC_BLACK; this->align = SA_CENTER; } @@ -1124,8 +1339,8 @@ void NWidgetStacked::SetupSmallestSize(Window *w, bool init_array) for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); - this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); + this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal()); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical()); this->fill_x = LeastCommonMultiple(this->fill_x, child_wid->fill_x); this->fill_y = LeastCommonMultiple(this->fill_y, child_wid->fill_y); this->resize_x = LeastCommonMultiple(this->resize_x, child_wid->resize_x); @@ -1142,12 +1357,12 @@ void NWidgetStacked::AssignSizePosition(SizingType sizing, uint x, uint y, uint for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { uint hor_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetHorizontalStepSize(sizing); - uint child_width = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding_left - child_wid->padding_right, hor_step); - uint child_pos_x = (rtl ? child_wid->padding_right : child_wid->padding_left); + uint child_width = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding.Horizontal(), hor_step); + uint child_pos_x = (rtl ? child_wid->padding.right : child_wid->padding.left); uint vert_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetVerticalStepSize(sizing); - uint child_height = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding_top - child_wid->padding_bottom, vert_step); - uint child_pos_y = child_wid->padding_top; + uint child_height = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding.Vertical(), vert_step); + uint child_pos_y = child_wid->padding.top; child_wid->AssignSizePosition(sizing, x + child_pos_x, y + child_pos_y, child_width, child_height, rtl); } @@ -1269,7 +1484,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) child_wid->SetupSmallestSize(w, init_array); longest = std::max(longest, child_wid->smallest_x); max_vert_fill = std::max(max_vert_fill, child_wid->GetVerticalStepSize(ST_SMALLEST)); - this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); + this->smallest_y = std::max(this->smallest_y, child_wid->smallest_y + child_wid->padding.Vertical()); } /* 1b. Make the container higher if needed to accommodate all children nicely. */ [[maybe_unused]] uint max_smallest = this->smallest_y + 3 * max_vert_fill; // Upper limit to computing smallest height. @@ -1277,7 +1492,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) for (;;) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { uint step_size = child_wid->GetVerticalStepSize(ST_SMALLEST); - uint child_height = child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom; + uint child_height = child_wid->smallest_y + child_wid->padding.Vertical(); if (step_size > 1 && child_height < cur_height) { // Small step sizes or already fitting children are not interesting. uint remainder = (cur_height - child_height) % step_size; if (remainder > 0) { // Child did not fit entirely, widen the container. @@ -1297,15 +1512,15 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) } } /* 3. Move PIP space to the children, compute smallest, fill, and resize values of the container. */ - if (this->head != nullptr) this->head->padding_left += this->pip_pre; + if (this->head != nullptr) this->head->padding.left += this->pip_pre; for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (child_wid->next != nullptr) { - child_wid->padding_right += this->pip_inter; + child_wid->padding.right += this->pip_inter; } else { - child_wid->padding_right += this->pip_post; + child_wid->padding.right += this->pip_post; } - this->smallest_x += child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right; + this->smallest_x += child_wid->smallest_x + child_wid->padding.Horizontal(); if (child_wid->fill_x > 0) { if (this->fill_x == 0 || this->fill_x > child_wid->fill_x) this->fill_x = child_wid->fill_x; } @@ -1329,7 +1544,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) { /* For EQUALSIZE containers this does not sum to smallest_x during initialisation */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { - additional_length -= child_wid->smallest_x + child_wid->padding_right + child_wid->padding_left; + additional_length -= child_wid->smallest_x + child_wid->padding.Horizontal(); } } else { additional_length -= this->smallest_x; @@ -1356,14 +1571,24 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { uint hor_step = child_wid->GetHorizontalStepSize(sizing); if (hor_step > 0) { - num_changing_childs++; + if (!(flags & NC_BIGFIRST)) num_changing_childs++; biggest_stepsize = std::max(biggest_stepsize, hor_step); } else { child_wid->current_x = child_wid->smallest_x; } uint vert_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetVerticalStepSize(sizing); - child_wid->current_y = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding_top - child_wid->padding_bottom, vert_step); + child_wid->current_y = ComputeMaxSize(child_wid->smallest_y, given_height - child_wid->padding.Vertical(), vert_step); + } + + /* First.5 loop: count how many children are of the biggest step size. */ + if ((flags & NC_BIGFIRST) && biggest_stepsize > 0) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { + uint hor_step = child_wid->GetHorizontalStepSize(sizing); + if (hor_step == biggest_stepsize) { + num_changing_childs++; + } + } } /* Second loop: Allocate the additional horizontal space over the resizing children, starting with the biggest resize steps. */ @@ -1383,6 +1608,16 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui next_biggest_stepsize = std::max(next_biggest_stepsize, hor_step); } biggest_stepsize = next_biggest_stepsize; + + if (num_changing_childs == 0 && (flags & NC_BIGFIRST) && biggest_stepsize > 0) { + /* Second.5 loop: count how many children are of the updated biggest step size. */ + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { + uint hor_step = child_wid->GetHorizontalStepSize(sizing); + if (hor_step == biggest_stepsize) { + num_changing_childs++; + } + } + } } assert(num_changing_childs == 0); @@ -1391,11 +1626,11 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui NWidgetBase *child_wid = this->head; while (child_wid != nullptr) { uint child_width = child_wid->current_x; - uint child_x = x + (rtl ? position - child_width - child_wid->padding_left : position + child_wid->padding_left); - uint child_y = y + child_wid->padding_top; + uint child_x = x + (rtl ? position - child_width - child_wid->padding.left : position + child_wid->padding.left); + uint child_y = y + child_wid->padding.top; child_wid->AssignSizePosition(sizing, child_x, child_y, child_width, child_wid->current_y, rtl); - uint padded_child_width = child_width + child_wid->padding_right + child_wid->padding_left; + uint padded_child_width = child_width + child_wid->padding.Horizontal(); position = rtl ? position - padded_child_width : position + padded_child_width; child_wid = child_wid->next; @@ -1434,7 +1669,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) child_wid->SetupSmallestSize(w, init_array); highest = std::max(highest, child_wid->smallest_y); max_hor_fill = std::max(max_hor_fill, child_wid->GetHorizontalStepSize(ST_SMALLEST)); - this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right); + this->smallest_x = std::max(this->smallest_x, child_wid->smallest_x + child_wid->padding.Horizontal()); } /* 1b. Make the container wider if needed to accommodate all children nicely. */ [[maybe_unused]] uint max_smallest = this->smallest_x + 3 * max_hor_fill; // Upper limit to computing smallest height. @@ -1442,7 +1677,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) for (;;) { for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { uint step_size = child_wid->GetHorizontalStepSize(ST_SMALLEST); - uint child_width = child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right; + uint child_width = child_wid->smallest_x + child_wid->padding.Horizontal(); if (step_size > 1 && child_width < cur_width) { // Small step sizes or already fitting children are not interesting. uint remainder = (cur_width - child_width) % step_size; if (remainder > 0) { // Child did not fit entirely, widen the container. @@ -1462,15 +1697,15 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) } } /* 3. Move PIP space to the child, compute smallest, fill, and resize values of the container. */ - if (this->head != nullptr) this->head->padding_top += this->pip_pre; + if (this->head != nullptr) this->head->padding.top += this->pip_pre; for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (child_wid->next != nullptr) { - child_wid->padding_bottom += this->pip_inter; + child_wid->padding.bottom += this->pip_inter; } else { - child_wid->padding_bottom += this->pip_post; + child_wid->padding.bottom += this->pip_post; } - this->smallest_y += child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom; + this->smallest_y += child_wid->smallest_y + child_wid->padding.Vertical(); if (child_wid->fill_y > 0) { if (this->fill_y == 0 || this->fill_y > child_wid->fill_y) this->fill_y = child_wid->fill_y; } @@ -1494,7 +1729,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint if (sizing == ST_SMALLEST && (this->flags & NC_EQUALSIZE)) { /* For EQUALSIZE containers this does not sum to smallest_y during initialisation */ for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { - additional_length -= child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom; + additional_length -= child_wid->smallest_y + child_wid->padding.Vertical(); } } else { additional_length -= this->smallest_y; @@ -1512,14 +1747,24 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { uint vert_step = child_wid->GetVerticalStepSize(sizing); if (vert_step > 0) { - num_changing_childs++; + if (!(flags & NC_BIGFIRST)) num_changing_childs++; biggest_stepsize = std::max(biggest_stepsize, vert_step); } else { child_wid->current_y = child_wid->smallest_y; } uint hor_step = (sizing == ST_SMALLEST) ? 1 : child_wid->GetHorizontalStepSize(sizing); - child_wid->current_x = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding_left - child_wid->padding_right, hor_step); + child_wid->current_x = ComputeMaxSize(child_wid->smallest_x, given_width - child_wid->padding.Horizontal(), hor_step); + } + + /* First.5 loop: count how many children are of the biggest step size. */ + if ((this->flags & NC_BIGFIRST) && biggest_stepsize > 0) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { + uint vert_step = child_wid->GetVerticalStepSize(sizing); + if (vert_step == biggest_stepsize) { + num_changing_childs++; + } + } } /* Second loop: Allocate the additional vertical space over the resizing children, starting with the biggest resize steps. */ @@ -1539,17 +1784,27 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint next_biggest_stepsize = std::max(next_biggest_stepsize, vert_step); } biggest_stepsize = next_biggest_stepsize; + + if (num_changing_childs == 0 && (flags & NC_BIGFIRST) && biggest_stepsize > 0) { + /* Second.5 loop: count how many children are of the updated biggest step size. */ + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { + uint vert_step = child_wid->GetVerticalStepSize(sizing); + if (vert_step == biggest_stepsize) { + num_changing_childs++; + } + } + } } assert(num_changing_childs == 0); /* Third loop: Compute position and call the child. */ uint position = 0; // Place to put next child relative to origin of the container. for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { - uint child_x = x + (rtl ? child_wid->padding_right : child_wid->padding_left); + uint child_x = x + (rtl ? child_wid->padding.right : child_wid->padding.left); uint child_height = child_wid->current_y; - child_wid->AssignSizePosition(sizing, child_x, y + position + child_wid->padding_top, child_wid->current_x, child_height, rtl); - position += child_height + child_wid->padding_top + child_wid->padding_bottom; + child_wid->AssignSizePosition(sizing, child_x, y + position + child_wid->padding.top, child_wid->current_x, child_height, rtl); + position += child_height + child_wid->padding.Vertical(); } } @@ -1755,8 +2010,7 @@ NWidgetCore *NWidgetMatrix::GetWidgetFromPos(int x, int y) bool rtl = _current_text_dir == TD_RTL; DrawPixelInfo tmp_dpi; if (!FillDrawPixelInfo(&tmp_dpi, this->pos_x + (rtl ? this->pip_post : this->pip_pre), this->pos_y + this->pip_pre, this->current_x - this->pip_pre - this->pip_post, this->current_y - this->pip_pre - this->pip_post)) return; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &tmp_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi); /* Get the appropriate offsets so we can draw the right widgets. */ NWidgetCore *child = dynamic_cast(this->head); @@ -1789,9 +2043,6 @@ NWidgetCore *NWidgetMatrix::GetWidgetFromPos(int x, int y) child->Draw(w); } } - - /* Restore the clipping area. */ - _cur_dpi = old_dpi; } /** @@ -1905,25 +2156,20 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array) if (this->type == WWT_FRAME) { /* Account for the size of the frame's text if that exists */ - this->child->padding_left = WD_FRAMETEXT_LEFT; - this->child->padding_right = WD_FRAMETEXT_RIGHT; - this->child->padding_top = std::max((int)WD_FRAMETEXT_TOP, this->widget_data != STR_NULL ? FONT_HEIGHT_NORMAL + WD_FRAMETEXT_TOP / 2 : 0); - this->child->padding_bottom = WD_FRAMETEXT_BOTTOM; + this->child->padding = WidgetDimensions::scaled.frametext; + this->child->padding.top = std::max(WidgetDimensions::scaled.frametext.top, this->widget_data != STR_NULL ? FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.frametext.top / 2 : 0); - this->smallest_x += this->child->padding_left + this->child->padding_right; - this->smallest_y += this->child->padding_top + this->child->padding_bottom; + this->smallest_x += this->child->padding.Horizontal(); + this->smallest_y += this->child->padding.Vertical(); if (this->index >= 0) w->SetStringParameters(this->index); - this->smallest_x = std::max(this->smallest_x, GetStringBoundingBox(this->widget_data).width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT); + this->smallest_x = std::max(this->smallest_x, GetStringBoundingBox(this->widget_data).width + WidgetDimensions::scaled.frametext.Horizontal()); } else if (this->type == WWT_INSET) { /* Apply automatic padding for bevel thickness. */ - this->child->padding_left = WD_BEVEL_LEFT; - this->child->padding_right = WD_BEVEL_RIGHT; - this->child->padding_top = WD_BEVEL_TOP; - this->child->padding_bottom = WD_BEVEL_BOTTOM; + this->child->padding = WidgetDimensions::scaled.bevel; - this->smallest_x += this->child->padding_left + this->child->padding_right; - this->smallest_y += this->child->padding_top + this->child->padding_bottom; + this->smallest_x += this->child->padding.Horizontal(); + this->smallest_y += this->child->padding.Vertical(); } } else { Dimension d = {this->min_x, this->min_y}; @@ -1933,11 +2179,17 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array) if (this->type == WWT_FRAME || this->type == WWT_INSET) { if (this->index >= 0) w->SetStringParameters(this->index); Dimension background = GetStringBoundingBox(this->widget_data); - background.width += (this->type == WWT_FRAME) ? (WD_FRAMETEXT_LEFT + WD_FRAMERECT_RIGHT) : (WD_INSET_LEFT + WD_INSET_RIGHT); + background.width += (this->type == WWT_FRAME) ? (WidgetDimensions::scaled.frametext.Horizontal()) : (WidgetDimensions::scaled.inset.Horizontal()); d = maxdim(d, background); } if (this->index >= 0) { - static const Dimension padding = {0, 0}; + Dimension padding; + switch (this->type) { + default: NOT_REACHED(); + case WWT_PANEL: padding = {WidgetDimensions::scaled.framerect.Horizontal(), WidgetDimensions::scaled.framerect.Vertical()}; break; + case WWT_FRAME: padding = {WidgetDimensions::scaled.frametext.Horizontal(), WidgetDimensions::scaled.frametext.Vertical()}; break; + case WWT_INSET: padding = {WidgetDimensions::scaled.inset.Horizontal(), WidgetDimensions::scaled.inset.Vertical()}; break; + } w->UpdateWidgetSize(this->index, &d, padding, &fill, &resize); } } @@ -1955,10 +2207,10 @@ void NWidgetBackground::AssignSizePosition(SizingType sizing, uint x, uint y, ui this->StoreSizePosition(sizing, x, y, given_width, given_height); if (this->child != nullptr) { - uint x_offset = (rtl ? this->child->padding_right : this->child->padding_left); - uint width = given_width - this->child->padding_right - this->child->padding_left; - uint height = given_height - this->child->padding_top - this->child->padding_bottom; - this->child->AssignSizePosition(sizing, x + x_offset, y + this->child->padding_top, width, height, rtl); + uint x_offset = (rtl ? this->child->padding.right : this->child->padding.left); + uint width = given_width - this->child->padding.Horizontal(); + uint height = given_height - this->child->padding.Vertical(); + this->child->AssignSizePosition(sizing, x + x_offset, y + this->child->padding.top, width, height, rtl); } } @@ -2001,7 +2253,7 @@ void NWidgetBackground::Draw(const Window *w) if (this->child != nullptr) this->child->Draw(w); if (this->IsDisabled()) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); } } @@ -2252,7 +2504,7 @@ void NWidgetScrollbar::Draw(const Window *w) } if (this->IsDisabled()) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); } } @@ -2264,22 +2516,20 @@ void NWidgetScrollbar::Draw(const Window *w) /* static */ Dimension NWidgetScrollbar::GetVerticalDimension() { - static const Dimension extra = {WD_SCROLLBAR_LEFT + WD_SCROLLBAR_RIGHT, WD_SCROLLBAR_TOP + WD_SCROLLBAR_BOTTOM}; if (vertical_dimension.width == 0) { - vertical_dimension = maxdim(GetSpriteSize(SPR_ARROW_UP), GetSpriteSize(SPR_ARROW_DOWN)); - vertical_dimension.width += extra.width; - vertical_dimension.height += extra.height; + vertical_dimension = maxdim(GetScaledSpriteSize(SPR_ARROW_UP), GetScaledSpriteSize(SPR_ARROW_DOWN)); + vertical_dimension.width += WidgetDimensions::scaled.vscrollbar.Horizontal(); + vertical_dimension.height += WidgetDimensions::scaled.vscrollbar.Vertical(); } return vertical_dimension; } /* static */ Dimension NWidgetScrollbar::GetHorizontalDimension() { - static const Dimension extra = {WD_SCROLLBAR_LEFT + WD_SCROLLBAR_RIGHT, WD_SCROLLBAR_TOP + WD_SCROLLBAR_BOTTOM}; if (horizontal_dimension.width == 0) { - horizontal_dimension = maxdim(GetSpriteSize(SPR_ARROW_LEFT), GetSpriteSize(SPR_ARROW_RIGHT)); - horizontal_dimension.width += extra.width; - horizontal_dimension.height += extra.height; + horizontal_dimension = maxdim(GetScaledSpriteSize(SPR_ARROW_LEFT), GetScaledSpriteSize(SPR_ARROW_RIGHT)); + horizontal_dimension.width += WidgetDimensions::scaled.hscrollbar.Horizontal(); + horizontal_dimension.height += WidgetDimensions::scaled.hscrollbar.Vertical(); } return horizontal_dimension; } @@ -2356,7 +2606,7 @@ NWidgetLeaf::NWidgetLeaf(WidgetType tp, Colours colour, int index, uint32 data, this->SetFill(1, 0); this->SetResize(1, 0); this->SetMinimalSize(0, WD_CAPTION_HEIGHT); - this->SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM, FS_NORMAL); + this->SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical(), FS_NORMAL); this->SetDataTip(data, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS); break; @@ -2414,41 +2664,35 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) w->nested_array[this->index] = this; } + Dimension padding = {0, 0}; Dimension size = {this->min_x, this->min_y}; Dimension fill = {this->fill_x, this->fill_y}; Dimension resize = {this->resize_x, this->resize_y}; - /* Get padding, and update size with the real content size if appropriate. */ - const Dimension *padding = nullptr; switch (this->type) { case WWT_EMPTY: { - static const Dimension extra = {0, 0}; - padding = &extra; break; } case WWT_MATRIX: { - static const Dimension extra = {WD_MATRIX_LEFT + WD_MATRIX_RIGHT, WD_MATRIX_TOP + WD_MATRIX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.matrix.Horizontal(), WidgetDimensions::scaled.matrix.Vertical()}; break; } case WWT_SHADEBOX: { - static const Dimension extra = {WD_SHADEBOX_LEFT + WD_SHADEBOX_RIGHT, WD_SHADEBOX_TOP + WD_SHADEBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.shadebox.Horizontal(), WidgetDimensions::scaled.shadebox.Vertical()}; if (NWidgetLeaf::shadebox_dimension.width == 0) { - NWidgetLeaf::shadebox_dimension = maxdim(GetSpriteSize(SPR_WINDOW_SHADE), GetSpriteSize(SPR_WINDOW_UNSHADE)); - NWidgetLeaf::shadebox_dimension.width += extra.width; - NWidgetLeaf::shadebox_dimension.height += extra.height; + NWidgetLeaf::shadebox_dimension = maxdim(GetScaledSpriteSize(SPR_WINDOW_SHADE), GetScaledSpriteSize(SPR_WINDOW_UNSHADE)); + NWidgetLeaf::shadebox_dimension.width += padding.width; + NWidgetLeaf::shadebox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::shadebox_dimension); break; } case WWT_DEBUGBOX: if (_settings_client.gui.newgrf_developer_tools && w->IsNewGRFInspectable()) { - static const Dimension extra = {WD_DEBUGBOX_LEFT + WD_DEBUGBOX_RIGHT, WD_DEBUGBOX_TOP + WD_DEBUGBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.debugbox.Horizontal(), WidgetDimensions::scaled.debugbox.Vertical()}; if (NWidgetLeaf::debugbox_dimension.width == 0) { - NWidgetLeaf::debugbox_dimension = GetSpriteSize(SPR_WINDOW_DEBUG); - NWidgetLeaf::debugbox_dimension.width += extra.width; - NWidgetLeaf::debugbox_dimension.height += extra.height; + NWidgetLeaf::debugbox_dimension = GetScaledSpriteSize(SPR_WINDOW_DEBUG); + NWidgetLeaf::debugbox_dimension.width += padding.width; + NWidgetLeaf::debugbox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::debugbox_dimension); } else { @@ -2460,81 +2704,74 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) break; case WWT_STICKYBOX: { - static const Dimension extra = {WD_STICKYBOX_LEFT + WD_STICKYBOX_RIGHT, WD_STICKYBOX_TOP + WD_STICKYBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.stickybox.Horizontal(), WidgetDimensions::scaled.stickybox.Vertical()}; if (NWidgetLeaf::stickybox_dimension.width == 0) { - NWidgetLeaf::stickybox_dimension = maxdim(GetSpriteSize(SPR_PIN_UP), GetSpriteSize(SPR_PIN_DOWN)); - NWidgetLeaf::stickybox_dimension.width += extra.width; - NWidgetLeaf::stickybox_dimension.height += extra.height; + NWidgetLeaf::stickybox_dimension = maxdim(GetScaledSpriteSize(SPR_PIN_UP), GetScaledSpriteSize(SPR_PIN_DOWN)); + NWidgetLeaf::stickybox_dimension.width += padding.width; + NWidgetLeaf::stickybox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::stickybox_dimension); break; } case WWT_DEFSIZEBOX: { - static const Dimension extra = {WD_DEFSIZEBOX_LEFT + WD_DEFSIZEBOX_RIGHT, WD_DEFSIZEBOX_TOP + WD_DEFSIZEBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.defsizebox.Horizontal(), WidgetDimensions::scaled.defsizebox.Vertical()}; if (NWidgetLeaf::defsizebox_dimension.width == 0) { - NWidgetLeaf::defsizebox_dimension = GetSpriteSize(SPR_WINDOW_DEFSIZE); - NWidgetLeaf::defsizebox_dimension.width += extra.width; - NWidgetLeaf::defsizebox_dimension.height += extra.height; + NWidgetLeaf::defsizebox_dimension = GetScaledSpriteSize(SPR_WINDOW_DEFSIZE); + NWidgetLeaf::defsizebox_dimension.width += padding.width; + NWidgetLeaf::defsizebox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::defsizebox_dimension); break; } case WWT_RESIZEBOX: { - static const Dimension extra = {WD_RESIZEBOX_LEFT + WD_RESIZEBOX_RIGHT, WD_RESIZEBOX_TOP + WD_RESIZEBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.resizebox.Horizontal(), WidgetDimensions::scaled.resizebox.Vertical()}; if (NWidgetLeaf::resizebox_dimension.width == 0) { - NWidgetLeaf::resizebox_dimension = maxdim(GetSpriteSize(SPR_WINDOW_RESIZE_LEFT), GetSpriteSize(SPR_WINDOW_RESIZE_RIGHT)); - NWidgetLeaf::resizebox_dimension.width += extra.width; - NWidgetLeaf::resizebox_dimension.height += extra.height; + NWidgetLeaf::resizebox_dimension = maxdim(GetScaledSpriteSize(SPR_WINDOW_RESIZE_LEFT), GetScaledSpriteSize(SPR_WINDOW_RESIZE_RIGHT)); + NWidgetLeaf::resizebox_dimension.width += padding.width; + NWidgetLeaf::resizebox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::resizebox_dimension); break; } case WWT_EDITBOX: { - Dimension sprite_size = GetSpriteSize(_current_text_dir == TD_RTL ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); - size.width = std::max(size.width, 30 + sprite_size.width); - size.height = std::max(sprite_size.height, GetStringBoundingBox("_").height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); + Dimension sprite_size = GetScaledSpriteSize(_current_text_dir == TD_RTL ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT); + size.width = std::max(size.width, ScaleGUITrad(30) + sprite_size.width); + size.height = std::max(sprite_size.height, GetStringBoundingBox("_").height + WidgetDimensions::scaled.framerect.Vertical()); } FALLTHROUGH; case WWT_PUSHBTN: { - static const Dimension extra = {WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.frametext.Horizontal(), WidgetDimensions::scaled.framerect.Vertical()}; break; } case WWT_IMGBTN: case WWT_IMGBTN_2: case WWT_PUSHIMGBTN: { - static const Dimension extra = {WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT, WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM}; - padding = &extra; - Dimension d2 = GetSpriteSize(this->widget_data); - if (this->type == WWT_IMGBTN_2) d2 = maxdim(d2, GetSpriteSize(this->widget_data + 1)); - d2.width += extra.width; - d2.height += extra.height; + padding = {WidgetDimensions::scaled.imgbtn.Horizontal(), WidgetDimensions::scaled.imgbtn.Vertical()}; + Dimension d2 = GetScaledSpriteSize(this->widget_data); + if (this->type == WWT_IMGBTN_2) d2 = maxdim(d2, GetScaledSpriteSize(this->widget_data + 1)); + d2.width += padding.width; + d2.height += padding.height; size = maxdim(size, d2); break; } case WWT_ARROWBTN: case WWT_PUSHARROWBTN: { - static const Dimension extra = {WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT, WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM}; - padding = &extra; - Dimension d2 = maxdim(GetSpriteSize(SPR_ARROW_LEFT), GetSpriteSize(SPR_ARROW_RIGHT)); - d2.width += extra.width; - d2.height += extra.height; + padding = {WidgetDimensions::scaled.imgbtn.Horizontal(), WidgetDimensions::scaled.imgbtn.Vertical()}; + Dimension d2 = maxdim(GetScaledSpriteSize(SPR_ARROW_LEFT), GetScaledSpriteSize(SPR_ARROW_RIGHT)); + d2.width += padding.width; + d2.height += padding.height; size = maxdim(size, d2); break; } case WWT_CLOSEBOX: { - static const Dimension extra = {WD_CLOSEBOX_LEFT + WD_CLOSEBOX_RIGHT, WD_CLOSEBOX_TOP + WD_CLOSEBOX_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.closebox.Horizontal(), WidgetDimensions::scaled.closebox.Vertical()}; if (NWidgetLeaf::closebox_dimension.width == 0) { - NWidgetLeaf::closebox_dimension = GetSpriteSize(SPR_CLOSEBOX); - NWidgetLeaf::closebox_dimension.width += extra.width; - NWidgetLeaf::closebox_dimension.height += extra.height; + NWidgetLeaf::closebox_dimension = GetScaledSpriteSize(SPR_CLOSEBOX); + NWidgetLeaf::closebox_dimension.width += padding.width; + NWidgetLeaf::closebox_dimension.height += padding.height; } size = maxdim(size, NWidgetLeaf::closebox_dimension); break; @@ -2542,48 +2779,42 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) case WWT_TEXTBTN: case WWT_PUSHTXTBTN: case WWT_TEXTBTN_2: { - static const Dimension extra = {WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.framerect.Horizontal(), WidgetDimensions::scaled.framerect.Vertical()}; if (this->index >= 0) w->SetStringParameters(this->index); Dimension d2 = GetStringBoundingBox(this->widget_data); - d2.width += extra.width; - d2.height += extra.height; + d2.width += padding.width; + d2.height += padding.height; size = maxdim(size, d2); break; } case WWT_LABEL: case WWT_TEXT: { - static const Dimension extra = {0, 0}; - padding = &extra; if (this->index >= 0) w->SetStringParameters(this->index); size = maxdim(size, GetStringBoundingBox(this->widget_data)); break; } case WWT_CAPTION: { - static const Dimension extra = {WD_CAPTIONTEXT_LEFT + WD_CAPTIONTEXT_RIGHT, WD_CAPTIONTEXT_TOP + WD_CAPTIONTEXT_BOTTOM}; - padding = &extra; + padding = {WidgetDimensions::scaled.captiontext.Horizontal(), WidgetDimensions::scaled.captiontext.Vertical()}; if (this->index >= 0) w->SetStringParameters(this->index); Dimension d2 = GetStringBoundingBox(this->widget_data); - d2.width += extra.width; - d2.height += extra.height; + d2.width += padding.width; + d2.height += padding.height; size = maxdim(size, d2); break; } case WWT_DROPDOWN: case NWID_BUTTON_DROPDOWN: case NWID_PUSHBUTTON_DROPDOWN: { - static Dimension extra = {WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT, WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM}; - padding = &extra; if (NWidgetLeaf::dropdown_dimension.width == 0) { - NWidgetLeaf::dropdown_dimension = GetSpriteSize(SPR_ARROW_DOWN); - NWidgetLeaf::dropdown_dimension.width += WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT; - NWidgetLeaf::dropdown_dimension.height += WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM; - extra.width = WD_DROPDOWNTEXT_LEFT + WD_DROPDOWNTEXT_RIGHT + NWidgetLeaf::dropdown_dimension.width; + NWidgetLeaf::dropdown_dimension = GetScaledSpriteSize(SPR_ARROW_DOWN); + NWidgetLeaf::dropdown_dimension.width += WidgetDimensions::scaled.vscrollbar.Horizontal(); + NWidgetLeaf::dropdown_dimension.height += WidgetDimensions::scaled.vscrollbar.Vertical(); } + padding = {WidgetDimensions::scaled.dropdowntext.Horizontal() + NWidgetLeaf::dropdown_dimension.width, WidgetDimensions::scaled.dropdowntext.Vertical()}; if (this->index >= 0) w->SetStringParameters(this->index); Dimension d2 = GetStringBoundingBox(this->widget_data); - d2.width += extra.width; - d2.height = std::max(d2.height, NWidgetLeaf::dropdown_dimension.height) + extra.height; + d2.width += padding.width; + d2.height = std::max(d2.height + padding.height, NWidgetLeaf::dropdown_dimension.height); size = maxdim(size, d2); break; } @@ -2591,7 +2822,7 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) NOT_REACHED(); } - if (this->index >= 0) w->UpdateWidgetSize(this->index, &size, *padding, &fill, &resize); + if (this->index >= 0) w->UpdateWidgetSize(this->index, &size, padding, &fill, &resize); this->smallest_x = size.width; this->smallest_y = size.height; @@ -2605,15 +2836,15 @@ void NWidgetLeaf::Draw(const Window *w) { if (this->current_x == 0 || this->current_y == 0) return; - /* Setup a clipping rectangle... */ + /* Setup a clipping rectangle... for WWT_EMPTY or WWT_TEXT, an extra scaled pixel is allowed vertically in case text shadow encroaches. */ + int extra_y = (this->type == WWT_EMPTY || this->type == WWT_TEXT) ? ScaleGUITrad(1) : 0; DrawPixelInfo new_dpi; - if (!FillDrawPixelInfo(&new_dpi, this->pos_x, this->pos_y, this->current_x, this->current_y)) return; + if (!FillDrawPixelInfo(&new_dpi, this->pos_x, this->pos_y, this->current_x, this->current_y + extra_y)) return; /* ...but keep coordinates relative to the window. */ new_dpi.left += this->pos_x; new_dpi.top += this->pos_y; - DrawPixelInfo *old_dpi = _cur_dpi; - _cur_dpi = &new_dpi; + AutoRestoreBackup dpi_backup(_cur_dpi, &new_dpi); Rect r = this->GetCurrentRect(); @@ -2725,10 +2956,8 @@ void NWidgetLeaf::Draw(const Window *w) if (this->index >= 0) w->DrawWidget(r, this->index); if (this->IsDisabled()) { - GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); + GfxFillRect(r.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[this->colour & 0xF][2], FILLRECT_CHECKER); } - - _cur_dpi = old_dpi; } /** @@ -2887,7 +3116,7 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, } case WPT_PADDING: - if (*dest != nullptr) (*dest)->SetPadding(parts->u.padding.top, parts->u.padding.right, parts->u.padding.bottom, parts->u.padding.left); + if (*dest != nullptr) (*dest)->SetPadding(parts->u.padding); break; case WPT_PIPSPACE: { @@ -2980,7 +3209,7 @@ static int MakeWidgetTree(const NWidgetPart *parts, int count, NWidgetBase **par if (fill_sub && (tp == NWID_HORIZONTAL || tp == NWID_HORIZONTAL_LTR || tp == NWID_VERTICAL || tp == NWID_MATRIX || tp == WWT_PANEL || tp == WWT_FRAME || tp == WWT_INSET || tp == NWID_SELECTION)) { NWidgetBase *sub_ptr = sub_widget; - int num_used = MakeWidgetTree(parts, count - total_used, &sub_ptr, biggest_index); + num_used = MakeWidgetTree(parts, count - total_used, &sub_ptr, biggest_index); parts += num_used; total_used += num_used; } @@ -3093,8 +3322,8 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid int hor_length = 0; Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON, nullptr, ZOOM_LVL_OUT_4X); - sprite_size.width += WD_MATRIX_LEFT + WD_MATRIX_RIGHT; - sprite_size.height += WD_MATRIX_TOP + WD_MATRIX_BOTTOM + 1; // 1 for the 'offset' of being pressed + sprite_size.width += WidgetDimensions::unscaled.matrix.Horizontal(); + sprite_size.height += WidgetDimensions::unscaled.matrix.Vertical() + 1; // 1 for the 'offset' of being pressed for (int widnum = widget_first; widnum <= widget_last; widnum++) { /* Ensure there is room in 'hor' for another button. */ diff --git a/src/widget_type.h b/src/widget_type.h index a5bd988492518..078aa49b10a9e 100644 --- a/src/widget_type.h +++ b/src/widget_type.h @@ -149,10 +149,20 @@ class NWidgetBase : public ZeroedMemoryAllocator { */ inline void SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left) { - this->uz_padding_top = top; - this->uz_padding_right = right; - this->uz_padding_bottom = bottom; - this->uz_padding_left = left; + this->uz_padding.top = top; + this->uz_padding.right = right; + this->uz_padding.bottom = bottom; + this->uz_padding.left = left; + this->AdjustPaddingForZoom(); + } + + /** + * Set additional space (padding) around the widget. + * @param padding Amount of padding around the widget. + */ + inline void SetPadding(const RectPadding &padding) + { + this->uz_padding = padding; this->AdjustPaddingForZoom(); } @@ -192,15 +202,8 @@ class NWidgetBase : public ZeroedMemoryAllocator { NWidgetBase *next; ///< Pointer to next widget in container. Managed by parent container widget. NWidgetBase *prev; ///< Pointer to previous widget in container. Managed by parent container widget. - uint8 padding_top; ///< Paddings added to the top of the widget. Managed by parent container widget. - uint8 padding_right; ///< Paddings added to the right of the widget. Managed by parent container widget. (parent container may swap this with padding_left for RTL) - uint8 padding_bottom; ///< Paddings added to the bottom of the widget. Managed by parent container widget. - uint8 padding_left; ///< Paddings added to the left of the widget. Managed by parent container widget. (parent container may swap this with padding_right for RTL) - - uint8 uz_padding_top; ///< Unscaled top padding, for resize calculation. - uint8 uz_padding_right; ///< Unscaled right padding, for resize calculation. - uint8 uz_padding_bottom; ///< Unscaled bottom padding, for resize calculation. - uint8 uz_padding_left; ///< Unscaled left padding, for resize calculation. + RectPadding padding; ///< Padding added to the widget. Managed by parent container widget. (parent container may swap left and right for RTL) + RectPadding uz_padding; ///< Unscaled padding, for resize calculation. protected: inline void StoreSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height); @@ -458,9 +461,11 @@ class NWidgetStacked : public NWidgetContainer { /** Nested widget container flags, */ enum NWidContainerFlags { NCB_EQUALSIZE = 0, ///< Containers should keep all their (resizing) children equally large. + NCB_BIGFIRST = 1, ///< Allocate space to biggest resize first. NC_NONE = 0, ///< All flags cleared. NC_EQUALSIZE = 1 << NCB_EQUALSIZE, ///< Value of the #NCB_EQUALSIZE flag. + NC_BIGFIRST = 1 << NCB_BIGFIRST, ///< Value of the #NCB_BIGFIRST flag. }; DECLARE_ENUM_AS_BIT_SET(NWidContainerFlags) @@ -741,10 +746,8 @@ class Scrollbar { */ bool SetPosition(int position) { - assert(position >= 0); - assert(this->count <= this->cap ? (position == 0) : (position + this->cap <= this->count)); uint16 old_pos = this->pos; - this->pos = position; + this->pos = Clamp(position, 0, std::max(this->count - this->cap, 0)); return this->pos != old_pos; } @@ -763,7 +766,7 @@ class Scrollbar { case SS_BIG: difference *= this->cap; break; default: break; } - return this->SetPosition(Clamp(this->pos + difference, 0, std::max(this->count - this->cap, 0))); + return this->SetPosition(this->pos + difference); } /** @@ -918,8 +921,7 @@ struct NWidgetPartWidget { * Widget part for storing padding. * @ingroup NestedWidgetParts */ -struct NWidgetPartPaddings { - uint8 top, right, bottom, left; ///< Paddings for all directions. +struct NWidgetPartPaddings : RectPadding { }; /** @@ -1149,6 +1151,24 @@ static inline NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 return part; } +/** + * Widget part function for setting additional space around a widget. + * @param r The padding around the widget. + * @ingroup NestedWidgetParts + */ +static inline NWidgetPart SetPadding(const RectPadding &padding) +{ + NWidgetPart part; + + part.type = WPT_PADDING; + part.u.padding.left = padding.left; + part.u.padding.top = padding.top; + part.u.padding.right = padding.right; + part.u.padding.bottom = padding.bottom; + + return part; +} + /** * Widget part function for setting a padding. * @param padding The padding to use for all directions. @@ -1251,4 +1271,6 @@ NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int widget_last, Colours button_colour, int max_length, StringID button_tooltip); +void SetupWidgetDimensions(); + #endif /* WIDGET_TYPE_H */ diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt index 903ebefb8ad86..1cf51e870c9c1 100644 --- a/src/widgets/CMakeLists.txt +++ b/src/widgets/CMakeLists.txt @@ -19,6 +19,7 @@ add_files( error_widget.h fios_widget.h framerate_widget.h + game_widget.h genworld_widget.h goal_widget.h graph_widget.h @@ -26,6 +27,7 @@ add_files( highscore_widget.h industry_widget.h intro_widget.h + league_widget.h link_graph_legend_widget.h main_widget.h misc_widget.h @@ -43,6 +45,7 @@ add_files( rail_widget.h road_widget.h screenshot_widget.h + script_widget.h settings_widget.h sign_widget.h slider.cpp diff --git a/src/widgets/ai_widget.h b/src/widgets/ai_widget.h index 163894df4c853..f50b6632c8563 100644 --- a/src/widgets/ai_widget.h +++ b/src/widgets/ai_widget.h @@ -10,35 +10,14 @@ #ifndef WIDGETS_AI_WIDGET_H #define WIDGETS_AI_WIDGET_H -#include "../company_type.h" #include "../textfile_type.h" -/** Widgets of the #AIListWindow class. */ -enum AIListWidgets { - WID_AIL_CAPTION, ///< Caption of the window. - WID_AIL_LIST, ///< The matrix with all available AIs. - WID_AIL_SCROLLBAR, ///< Scrollbar next to the AI list. - WID_AIL_INFO_BG, ///< Panel to draw some AI information on. - WID_AIL_ACCEPT, ///< Accept button. - WID_AIL_CANCEL, ///< Cancel button. -}; - -/** Widgets of the #AISettingsWindow class. */ -enum AISettingsWidgets { - WID_AIS_CAPTION, ///< Caption of the window. - WID_AIS_BACKGROUND, ///< Panel to draw the settings on. - WID_AIS_SCROLLBAR, ///< Scrollbar to scroll through all settings. - WID_AIS_ACCEPT, ///< Accept button. - WID_AIS_RESET, ///< Reset button. -}; - /** Widgets of the #AIConfigWindow class. */ enum AIConfigWidgets { WID_AIC_BACKGROUND, ///< Window background. WID_AIC_DECREASE, ///< Decrease the number of AIs. WID_AIC_INCREASE, ///< Increase the number of AIs. WID_AIC_NUMBER, ///< Number of AIs. - WID_AIC_GAMELIST, ///< List with current selected GameScript. WID_AIC_LIST, ///< List with currently selected AIs. WID_AIC_SCROLLBAR, ///< Scrollbar to scroll through the selected AIs. WID_AIC_MOVE_UP, ///< Move up button. @@ -50,22 +29,4 @@ enum AIConfigWidgets { WID_AIC_CONTENT_DOWNLOAD = WID_AIC_TEXTFILE + TFT_END, ///< Download content button. }; -/** Widgets of the #AIDebugWindow class. */ -enum AIDebugWidgets { - WID_AID_VIEW, ///< The row of company buttons. - WID_AID_NAME_TEXT, ///< Name of the current selected. - WID_AID_SETTINGS, ///< Settings button. - WID_AID_SCRIPT_GAME, ///< Game Script button. - WID_AID_RELOAD_TOGGLE, ///< Reload button. - WID_AID_LOG_PANEL, ///< Panel where the log is in. - WID_AID_SCROLLBAR, ///< Scrollbar of the log panel. - WID_AID_COMPANY_BUTTON_START, ///< Buttons in the VIEW. - WID_AID_COMPANY_BUTTON_END = WID_AID_COMPANY_BUTTON_START + MAX_COMPANIES - 1, ///< Last possible button in the VIEW. - WID_AID_BREAK_STRING_WIDGETS, ///< The panel to handle the breaking on string. - WID_AID_BREAK_STR_ON_OFF_BTN, ///< Enable breaking on string. - WID_AID_BREAK_STR_EDIT_BOX, ///< Edit box for the string to break on. - WID_AID_MATCH_CASE_BTN, ///< Checkbox to use match caching or not. - WID_AID_CONTINUE_BTN, ///< Continue button. -}; - #endif /* WIDGETS_AI_WIDGET_H */ diff --git a/src/widgets/airport_widget.h b/src/widgets/airport_widget.h index da0770bcb9c75..75b805031c1aa 100644 --- a/src/widgets/airport_widget.h +++ b/src/widgets/airport_widget.h @@ -30,6 +30,7 @@ enum AirportPickerWidgets { WID_AP_COVERAGE_LABEL, ///< Label if you want to see the coverage. WID_AP_BTN_DONTHILIGHT, ///< Don't show the coverage button. WID_AP_BTN_DOHILIGHT, ///< Show the coverage button. + WID_AP_ACCEPTANCE, ///< Acceptance info. }; #endif /* WIDGETS_AIRPORT_WIDGET_H */ diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index f104be68c8428..b9cc1c8b9ba88 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -13,6 +13,7 @@ #include "../strings_func.h" #include "../window_func.h" #include "../guitimer_func.h" +#include "../zoom_func.h" #include "dropdown_type.h" #include "dropdown_widget.h" @@ -20,26 +21,27 @@ #include "../safeguards.h" -void DropDownListItem::Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const +void DropDownListItem::Draw(const Rect &r, bool sel, Colours bg_colour) const { int c1 = _colour_gradient[bg_colour][3]; int c2 = _colour_gradient[bg_colour][7]; - int mid = top + this->Height(0) / 2; - GfxFillRect(left + 1, mid - 2, right - 1, mid - 2, c1); - GfxFillRect(left + 1, mid - 1, right - 1, mid - 1, c2); + int mid = CenterBounds(r.top, r.bottom, 0); + GfxFillRect(r.left, mid - WidgetDimensions::scaled.bevel.bottom, r.right, mid - 1, c1); + GfxFillRect(r.left, mid, r.right, mid + WidgetDimensions::scaled.bevel.top - 1, c2); } uint DropDownListStringItem::Width() const { char buffer[512]; GetString(buffer, this->String(), lastof(buffer)); - return GetStringBoundingBox(buffer).width; + return GetStringBoundingBox(buffer).width + WidgetDimensions::scaled.dropdowntext.Horizontal(); } -void DropDownListStringItem::Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const +void DropDownListStringItem::Draw(const Rect &r, bool sel, Colours bg_colour) const { - DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, top, this->String(), sel ? TC_WHITE : TC_BLACK); + Rect ir = r.Shrink(WidgetDimensions::scaled.dropdowntext); + DrawString(ir.left, ir.right, r.top, this->String(), sel ? TC_WHITE : TC_BLACK); } /** @@ -82,14 +84,16 @@ uint DropDownListIconItem::Height(uint width) const uint DropDownListIconItem::Width() const { - return DropDownListStringItem::Width() + this->dim.width + WD_FRAMERECT_LEFT; + return DropDownListParamStringItem::Width() + this->dim.width + WidgetDimensions::scaled.hsep_wide; } -void DropDownListIconItem::Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const +void DropDownListIconItem::Draw(const Rect &r, bool sel, Colours bg_colour) const { bool rtl = _current_text_dir == TD_RTL; - DrawSprite(this->sprite, this->pal, rtl ? right - this->dim.width - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT, CenterBounds(top, bottom, this->sprite_y)); - DrawString(left + WD_FRAMERECT_LEFT + (rtl ? 0 : (this->dim.width + WD_FRAMERECT_LEFT)), right - WD_FRAMERECT_RIGHT - (rtl ? (this->dim.width + WD_FRAMERECT_RIGHT) : 0), CenterBounds(top, bottom, FONT_HEIGHT_NORMAL), this->String(), sel ? TC_WHITE : TC_BLACK); + Rect ir = r.Shrink(WidgetDimensions::scaled.dropdowntext); + Rect tr = ir.Indent(this->dim.width + WidgetDimensions::scaled.hsep_normal, rtl); + DrawSprite(this->sprite, this->pal, ir.WithWidth(this->dim.width, rtl).left, CenterBounds(r.top, r.bottom, this->sprite_y)); + DrawString(tr.left, tr.right, CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), this->String(), sel ? TC_WHITE : TC_BLACK); } void DropDownListIconItem::SetDimension(Dimension d) @@ -153,7 +157,7 @@ struct DropdownWindow : Window { uint items_width = size.width - (scroll ? NWidgetScrollbar::GetVerticalDimension().width : 0); NWidgetCore *nwi = this->GetWidget(WID_DM_ITEMS); - nwi->SetMinimalSizeAbsolute(items_width, size.height + 4); + nwi->SetMinimalSizeAbsolute(items_width, size.height + WidgetDimensions::scaled.fullbevel.Vertical() * 2); nwi->colour = wi_colour; nwi = this->GetWidget(WID_DM_SCROLL); @@ -213,9 +217,9 @@ struct DropdownWindow : Window { { if (GetWidgetFromPos(this, _cursor.pos.x - this->left, _cursor.pos.y - this->top) < 0) return false; - NWidgetBase *nwi = this->GetWidget(WID_DM_ITEMS); - int y = _cursor.pos.y - this->top - nwi->pos_y - 2; - int width = nwi->current_x - 4; + const Rect &r = this->GetWidget(WID_DM_ITEMS)->GetCurrentRect().Shrink(WidgetDimensions::scaled.fullbevel); + int y = _cursor.pos.y - this->top - r.top - WidgetDimensions::scaled.fullbevel.top; + int width = r.Width(); int pos = this->vscroll->GetPosition(); for (const auto &item : this->list) { @@ -242,22 +246,23 @@ struct DropdownWindow : Window { Colours colour = this->GetWidget(widget)->colour; - int y = r.top + 2; + Rect ir = r.Shrink(WidgetDimensions::scaled.fullbevel).Shrink(RectPadding::zero, WidgetDimensions::scaled.fullbevel); + int y = ir.top; int pos = this->vscroll->GetPosition(); for (const auto &item : this->list) { - int item_height = item->Height(r.right - r.left + 1); + int item_height = item->Height(ir.Width()); /* Skip items that are scrolled up */ if (--pos >= 0) continue; - if (y + item_height < r.bottom) { + if (y + item_height - 1 <= ir.bottom) { bool selected = (this->selected_index == item->result); - if (selected) GfxFillRect(r.left + 2, y, r.right - 1, y + item_height - 1, PC_BLACK); + if (selected) GfxFillRect(ir.left, y, ir.right, y + item_height - 1, PC_BLACK); - item->Draw(r.left, r.right, y, y + item_height, selected, colour); + item->Draw({ir.left, y, ir.right, y + item_height - 1}, selected, colour); if (item->masked) { - GfxFillRect(r.left + 1, y, r.right - 1, y + item_height - 1, _colour_gradient[colour][5], FILLRECT_CHECKER); + GfxFillRect(ir.left, y, ir.right, y + item_height - 1, _colour_gradient[colour][5], FILLRECT_CHECKER); } } y += item_height; @@ -361,7 +366,7 @@ void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button int top = w->top + wi_rect.bottom + 1; /* The preferred width equals the calling widget */ - uint width = wi_rect.right - wi_rect.left + 1; + uint width = wi_rect.Width(); /* Longest item in the list, if auto_width is enabled */ uint max_item_width = 0; @@ -371,9 +376,11 @@ void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button for (const auto &item : list) { height += item->Height(width); - if (auto_width) max_item_width = std::max(max_item_width, item->Width() + 5); + if (auto_width) max_item_width = std::max(max_item_width, item->Width()); } + if (auto_width) max_item_width += WidgetDimensions::scaled.fullbevel.Horizontal(); + /* Scrollbar needed? */ bool scroll = false; @@ -381,12 +388,12 @@ void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button bool above = false; /* Available height below (or above, if the dropdown is placed above the widget). */ - uint available_height = std::max(GetMainViewBottom() - top - 4, 0); + uint available_height = std::max(GetMainViewBottom() - top - (int)WidgetDimensions::scaled.fullbevel.Vertical() * 2, 0); /* If the dropdown doesn't fully fit below the widget... */ if (height > available_height) { - uint available_height_above = std::max(w->top + wi_rect.top - GetMainViewTop() - 4, 0); + uint available_height_above = std::max(w->top + wi_rect.top - GetMainViewTop() - (int)WidgetDimensions::scaled.fullbevel.Vertical() * 2, 0); /* Put the dropdown above if there is more available space. */ if (available_height_above > available_height) { @@ -412,7 +419,7 @@ void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button /* Set the top position if needed. */ if (above) { - top = w->top + wi_rect.top - height - 4; + top = w->top + wi_rect.top - height - WidgetDimensions::scaled.fullbevel.Vertical() * 2; } } @@ -457,9 +464,9 @@ void ShowDropDownList(Window *w, DropDownList &&list, int selected, int button, if (width != 0) { if (_current_text_dir == TD_RTL) { - wi_rect.left = wi_rect.right + 1 - width; + wi_rect.left = wi_rect.right + 1 - ScaleGUITrad(width); } else { - wi_rect.right = wi_rect.left + width - 1; + wi_rect.right = wi_rect.left + ScaleGUITrad(width) - 1; } } diff --git a/src/widgets/dropdown_type.h b/src/widgets/dropdown_type.h index 5dfa9ed58be02..2e95b407d72dc 100644 --- a/src/widgets/dropdown_type.h +++ b/src/widgets/dropdown_type.h @@ -30,7 +30,7 @@ class DropDownListItem { virtual bool Selectable() const { return false; } virtual uint Height(uint width) const { return FONT_HEIGHT_NORMAL; } virtual uint Width() const { return 0; } - virtual void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const; + virtual void Draw(const Rect &r, bool sel, Colours bg_colour) const; }; /** @@ -44,7 +44,7 @@ class DropDownListStringItem : public DropDownListItem { bool Selectable() const override { return true; } uint Width() const override; - void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const override; + void Draw(const Rect &r, bool sel, Colours bg_colour) const override; virtual StringID String() const { return this->string; } static bool NatSortFunc(std::unique_ptr const &first, std::unique_ptr const &second); @@ -89,7 +89,7 @@ class DropDownListIconItem : public DropDownListParamStringItem { uint Height(uint width) const override; uint Width() const override; - void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const override; + void Draw(const Rect &r, bool sel, Colours bg_colour) const override; void SetDimension(Dimension d); }; diff --git a/src/widgets/game_widget.h b/src/widgets/game_widget.h new file mode 100644 index 0000000000000..f791a4374926d --- /dev/null +++ b/src/widgets/game_widget.h @@ -0,0 +1,28 @@ +/* + * 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 game_widget.h Types related to the GS widgets. */ + +#ifndef WIDGETS_GS_WIDGET_H +#define WIDGETS_GS_WIDGET_H + +#include "../textfile_type.h" + +/** Widgets of the #GSConfigWindow class. */ +enum GSConfigWidgets { + WID_GSC_BACKGROUND, ///< Window background. + WID_GSC_GSLIST, ///< List with current selected Game Script. + WID_GSC_SETTINGS, ///< Panel to draw the Game Script settings on + WID_GSC_SCROLLBAR, ///< Scrollbar to scroll through the selected AIs. + WID_GSC_CHANGE, ///< Select another Game Script button. + WID_GSC_TEXTFILE, ///< Open GS readme, changelog (+1) or license (+2). + WID_GSC_CONTENT_DOWNLOAD = WID_GSC_TEXTFILE + TFT_END, ///< Download content button. + WID_GSC_ACCEPT, ///< Accept ("Close") button + WID_GSC_RESET, ///< Reset button. +}; + +#endif /* WIDGETS_GS_WIDGET_H */ diff --git a/src/widgets/genworld_widget.h b/src/widgets/genworld_widget.h index 6644dc1aa70ee..34d2f149d82db 100644 --- a/src/widgets/genworld_widget.h +++ b/src/widgets/genworld_widget.h @@ -60,6 +60,10 @@ enum GenerateLandscapeWidgets { WID_GL_WATER_SE, ///< SE 'Water'/'Freeform'. WID_GL_WATER_SW, ///< SW 'Water'/'Freeform'. + WID_GL_AI_BUTTON, ///< 'AI Settings' button. + WID_GL_GS_BUTTON, ///< 'Game Script Settings' button. + WID_GL_NEWGRF_BUTTON, ///< 'NewGRF Settings' button. + WID_GL_CLIMATE_SEL_LABEL, ///< NWID_SELECTION for snow or desert coverage label WID_GL_CLIMATE_SEL_SELECTOR, ///< NWID_SELECTION for snow or desert coverage selector }; diff --git a/src/widgets/graph_widget.h b/src/widgets/graph_widget.h index 7c6478f6409c8..2548c990cd144 100644 --- a/src/widgets/graph_widget.h +++ b/src/widgets/graph_widget.h @@ -51,11 +51,6 @@ enum CargoPaymentRatesWidgets { WID_CPR_MATRIX_SCROLLBAR,///< Cargo list scrollbar. }; -/** Widget of the #CompanyLeagueWindow class. */ -enum CompanyLeagueWidgets { - WID_CL_BACKGROUND, ///< Background of the window. -}; - /** Widget of the #PerformanceRatingDetailWindow class. */ enum PerformanceRatingDetailsWidgets { WID_PRD_SCORE_FIRST, ///< First entry in the score list. diff --git a/src/widgets/group_widget.h b/src/widgets/group_widget.h index 03ac61a48e856..e097b5314ee8a 100644 --- a/src/widgets/group_widget.h +++ b/src/widgets/group_widget.h @@ -17,6 +17,7 @@ enum GroupListWidgets { WID_GL_GROUP_BY_DROPDOWN, ///< Group by dropdown list. WID_GL_SORT_BY_ORDER, ///< Sort order. WID_GL_SORT_BY_DROPDOWN, ///< Sort by dropdown list. + WID_GL_FILTER_BY_CARGO, ///< Filter vehicles by cargo type. WID_GL_LIST_VEHICLE, ///< List of the vehicles. WID_GL_LIST_VEHICLE_SCROLLBAR, ///< Scrollbar for the list. WID_GL_AVAILABLE_VEHICLES, ///< Available vehicles. diff --git a/src/widgets/industry_widget.h b/src/widgets/industry_widget.h index 5e3a656c1f6de..9f5762a53407b 100644 --- a/src/widgets/industry_widget.h +++ b/src/widgets/industry_widget.h @@ -37,6 +37,7 @@ enum IndustryDirectoryWidgets { WID_ID_DROPDOWN_CRITERIA, ///< Dropdown for the criteria of the sort. WID_ID_FILTER_BY_ACC_CARGO, ///< Accepted cargo filter dropdown list. WID_ID_FILTER_BY_PROD_CARGO, ///< Produced cargo filter dropdown list. + WID_ID_FILTER, ///< Textbox to filter industry name. WID_ID_INDUSTRY_LIST, ///< Industry list. WID_ID_SCROLLBAR, ///< Scrollbar of the list. }; diff --git a/src/widgets/intro_widget.h b/src/widgets/intro_widget.h index d7b53b85f7f3c..ef8e4997a0ca4 100644 --- a/src/widgets/intro_widget.h +++ b/src/widgets/intro_widget.h @@ -32,6 +32,7 @@ enum SelectGameIntroWidgets { WID_SGI_GRF_SETTINGS, ///< NewGRF button. WID_SGI_CONTENT_DOWNLOAD, ///< Content Download button. WID_SGI_AI_SETTINGS, ///< AI button. + WID_SGI_GS_SETTINGS, ///< Game Script button. WID_SGI_GAMEYEAR_DROPDOWN, ///< Dropdown 'Game year'. WID_SGI_EXIT, ///< Exit button. }; diff --git a/src/widgets/league_widget.h b/src/widgets/league_widget.h new file mode 100644 index 0000000000000..381d379a7e96e --- /dev/null +++ b/src/widgets/league_widget.h @@ -0,0 +1,24 @@ +/* + * 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 league_widget.h Types related to the graph widgets. */ + +#ifndef WIDGETS_LEAGUE_WIDGET_H +#define WIDGETS_LEAGUE_WIDGET_H + +/** Widget of the #PerformanceLeagueWindow class. */ +enum PerformanceLeagueWidgets { + WID_PLT_BACKGROUND, ///< Background of the window. +}; + +/** Widget of the #ScriptLeagueWindow class. */ +enum ScriptLeagueWidgets { + WID_SLT_CAPTION, ///< Caption of the window. + WID_SLT_BACKGROUND, ///< Background of the window. +}; + +#endif /* WIDGETS_LEAGUE_WIDGET_H */ diff --git a/src/widgets/network_content_widget.h b/src/widgets/network_content_widget.h index fd77f90aaf7e4..49c8153d4aeaa 100644 --- a/src/widgets/network_content_widget.h +++ b/src/widgets/network_content_widget.h @@ -14,8 +14,9 @@ /** Widgets of the #NetworkContentDownloadStatusWindow class. */ enum NetworkContentDownloadStatusWidgets { - WID_NCDS_BACKGROUND, ///< Background of the window. - WID_NCDS_CANCELOK, ///< (Optional) Cancel/OK button. + WID_NCDS_PROGRESS_BAR, ///< Simple progress bar. + WID_NCDS_PROGRESS_TEXT, ///< Text explaining what is happening. + WID_NCDS_CANCELOK, ///< (Optional) Cancel/OK button. }; /** Widgets of the #NetworkContentListWindow class. */ diff --git a/src/widgets/network_widget.h b/src/widgets/network_widget.h index f50bf04e93383..058cb090b0cdd 100644 --- a/src/widgets/network_widget.h +++ b/src/widgets/network_widget.h @@ -94,8 +94,9 @@ enum ClientListWidgets { /** Widgets of the #NetworkJoinStatusWindow class. */ enum NetworkJoinStatusWidgets { - WID_NJS_BACKGROUND, ///< Background of the window. - WID_NJS_CANCELOK, ///< Cancel / OK button. + WID_NJS_PROGRESS_BAR, ///< Simple progress bar. + WID_NJS_PROGRESS_TEXT, ///< Text explaining what is happening. + WID_NJS_CANCELOK, ///< Cancel / OK button. }; /** Widgets of the #NetworkCompanyPasswordWindow class. */ diff --git a/src/widgets/newgrf_debug_widget.h b/src/widgets/newgrf_debug_widget.h index 6ae41de348a53..bed87dc2c1090 100644 --- a/src/widgets/newgrf_debug_widget.h +++ b/src/widgets/newgrf_debug_widget.h @@ -38,6 +38,8 @@ enum SpriteAlignerWidgets { WID_SA_LIST, ///< Queried sprite list. WID_SA_SCROLLBAR, ///< Scrollbar for sprite list. WID_SA_RESET_REL, ///< Reset relative sprite offset + WID_SA_CENTRE, ///< Toggle centre sprite. + WID_SA_CROSSHAIR, ///< Toggle crosshair. }; #endif /* WIDGETS_NEWGRF_DEBUG_WIDGET_H */ diff --git a/src/widgets/road_widget.h b/src/widgets/road_widget.h index 3d49e9ae9db06..fa23631ba124d 100644 --- a/src/widgets/road_widget.h +++ b/src/widgets/road_widget.h @@ -41,17 +41,31 @@ enum BuildRoadDepotWidgets { /** Widgets of the #BuildRoadStationWindow class. */ enum BuildRoadStationWidgets { /* Name starts with BRO instead of BR, because of collision with BuildRailStationWidgets */ - WID_BROS_CAPTION, ///< Caption of the window. - WID_BROS_BACKGROUND, ///< Background of the window. - WID_BROS_STATION_NE, ///< Terminal station with NE entry. - WID_BROS_STATION_SE, ///< Terminal station with SE entry. - WID_BROS_STATION_SW, ///< Terminal station with SW entry. - WID_BROS_STATION_NW, ///< Terminal station with NW entry. - WID_BROS_STATION_X, ///< Drive-through station in x-direction. - WID_BROS_STATION_Y, ///< Drive-through station in y-direction. - WID_BROS_LT_OFF, ///< Turn off area highlight. - WID_BROS_LT_ON, ///< Turn on area highlight. - WID_BROS_INFO, ///< Station acceptance info. + WID_BROS_CAPTION, ///< Caption of the window. + WID_BROS_BACKGROUND, ///< Background of the window. + WID_BROS_STATION_NE, ///< Terminal station with NE entry. + WID_BROS_STATION_SE, ///< Terminal station with SE entry. + WID_BROS_STATION_SW, ///< Terminal station with SW entry. + WID_BROS_STATION_NW, ///< Terminal station with NW entry. + WID_BROS_STATION_X, ///< Drive-through station in x-direction. + WID_BROS_STATION_Y, ///< Drive-through station in y-direction. + WID_BROS_LT_OFF, ///< Turn off area highlight. + WID_BROS_LT_ON, ///< Turn on area highlight. + WID_BROS_ACCEPTANCE, ///< Station acceptance info. + WID_BROS_MATRIX, ///< Matrix widget displaying all available road stops. + WID_BROS_IMAGE, ///< Panel used for each image of the matrix. + WID_BROS_MATRIX_SCROLL, ///< Scrollbar of the #WID_BROS_SHOW_NEWST_ADDITIONS. + WID_BROS_FILTER_CONTAINER, ///< Container for the filter text box for the road stop class list. + WID_BROS_FILTER_EDITBOX, ///< Filter text box for the road stop class list. + WID_BROS_SHOW_NEWST_DEFSIZE, ///< Selection for default-size button for new road stops. + WID_BROS_SHOW_NEWST_ADDITIONS, ///< Selection for new class selection list. + WID_BROS_SHOW_NEWST_MATRIX, ///< Selection for new stop image matrix. + WID_BROS_SHOW_NEWST_RESIZE, ///< Selection for panel and resize at bottom right for new stops. + WID_BROS_SHOW_NEWST_ORIENTATION, ///< Selection for the orientation string for new stops. + WID_BROS_SHOW_NEWST_TYPE_SEL, ///< Selection for the type name. + WID_BROS_SHOW_NEWST_TYPE, ///< Display of selected stop type. + WID_BROS_NEWST_LIST, ///< List with new road stops. + WID_BROS_NEWST_SCROLL, ///< Scrollbar of the #WID_BROS_NEWST_LIST. }; #endif /* WIDGETS_ROAD_WIDGET_H */ diff --git a/src/widgets/script_widget.h b/src/widgets/script_widget.h new file mode 100644 index 0000000000000..9c757e12faa2d --- /dev/null +++ b/src/widgets/script_widget.h @@ -0,0 +1,52 @@ +/* + * 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 script_widget.h Types related to the script widgets. */ + +#ifndef WIDGETS_SCRIPT_WIDGET_H +#define WIDGETS_SCRIPT_WIDGET_H + +#include "../company_type.h" + +/** Widgets of the #ScriptListWindow class. */ +enum ScriptListWidgets { + WID_SCRL_CAPTION, ///< Caption of the window. + WID_SCRL_LIST, ///< The matrix with all available Scripts. + WID_SCRL_SCROLLBAR, ///< Scrollbar next to the Script list. + WID_SCRL_INFO_BG, ///< Panel to draw some Script information on. + WID_SCRL_ACCEPT, ///< Accept button. + WID_SCRL_CANCEL, ///< Cancel button. +}; + +/** Widgets of the #ScriptSettingsWindow class. */ +enum ScriptSettingsWidgets { + WID_SCRS_CAPTION, ///< Caption of the window. + WID_SCRS_BACKGROUND, ///< Panel to draw the settings on. + WID_SCRS_SCROLLBAR, ///< Scrollbar to scroll through all settings. + WID_SCRS_ACCEPT, ///< Accept button. + WID_SCRS_RESET, ///< Reset button. +}; + +/** Widgets of the #ScriptDebugWindow class. */ +enum ScriptDebugWidgets { + WID_SCRD_VIEW, ///< The row of company buttons. + WID_SCRD_NAME_TEXT, ///< Name of the current selected. + WID_SCRD_SETTINGS, ///< Settings button. + WID_SCRD_SCRIPT_GAME, ///< Game Script button. + WID_SCRD_RELOAD_TOGGLE, ///< Reload button. + WID_SCRD_LOG_PANEL, ///< Panel where the log is in. + WID_SCRD_SCROLLBAR, ///< Scrollbar of the log panel. + WID_SCRD_COMPANY_BUTTON_START, ///< Buttons in the VIEW. + WID_SCRD_COMPANY_BUTTON_END = WID_SCRD_COMPANY_BUTTON_START + MAX_COMPANIES - 1, ///< Last possible button in the VIEW. + WID_SCRD_BREAK_STRING_WIDGETS, ///< The panel to handle the breaking on string. + WID_SCRD_BREAK_STR_ON_OFF_BTN, ///< Enable breaking on string. + WID_SCRD_BREAK_STR_EDIT_BOX, ///< Edit box for the string to break on. + WID_SCRD_MATCH_CASE_BTN, ///< Checkbox to use match caching or not. + WID_SCRD_CONTINUE_BTN, ///< Continue button. +}; + +#endif /* WIDGETS_SCRIPT_WIDGET_H */ diff --git a/src/widgets/settings_widget.h b/src/widgets/settings_widget.h index 2a83ec657a7fd..8f655d945a0d5 100644 --- a/src/widgets/settings_widget.h +++ b/src/widgets/settings_widget.h @@ -19,7 +19,9 @@ enum GameOptionsWidgets { WID_GO_LANG_DROPDOWN, ///< Language dropdown. WID_GO_RESOLUTION_DROPDOWN, ///< Dropdown for the resolution. WID_GO_FULLSCREEN_BUTTON, ///< Toggle fullscreen. - WID_GO_GUI_ZOOM_DROPDOWN, ///< Dropdown for the GUI zoom level. + WID_GO_GUI_SCALE, ///< GUI Scale slider. + WID_GO_GUI_SCALE_AUTO, ///< Autodetect GUI scale button. + WID_GO_GUI_SCALE_BEVEL_BUTTON, ///< Toggle for chunky bevels. WID_GO_BASE_GRF_DROPDOWN, ///< Use to select a base GRF. WID_GO_BASE_GRF_STATUS, ///< Info about missing files etc. WID_GO_BASE_GRF_TEXTFILE, ///< Open base GRF readme, changelog (+1) or license (+2). @@ -30,10 +32,10 @@ enum GameOptionsWidgets { WID_GO_BASE_SFX_DESCRIPTION = WID_GO_BASE_SFX_TEXTFILE + TFT_END, ///< Description of selected base SFX. WID_GO_BASE_MUSIC_DROPDOWN, ///< Use to select a base music set. WID_GO_BASE_MUSIC_VOLUME, ///< Change music volume. + WID_GO_BASE_MUSIC_JUKEBOX, ///< Open the jukebox. WID_GO_BASE_MUSIC_STATUS, ///< Info about corrupted files etc. WID_GO_BASE_MUSIC_TEXTFILE, ///< Open base music readme, changelog (+1) or license (+2). WID_GO_BASE_MUSIC_DESCRIPTION = WID_GO_BASE_MUSIC_TEXTFILE + TFT_END, ///< Description of selected base music set. - WID_GO_FONT_ZOOM_DROPDOWN, ///< Dropdown for the font zoom level. WID_GO_VIDEO_ACCEL_BUTTON, ///< Toggle for video acceleration. WID_GO_VIDEO_VSYNC_BUTTON, ///< Toggle for video vsync. WID_GO_REFRESH_RATE_DROPDOWN, ///< Dropdown for all available refresh rates. diff --git a/src/widgets/slider.cpp b/src/widgets/slider.cpp index 67c4c372d2c4b..59d0483668f51 100644 --- a/src/widgets/slider.cpp +++ b/src/widgets/slider.cpp @@ -19,47 +19,74 @@ static const int SLIDER_WIDTH = 3; /** - * Draw a volume slider widget with know at given value - * @param r Rectangle to draw the widget in + * Draw a slider widget with knob at given value + * @param r Rectangle to draw the widget in + * @param min_value Minimum value of slider + * @param max_value Maximum value of slider * @param value Value to put the slider at + * @param labels List of positions and labels to draw along the slider. */ -void DrawVolumeSliderWidget(Rect r, byte value) +void DrawSliderWidget(Rect r, int min_value, int max_value, int value, const std::map &labels) { - /* Draw a wedge indicating low to high volume level. */ + /* Allow space for labels. We assume they are in the small font. */ + if (labels.size() > 0) r.bottom -= FONT_HEIGHT_SMALL + WidgetDimensions::scaled.hsep_normal; + + max_value -= min_value; + + /* Draw a wedge indicating low to high value. */ const int ha = (r.bottom - r.top) / 5; - int wx1 = r.left, wx2 = r.right; + const int sw = ScaleGUITrad(SLIDER_WIDTH); + const int t = WidgetDimensions::scaled.bevel.top; /* Thickness of lines */ + int wx1 = r.left + sw / 2; + int wx2 = r.right - sw / 2; if (_current_text_dir == TD_RTL) std::swap(wx1, wx2); const uint shadow = _colour_gradient[COLOUR_GREY][3]; const uint fill = _colour_gradient[COLOUR_GREY][6]; const uint light = _colour_gradient[COLOUR_GREY][7]; const std::vector wedge{ Point{wx1, r.bottom - ha}, Point{wx2, r.top + ha}, Point{wx2, r.bottom - ha} }; GfxFillPolygon(wedge, fill); - GfxDrawLine(wedge[0].x, wedge[0].y, wedge[2].x, wedge[2].y, light); - GfxDrawLine(wedge[1].x, wedge[1].y, wedge[2].x, wedge[2].y, _current_text_dir == TD_RTL ? shadow : light); - GfxDrawLine(wedge[0].x, wedge[0].y, wedge[1].x, wedge[1].y, shadow); + GfxDrawLine(wedge[0].x, wedge[0].y, wedge[2].x, wedge[2].y, light, t); + GfxDrawLine(wedge[1].x, wedge[1].y, wedge[2].x, wedge[2].y, _current_text_dir == TD_RTL ? shadow : light, t); + GfxDrawLine(wedge[0].x, wedge[0].y, wedge[1].x, wedge[1].y, shadow, t); - /* Draw a slider handle indicating current volume level. */ - const int sw = ScaleGUITrad(SLIDER_WIDTH); - if (_current_text_dir == TD_RTL) value = 127 - value; - const int x = r.left + (value * (r.right - r.left - sw) / 127); + int x; + for (auto label : labels) { + x = label.first - min_value; + if (_current_text_dir == TD_RTL) x = max_value - x; + x = r.left + (x * (r.right - r.left - sw) / max_value) + sw / 2; + GfxDrawLine(x, r.bottom - ha + 1, x, r.bottom + (label.second == STR_NULL ? 0 : WidgetDimensions::scaled.hsep_normal), shadow, t); + if (label.second != STR_NULL) { + Dimension d = GetStringBoundingBox(label.second, FS_SMALL); + x = Clamp(x - d.width / 2, r.left, r.right - d.width); + DrawString(x, x + d.width, r.bottom + 1 + WidgetDimensions::scaled.hsep_normal, label.second, TC_BLACK, SA_CENTER, false, FS_SMALL); + } + } + + /* Draw a slider handle indicating current value. */ + value -= min_value; + if (_current_text_dir == TD_RTL) value = max_value - value; + x = r.left + (value * (r.right - r.left - sw) / max_value); DrawFrameRect(x, r.top, x + sw, r.bottom, COLOUR_GREY, FR_NONE); } /** - * Handle click on a volume slider widget to change the value + * Handle click on a slider widget to change the value * @param r Rectangle of the widget * @param pt Clicked point - * @param value[in,out] Volume value to modify - * @return True if the volume setting was modified + * @param value[in,out] Value to modify + * @return True if the value setting was modified */ -bool ClickVolumeSliderWidget(Rect r, Point pt, byte &value) +bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, int &value) { + max_value -= min_value; + const int sw = ScaleGUITrad(SLIDER_WIDTH); - byte new_vol = Clamp((pt.x - r.left - sw / 2) * 127 / (r.right - r.left - sw), 0, 127); - if (_current_text_dir == TD_RTL) new_vol = 127 - new_vol; + int new_value = Clamp((pt.x - r.left - sw / 2) * max_value / (r.right - r.left - sw), 0, max_value); + if (_current_text_dir == TD_RTL) new_value = max_value - new_value; + new_value += min_value; - if (new_vol != value) { - value = new_vol; + if (new_value != value) { + value = new_value; return true; } diff --git a/src/widgets/slider_func.h b/src/widgets/slider_func.h index 1aa1fa10c6d8d..7de929512c662 100644 --- a/src/widgets/slider_func.h +++ b/src/widgets/slider_func.h @@ -13,9 +13,17 @@ #include "../window_type.h" #include "../gfx_func.h" +#include -void DrawVolumeSliderWidget(Rect r, byte value); -bool ClickVolumeSliderWidget(Rect r, Point pt, byte &value); +void DrawSliderWidget(Rect r, int min_value, int max_value, int value, const std::map &labels); +bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, int &value); +inline bool ClickSliderWidget(Rect r, Point pt, int min_value, int max_value, byte &value) +{ + int tmp_value = value; + if (!ClickSliderWidget(r, pt, min_value, max_value, tmp_value)) return false; + value = tmp_value; + return true; +} #endif /* WIDGETS_SLIDER_TYPE_H */ diff --git a/src/widgets/town_widget.h b/src/widgets/town_widget.h index 1a3291a3db386..f16a8a585eb45 100644 --- a/src/widgets/town_widget.h +++ b/src/widgets/town_widget.h @@ -49,6 +49,7 @@ enum TownFoundingWidgets { WID_TF_NEW_TOWN, ///< Create a new town. WID_TF_RANDOM_TOWN, ///< Randomly place a town. WID_TF_MANY_RANDOM_TOWNS, ///< Randomly place many towns. + WID_TF_EXPAND_ALL_TOWNS, ///< Make all towns grow slightly. WID_TF_TOWN_NAME_EDITBOX, ///< Editor for the town name. WID_TF_TOWN_NAME_RANDOM, ///< Generate a random town name. WID_TF_SIZE_SMALL, ///< Selection for a small town. diff --git a/src/widgets/vehicle_widget.h b/src/widgets/vehicle_widget.h index 954e72f70e538..8e960bcb7988c 100644 --- a/src/widgets/vehicle_widget.h +++ b/src/widgets/vehicle_widget.h @@ -27,6 +27,7 @@ enum VehicleViewWidgets { WID_VV_SELECT_REFIT_TURN, ///< Selection widget between 'refit' and 'turn around' buttons. WID_VV_TURN_AROUND, ///< Turn this vehicle around. WID_VV_FORCE_PROCEED, ///< Force this vehicle to pass a signal at danger. + WID_VV_HONK_HORN, ///< Honk the vehicles horn (not drawn on UI, only used for hotkey). }; /** Widgets of the #RefitWindow class. */ @@ -69,6 +70,8 @@ enum VehicleListWidgets { WID_VL_GROUP_BY_PULLDOWN, ///< Group by dropdown list. WID_VL_SORT_ORDER, ///< Sort order. WID_VL_SORT_BY_PULLDOWN, ///< Sort by dropdown list. + WID_VL_FILTER_BY_CARGO, ///< Cargo filter dropdown list. + WID_VL_FILTER_BY_CARGO_SEL, ///< Cargo filter dropdown list panel selector. WID_VL_LIST, ///< List of the vehicles. WID_VL_SCROLLBAR, ///< Scrollbar for the list. WID_VL_HIDE_BUTTONS, ///< Selection to hide the buttons. diff --git a/src/window.cpp b/src/window.cpp index 62a930d9da9c5..562823cea238c 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -18,6 +18,7 @@ #include "blitter/factory.hpp" #include "zoom_func.h" #include "vehicle_base.h" +#include "depot_func.h" #include "window_func.h" #include "tilehighlight_func.h" #include "network/network.h" @@ -257,7 +258,7 @@ void Window::SetWidgetHighlight(byte widget_index, TextColour highlighted_colour /* If we disable a highlight, check all widgets if anyone still has a highlight */ bool valid = false; for (uint i = 0; i < this->nested_array_size; i++) { - NWidgetBase *nwid = this->GetWidget(i); + nwid = this->GetWidget(i); if (nwid == nullptr) continue; if (!nwid->IsHighlighted()) continue; @@ -354,6 +355,17 @@ QueryString *Window::GetQueryString(uint widnum) return query != this->querystrings.End() ? query->second : nullptr; } +/** + * Update size of all QueryStrings of this window. + */ +void Window::UpdateQueryStringSize() +{ + for (auto &qs : this->querystrings) + { + qs.second->text.UpdateSize(); + } +} + /** * Get the current input text if an edit box has the focus. * @return The currently focused input text or nullptr if no input focused. @@ -969,9 +981,8 @@ static void DrawOverlappedWindow(Window *w, int left, int top, int right, int bo */ void DrawOverlappedWindowForAll(int left, int top, int right, int bottom) { - DrawPixelInfo *old_dpi = _cur_dpi; DrawPixelInfo bk; - _cur_dpi = &bk; + AutoRestoreBackup dpi_backup(_cur_dpi, &bk); for (Window *w : Window::IterateFromBack()) { if (MayBeShown(w) && @@ -983,7 +994,6 @@ void DrawOverlappedWindowForAll(int left, int top, int right, int bottom) DrawOverlappedWindow(w, std::max(left, w->left), std::max(top, w->top), std::min(right, w->left + w->width), std::min(bottom, w->top + w->height)); } } - _cur_dpi = old_dpi; } /** @@ -1167,6 +1177,18 @@ Window *FindWindowByClass(WindowClass cls) return nullptr; } +/** + * Get the main window, i.e. FindWindowById(WC_MAIN_WINDOW, 0). + * If the main window is not available, this function will trigger an assert. + * @return Pointer to the main window. + */ +Window *GetMainWindow() +{ + Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + assert(w != nullptr); + return w; +} + /** * Close a window by its class and window number (if it is open). * @param cls Window class @@ -1349,8 +1371,8 @@ static uint GetWindowZPriority(WindowClass wc) case WC_CUSTOM_CURRENCY: case WC_NETWORK_WINDOW: case WC_GRF_PARAMETERS: - case WC_AI_LIST: - case WC_AI_SETTINGS: + case WC_SCRIPT_LIST: + case WC_SCRIPT_SETTINGS: case WC_TEXTFILE: ++z_priority; FALLTHROUGH; @@ -1643,7 +1665,7 @@ static Point GetAutoPlacePosition(int width, int height) */ int left = rtl ? _screen.width - width : 0, top = toolbar_y; int offset_x = rtl ? -(int)NWidgetLeaf::closebox_dimension.width : (int)NWidgetLeaf::closebox_dimension.width; - int offset_y = std::max(NWidgetLeaf::closebox_dimension.height, FONT_HEIGHT_NORMAL + WD_CAPTIONTEXT_TOP + WD_CAPTIONTEXT_BOTTOM); + int offset_y = std::max(NWidgetLeaf::closebox_dimension.height, FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.captiontext.Vertical()); restart: for (const Window *w : Window::Iterate()) { @@ -1709,7 +1731,7 @@ static Point LocalGetWindowPlacement(const WindowDesc *desc, int16 sm_width, int * - Y position: closebox of parent + closebox of child + statusbar * - X position: closebox on left/right, resizebox on right/left (depending on ltr/rtl) */ - int indent_y = std::max(NWidgetLeaf::closebox_dimension.height, FONT_HEIGHT_NORMAL + WD_CAPTIONTEXT_TOP + WD_CAPTIONTEXT_BOTTOM); + int indent_y = std::max(NWidgetLeaf::closebox_dimension.height, FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.captiontext.Vertical()); if (w->top + 3 * indent_y < _screen.height) { pt.y = w->top + indent_y; int indent_close = NWidgetLeaf::closebox_dimension.width; @@ -2000,28 +2022,30 @@ static void PreventHiding(int *nx, int *ny, const Rect &rect, const Window *v, i { if (v == nullptr) return; + const int min_visible = ScaleGUITrad(MIN_VISIBLE_TITLE_BAR); + int v_bottom = v->top + v->height; int v_right = v->left + v->width; - int safe_y = (dir == PHD_UP) ? (v->top - MIN_VISIBLE_TITLE_BAR - rect.top) : (v_bottom + MIN_VISIBLE_TITLE_BAR - rect.bottom); // Compute safe vertical position. + int safe_y = (dir == PHD_UP) ? (v->top - min_visible - rect.top) : (v_bottom + min_visible - rect.bottom); // Compute safe vertical position. - if (*ny + rect.top <= v->top - MIN_VISIBLE_TITLE_BAR) return; // Above v is enough space - if (*ny + rect.bottom >= v_bottom + MIN_VISIBLE_TITLE_BAR) return; // Below v is enough space + if (*ny + rect.top <= v->top - min_visible) return; // Above v is enough space + if (*ny + rect.bottom >= v_bottom + min_visible) return; // Below v is enough space /* Vertically, the rectangle is hidden behind v. */ - if (*nx + rect.left + MIN_VISIBLE_TITLE_BAR < v->left) { // At left of v. - if (v->left < MIN_VISIBLE_TITLE_BAR) *ny = safe_y; // But enough room, force it to a safe position. + if (*nx + rect.left + min_visible < v->left) { // At left of v. + if (v->left < min_visible) *ny = safe_y; // But enough room, force it to a safe position. return; } - if (*nx + rect.right - MIN_VISIBLE_TITLE_BAR > v_right) { // At right of v. - if (v_right > _screen.width - MIN_VISIBLE_TITLE_BAR) *ny = safe_y; // Not enough room, force it to a safe position. + if (*nx + rect.right - min_visible > v_right) { // At right of v. + if (v_right > _screen.width - min_visible) *ny = safe_y; // Not enough room, force it to a safe position. return; } /* Horizontally also hidden, force movement to a safe area. */ - if (px + rect.left < v->left && v->left >= MIN_VISIBLE_TITLE_BAR) { // Coming from the left, and enough room there. - *nx = v->left - MIN_VISIBLE_TITLE_BAR - rect.left; - } else if (px + rect.right > v_right && v_right <= _screen.width - MIN_VISIBLE_TITLE_BAR) { // Coming from the right, and enough room there. - *nx = v_right + MIN_VISIBLE_TITLE_BAR - rect.right; + if (px + rect.left < v->left && v->left >= min_visible) { // Coming from the left, and enough room there. + *nx = v->left - min_visible - rect.left; + } else if (px + rect.right > v_right && v_right <= _screen.width - min_visible) { // Coming from the right, and enough room there. + *nx = v_right + min_visible - rect.right; } else { *ny = safe_y; } @@ -2042,9 +2066,11 @@ static void EnsureVisibleCaption(Window *w, int nx, int ny) if (caption != nullptr) { caption_rect = caption->GetCurrentRect(); + const int min_visible = ScaleGUITrad(MIN_VISIBLE_TITLE_BAR); + /* Make sure the window doesn't leave the screen */ - nx = Clamp(nx, MIN_VISIBLE_TITLE_BAR - caption_rect.right, _screen.width - MIN_VISIBLE_TITLE_BAR - caption_rect.left); - ny = Clamp(ny, 0, _screen.height - MIN_VISIBLE_TITLE_BAR); + nx = Clamp(nx, min_visible - caption_rect.right, _screen.width - min_visible - caption_rect.left); + ny = Clamp(ny, 0, _screen.height - min_visible); /* Make sure the title bar isn't hidden behind the main tool bar or the status bar. */ PreventHiding(&nx, &ny, caption_rect, FindWindowById(WC_MAIN_TOOLBAR, 0), w->left, PHD_DOWN); @@ -2420,7 +2446,7 @@ static EventState HandleViewportScroll() return ES_NOT_HANDLED; } - if (_last_scroll_window == FindWindowById(WC_MAIN_WINDOW, 0) && _last_scroll_window->viewport->follow_vehicle != INVALID_VEHICLE) { + if (_last_scroll_window == GetMainWindow() && _last_scroll_window->viewport->follow_vehicle != INVALID_VEHICLE) { /* If the main window is following a vehicle, then first let go of it! */ const Vehicle *veh = Vehicle::Get(_last_scroll_window->viewport->follow_vehicle); ScrollMainWindowTo(veh->x_pos, veh->y_pos, veh->z_pos, true); // This also resets follow_vehicle @@ -2765,9 +2791,7 @@ const std::chrono::milliseconds TIME_BETWEEN_DOUBLE_CLICK(500); ///< Time betwee static void ScrollMainViewport(int x, int y) { if (_game_mode != GM_MENU) { - Window *w = FindWindowById(WC_MAIN_WINDOW, 0); - assert(w); - + Window *w = GetMainWindow(); w->viewport->dest_scrollpos_x += ScaleByZoom(x, w->viewport->zoom); w->viewport->dest_scrollpos_y += ScaleByZoom(y, w->viewport->zoom); } @@ -2877,6 +2901,7 @@ static void MouseLoop(MouseClick click, int mousewheel) _scrolling_viewport = true; _cursor.fix_at = (_settings_client.gui.scroll_mode == VSM_VIEWPORT_RMB_FIXED || _settings_client.gui.scroll_mode == VSM_MAP_RMB_FIXED); + DispatchRightClickEvent(w, x - w->left, y - w->top); return; } break; @@ -2886,27 +2911,25 @@ static void MouseLoop(MouseClick click, int mousewheel) } } - if (vp == nullptr || (w->flags & WF_DISABLE_VP_SCROLL)) { - switch (click) { - case MC_LEFT: - case MC_DOUBLE_LEFT: - DispatchLeftClickEvent(w, x - w->left, y - w->top, click == MC_DOUBLE_LEFT ? 2 : 1); - return; + switch (click) { + case MC_LEFT: + case MC_DOUBLE_LEFT: + DispatchLeftClickEvent(w, x - w->left, y - w->top, click == MC_DOUBLE_LEFT ? 2 : 1); + return; - default: - if (!scrollwheel_scrolling || w == nullptr || w->window_class != WC_SMALLMAP) break; - /* We try to use the scrollwheel to scroll since we didn't touch any of the buttons. - * Simulate a right button click so we can get started. */ - FALLTHROUGH; + default: + if (!scrollwheel_scrolling || w == nullptr || w->window_class != WC_SMALLMAP) break; + /* We try to use the scrollwheel to scroll since we didn't touch any of the buttons. + * Simulate a right button click so we can get started. */ + FALLTHROUGH; - case MC_RIGHT: - DispatchRightClickEvent(w, x - w->left, y - w->top); - return; + case MC_RIGHT: + DispatchRightClickEvent(w, x - w->left, y - w->top); + return; - case MC_HOVER: - DispatchHoverEvent(w, x - w->left, y - w->top); - break; - } + case MC_HOVER: + DispatchHoverEvent(w, x - w->left, y - w->top); + break; } /* We're not doing anything with 2D scrolling, so reset the value. */ @@ -2970,11 +2993,12 @@ void HandleMouseEvents() hover_pos = _cursor.pos; hover_time = std::chrono::steady_clock::now(); _mouse_hovering = false; - } else { + } else if (!_mouse_hovering) { if (std::chrono::steady_clock::now() > hover_time + std::chrono::milliseconds(_settings_client.gui.hover_delay_ms)) { click = MC_HOVER; _input_events_this_tick++; _mouse_hovering = true; + hover_time = std::chrono::steady_clock::now(); } } } @@ -3071,6 +3095,8 @@ void UpdateWindows() PerformanceMeasurer framerate(PFE_DRAWING); PerformanceAccumulator::Reset(PFE_DRAWWORLD); + ProcessPendingPerformanceMeasurements(); + CallWindowRealtimeTickEvent(delta_ms); static GUITimer network_message_timer = GUITimer(1); @@ -3347,21 +3373,34 @@ void HideVitalWindows() CloseWindowById(WC_STATUS_BAR, 0); } +void ReInitWindow(Window *w, bool zoom_changed) +{ + if (w == nullptr) return; + if (zoom_changed) { + w->nested_root->AdjustPaddingForZoom(); + w->UpdateQueryStringSize(); + } + w->ReInit(); +} + /** Re-initialize all windows. */ void ReInitAllWindows(bool zoom_changed) { + SetupWidgetDimensions(); NWidgetLeaf::InvalidateDimensionCache(); // Reset cached sizes of several widgets. NWidgetScrollbar::InvalidateDimensionCache(); - extern void InitDepotWindowBlockSizes(); InitDepotWindowBlockSizes(); + /* When _gui_zoom has changed, we need to resize toolbar and statusbar first, + * so EnsureVisibleCaption uses the updated size information. */ + ReInitWindow(FindWindowById(WC_MAIN_TOOLBAR, 0), zoom_changed); + ReInitWindow(FindWindowById(WC_STATUS_BAR, 0), zoom_changed); for (Window *w : Window::Iterate()) { - if (zoom_changed) w->nested_root->AdjustPaddingForZoom(); - w->ReInit(); + if (w->window_class == WC_MAIN_TOOLBAR || w->window_class == WC_STATUS_BAR) continue; + ReInitWindow(w, zoom_changed); } - void NetworkReInitChatBoxSize(); NetworkReInitChatBoxSize(); /* Make sure essential parts of all windows are visible */ diff --git a/src/window_func.h b/src/window_func.h index d68b7ba1c1ed4..0f4d154e546fb 100644 --- a/src/window_func.h +++ b/src/window_func.h @@ -16,6 +16,7 @@ Window *FindWindowById(WindowClass cls, WindowNumber number); Window *FindWindowByClass(WindowClass cls); +Window *GetMainWindow(); void ChangeWindowOwner(Owner old_owner, Owner new_owner); void ResizeWindow(Window *w, int x, int y, bool clamp_to_screen = true); diff --git a/src/window_gui.h b/src/window_gui.h index 58d14a54e7dd5..00dfd9960a563 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -11,7 +11,10 @@ #define WINDOW_GUI_H #include +#include +#include +#include "vehiclelist.h" #include "vehicle_type.h" #include "viewport_type.h" #include "company_type.h" @@ -34,114 +37,45 @@ enum FrameFlags { DECLARE_ENUM_AS_BIT_SET(FrameFlags) -/** Distances used in drawing widgets. */ -enum WidgetDrawDistances { - /* WWT_IMGBTN(_2) */ - WD_IMGBTN_LEFT = 1, ///< Left offset of the image in the button. - WD_IMGBTN_RIGHT = 2, ///< Right offset of the image in the button. - WD_IMGBTN_TOP = 1, ///< Top offset of image in the button. - WD_IMGBTN_BOTTOM = 2, ///< Bottom offset of image in the button. - - /* WWT_INSET */ - WD_INSET_LEFT = 2, ///< Left offset of string. - WD_INSET_RIGHT = 2, ///< Right offset of string. - WD_INSET_TOP = 1, ///< Top offset of string. - - WD_SCROLLBAR_LEFT = 2, ///< Left offset of scrollbar. - WD_SCROLLBAR_RIGHT = 2, ///< Right offset of scrollbar. - WD_SCROLLBAR_TOP = 2, ///< Top offset of scrollbar. - WD_SCROLLBAR_BOTTOM = 2, ///< Bottom offset of scrollbar. - - /* Size of the pure frame bevel without any padding. */ - WD_BEVEL_LEFT = 1, ///< Width of left bevel border. - WD_BEVEL_RIGHT = 1, ///< Width of right bevel border. - WD_BEVEL_TOP = 1, ///< Height of top bevel border. - WD_BEVEL_BOTTOM = 1, ///< Height of bottom bevel border. - - /* FrameRect widgets, all text buttons, panel, editbox */ - WD_FRAMERECT_LEFT = 2, ///< Offset at left to draw the frame rectangular area - WD_FRAMERECT_RIGHT = 2, ///< Offset at right to draw the frame rectangular area - WD_FRAMERECT_TOP = 1, ///< Offset at top to draw the frame rectangular area - WD_FRAMERECT_BOTTOM = 1, ///< Offset at bottom to draw the frame rectangular area - - /* Extra space at top/bottom of text panels */ - WD_TEXTPANEL_TOP = 6, ///< Offset at top to draw above the text - WD_TEXTPANEL_BOTTOM = 6, ///< Offset at bottom to draw below the text - - /* WWT_FRAME */ - WD_FRAMETEXT_LEFT = 6, ///< Left offset of the text of the frame. - WD_FRAMETEXT_RIGHT = 6, ///< Right offset of the text of the frame. - WD_FRAMETEXT_TOP = 6, ///< Top offset of the text of the frame - WD_FRAMETEXT_BOTTOM = 6, ///< Bottom offset of the text of the frame - - /* WWT_MATRIX */ - WD_MATRIX_LEFT = 2, ///< Offset at left of a matrix cell. - WD_MATRIX_RIGHT = 2, ///< Offset at right of a matrix cell. - WD_MATRIX_TOP = 3, ///< Offset at top of a matrix cell. - WD_MATRIX_BOTTOM = 1, ///< Offset at bottom of a matrix cell. - - /* WWT_SHADEBOX */ - WD_SHADEBOX_WIDTH = 12, ///< Width of a standard shade box widget. - WD_SHADEBOX_LEFT = 2, ///< Left offset of shade sprite. - WD_SHADEBOX_RIGHT = 2, ///< Right offset of shade sprite. - WD_SHADEBOX_TOP = 3, ///< Top offset of shade sprite. - WD_SHADEBOX_BOTTOM = 3, ///< Bottom offset of shade sprite. - - /* WWT_STICKYBOX */ - WD_STICKYBOX_WIDTH = 12, ///< Width of a standard sticky box widget. - WD_STICKYBOX_LEFT = 2, ///< Left offset of sticky sprite. - WD_STICKYBOX_RIGHT = 2, ///< Right offset of sticky sprite. - WD_STICKYBOX_TOP = 3, ///< Top offset of sticky sprite. - WD_STICKYBOX_BOTTOM = 3, ///< Bottom offset of sticky sprite. - - /* WWT_DEBUGBOX */ - WD_DEBUGBOX_WIDTH = 12, ///< Width of a standard debug box widget. - WD_DEBUGBOX_LEFT = 2, ///< Left offset of debug sprite. - WD_DEBUGBOX_RIGHT = 2, ///< Right offset of debug sprite. - WD_DEBUGBOX_TOP = 3, ///< Top offset of debug sprite. - WD_DEBUGBOX_BOTTOM = 3, ///< Bottom offset of debug sprite. - - /* WWT_DEFSIZEBOX */ - WD_DEFSIZEBOX_WIDTH = 12, ///< Width of a standard defsize box widget. - WD_DEFSIZEBOX_LEFT = 2, ///< Left offset of defsize sprite. - WD_DEFSIZEBOX_RIGHT = 2, ///< Right offset of defsize sprite. - WD_DEFSIZEBOX_TOP = 3, ///< Top offset of defsize sprite. - WD_DEFSIZEBOX_BOTTOM = 3, ///< Bottom offset of defsize sprite. - - /* WWT_RESIZEBOX */ - WD_RESIZEBOX_WIDTH = 12, ///< Width of a resize box widget. - WD_RESIZEBOX_LEFT = 3, ///< Left offset of resize sprite. - WD_RESIZEBOX_RIGHT = 2, ///< Right offset of resize sprite. - WD_RESIZEBOX_TOP = 3, ///< Top offset of resize sprite. - WD_RESIZEBOX_BOTTOM = 2, ///< Bottom offset of resize sprite. - - /* WWT_CLOSEBOX */ - WD_CLOSEBOX_WIDTH = 11, ///< Width of a close box widget. - WD_CLOSEBOX_LEFT = 2, ///< Left offset of closebox string. - WD_CLOSEBOX_RIGHT = 1, ///< Right offset of closebox string. - WD_CLOSEBOX_TOP = 2, ///< Top offset of closebox string. - WD_CLOSEBOX_BOTTOM = 2, ///< Bottom offset of closebox string. - - /* WWT_CAPTION */ - WD_CAPTION_HEIGHT = 14, ///< Height of a title bar. - WD_CAPTIONTEXT_LEFT = 2, ///< Offset of the caption text at the left. - WD_CAPTIONTEXT_RIGHT = 2, ///< Offset of the caption text at the right. - WD_CAPTIONTEXT_TOP = 2, ///< Offset of the caption text at the top. - WD_CAPTIONTEXT_BOTTOM = 2, ///< Offset of the caption text at the bottom. - - /* Dropdown widget. */ - WD_DROPDOWN_HEIGHT = 12, ///< Height of a drop down widget. - WD_DROPDOWNTEXT_LEFT = 2, ///< Left offset of the dropdown widget string. - WD_DROPDOWNTEXT_RIGHT = 2, ///< Right offset of the dropdown widget string. - WD_DROPDOWNTEXT_TOP = 1, ///< Top offset of the dropdown widget string. - WD_DROPDOWNTEXT_BOTTOM = 1, ///< Bottom offset of the dropdown widget string. - - WD_PAR_VSEP_NORMAL = 2, ///< Normal amount of vertical space between two paragraphs of text. - WD_PAR_VSEP_WIDE = 8, ///< Large amount of vertical space between two paragraphs of text. +struct WidgetDimensions { + RectPadding imgbtn; + RectPadding inset; + RectPadding vscrollbar; + RectPadding hscrollbar; + RectPadding bevel; ///< Widths of bevel border. + RectPadding fullbevel; ///< Always-scaled bevel border. + RectPadding framerect; ///< Offsets within frame area. + RectPadding frametext; ///< Offsets within a text frame area. + RectPadding matrix; ///< Offsets within a matrix cell. + RectPadding shadebox; + RectPadding stickybox; + RectPadding debugbox; + RectPadding defsizebox; + RectPadding resizebox; + RectPadding closebox; + RectPadding captiontext; ///< Offsets of text within a caption. + RectPadding dropdowntext; ///< Offsets of text within a dropdown widget. + RectPadding modalpopup; ///< Padding for a modal popup. + + int pressed; ///< Offset for contents of depressed widget. + int vsep_normal; ///< Normal vertical spacing. + int vsep_wide; ///< Wide vertical spacing. + int hsep_normal; ///< Normal horizontal spacing. + int hsep_wide; ///< Wide horizontal spacing. + int hsep_indent; ///< Width of identation for tree layouts. + + static const WidgetDimensions unscaled; ///< Unscaled widget dimensions. + static WidgetDimensions scaled; ///< Widget dimensions scaled for current zoom level. }; /* widget.cpp */ void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags); + +static inline void DrawFrameRect(const Rect &r, Colours colour, FrameFlags flags) +{ + DrawFrameRect(r.left, r.top, r.right, r.bottom, colour, flags); +} + void DrawCaption(const Rect &r, Colours colour, Owner owner, TextColour text_colour, StringID str, StringAlignment align); /* window.cpp */ @@ -342,6 +276,7 @@ struct Window : ZeroedMemoryAllocator { const QueryString *GetQueryString(uint widnum) const; QueryString *GetQueryString(uint widnum); + void UpdateQueryStringSize(); virtual const char *GetFocusedText() const; virtual const char *GetCaret() const; @@ -750,11 +685,20 @@ struct Window : ZeroedMemoryAllocator { /** * The user clicked on a vehicle while HT_VEHICLE has been set. - * @param v clicked vehicle. It is guaranteed to be v->IsPrimaryVehicle() == true - * @return True if the click is handled, false if it is ignored. + * @param v clicked vehicle + * @return true if the click is handled, false if it is ignored + * @pre v->IsPrimaryVehicle() == true */ virtual bool OnVehicleSelect(const struct Vehicle *v) { return false; } + /** + * The user clicked on a vehicle while HT_VEHICLE has been set. + * @param v clicked vehicle + * @return True if the click is handled, false if it is ignored + * @pre v->IsPrimaryVehicle() == true + */ + virtual bool OnVehicleSelect(VehicleList::const_iterator begin, VehicleList::const_iterator end) { return false; } + /** * The user cancelled a tile highlight mode that has been set. */ @@ -875,6 +819,19 @@ struct Window : ZeroedMemoryAllocator { using IterateFromFront = AllWindows; //!< Iterate all windows in Z order from front to back. }; +/** + * Generic helper function that checks if all elements of the range are equal with respect to the given predicate. + * @param begin The start of the range. + * @param end The end of the range. + * @param pred The predicate to use. + * @return True if all elements are equal, false otherwise. + */ +template +inline bool AllEqual(It begin, It end, Pred pred) +{ + return std::adjacent_find(begin, end, std::not_fn(pred)) == end; +} + /** * Get the nested widget with number \a widnum from the nested widget tree. * @tparam NWID Type of the nested widget. diff --git a/src/window_type.h b/src/window_type.h index 6bf4b6f0ad6be..12a32fc12e285 100644 --- a/src/window_type.h +++ b/src/window_type.h @@ -13,6 +13,7 @@ /** %Window numbers. */ enum WindowNumberEnum { WN_GAME_OPTIONS_AI = 0, ///< AI settings. + WN_GAME_OPTIONS_GS, ///< GS settings. WN_GAME_OPTIONS_ABOUT, ///< About window. WN_GAME_OPTIONS_NEWGRF_STATE, ///< NewGRF settings. WN_GAME_OPTIONS_GAME_OPTIONS, ///< Game options. @@ -163,10 +164,10 @@ enum WindowClass { /** - * AI settings; %Window numbers: - * - 0 = #AISettingsWidgets + * Script settings; %Window numbers: + * - 0 = #ScriptSettingsWidgets */ - WC_AI_SETTINGS, + WC_SCRIPT_SETTINGS, /** * NewGRF parameters; %Window numbers: @@ -272,10 +273,10 @@ enum WindowClass { WC_SIGN_LIST, /** - * AI list; %Window numbers: - * - 0 = #AIListWidgets + * Scripts list; %Window numbers: + * - 0 = #ScriptListWidgets */ - WC_AI_LIST, + WC_SCRIPT_LIST, /** * Goals list; %Window numbers: @@ -598,6 +599,7 @@ enum WindowClass { /** * Game options window; %Window numbers: * - #WN_GAME_OPTIONS_AI = #AIConfigWidgets + * - #WN_GAME_OPTIONS_GS = #GSConfigWidgets * - #WN_GAME_OPTIONS_ABOUT = #AboutWidgets * - #WN_GAME_OPTIONS_NEWGRF_STATE = #NewGRFStateWidgets * - #WN_GAME_OPTIONS_GAME_OPTIONS = #GameOptionsWidgets @@ -650,10 +652,10 @@ enum WindowClass { /** - * AI debug window; %Window numbers: - * - 0 = #AIDebugWidgets + * Script debug window; %Window numbers: + * - 0 = #ScriptDebugWidgets */ - WC_AI_DEBUG, + WC_SCRIPT_DEBUG, /** * NewGRF inspect (debug); %Window numbers: diff --git a/src/zoom_func.h b/src/zoom_func.h index 485284a06cd7e..abcc050d25c30 100644 --- a/src/zoom_func.h +++ b/src/zoom_func.h @@ -36,6 +36,17 @@ static inline int UnScaleByZoom(int value, ZoomLevel zoom) return (value + (1 << zoom) - 1) >> zoom; } +/** + * Adjust by zoom level; zoom < 0 shifts right, zoom >= 0 shifts left + * @param value value to shift + * @param zoom zoom level to shift to + * @return shifted value + */ +static inline int AdjustByZoom(int value, int zoom) +{ + return zoom < 0 ? UnScaleByZoom(value, ZoomLevel(-zoom)) : ScaleByZoom(value, ZoomLevel(zoom)); +} + /** * Scale by zoom level, usually shift left (when zoom > ZOOM_LVL_NORMAL) * @param value value to shift @@ -69,33 +80,43 @@ static inline int UnScaleGUI(int value) } /** - * Scale traditional pixel dimensions to GUI zoom level. - * @param value Pixel amount at #ZOOM_LVL_BASE (traditional "normal" interface size). - * @return Pixel amount at #ZOOM_LVL_GUI (current interface size). + * Scale zoom level relative to GUI zoom. + * @param value zoom level to scale + * @return scaled zoom level */ -static inline int ScaleGUITrad(int value) +static inline ZoomLevel ScaleZoomGUI(ZoomLevel value) { - return UnScaleGUI(value * ZOOM_LVL_BASE); + return std::clamp(ZoomLevel(value + (ZOOM_LVL_GUI - ZOOM_LVL_OUT_4X)), ZOOM_LVL_MIN, ZOOM_LVL_MAX); } /** - * Short-hand to apply font zoom level. - * @param value Pixel amount at #ZOOM_LVL_BEGIN (full zoom in). - * @return Pixel amount at #ZOOM_LVL_FONT (current interface size). + * UnScale zoom level relative to GUI zoom. + * @param value zoom level to scale + * @return un-scaled zoom level + */ +static inline ZoomLevel UnScaleZoomGUI(ZoomLevel value) +{ + return std::clamp(ZoomLevel(value - (ZOOM_LVL_GUI - ZOOM_LVL_OUT_4X)), ZOOM_LVL_MIN, ZOOM_LVL_MAX); +} + +/** + * Scale traditional pixel dimensions to GUI zoom level, for drawing sprites. + * @param value Pixel amount at #ZOOM_LVL_BASE (traditional "normal" interface size). + * @return Pixel amount at #ZOOM_LVL_GUI (current interface size). */ -static inline int UnScaleFont(int value) +static inline int ScaleSpriteTrad(int value) { - return UnScaleByZoom(value, ZOOM_LVL_FONT); + return UnScaleGUI(value * ZOOM_LVL_BASE); } /** - * Scale traditional pixel dimensions to Font zoom level. + * Scale traditional pixel dimensions to GUI zoom level. * @param value Pixel amount at #ZOOM_LVL_BASE (traditional "normal" interface size). - * @return Pixel amount at #ZOOM_LVL_FONT (current interface size). + * @return Pixel amount at #ZOOM_LVL_GUI (current interface size). */ -static inline int ScaleFontTrad(int value) +static inline int ScaleGUITrad(int value) { - return UnScaleFont(value * ZOOM_LVL_BASE); + return value * _gui_scale / 100; } #endif /* ZOOM_FUNC_H */ diff --git a/src/zoom_type.h b/src/zoom_type.h index 0945e1cc0960f..7ccc142ef3a72 100644 --- a/src/zoom_type.h +++ b/src/zoom_type.h @@ -15,8 +15,6 @@ static uint const ZOOM_LVL_SHIFT = 2; static uint const ZOOM_LVL_BASE = 1 << ZOOM_LVL_SHIFT; -static const int8 ZOOM_LVL_CFG_AUTO = -1; - /** All zoom levels we know. */ enum ZoomLevel : byte { /* Our possible zoom-levels */ @@ -35,7 +33,7 @@ enum ZoomLevel : byte { ZOOM_LVL_VIEWPORT = ZOOM_LVL_OUT_4X, ///< Default zoom level for viewports. ZOOM_LVL_NEWS = ZOOM_LVL_OUT_4X, ///< Default zoom level for the news messages. ZOOM_LVL_INDUSTRY = ZOOM_LVL_OUT_8X, ///< Default zoom level for the industry view. - ZOOM_LVL_TOWN = ZOOM_LVL_OUT_8X, ///< Default zoom level for the town view. + ZOOM_LVL_TOWN = ZOOM_LVL_OUT_4X, ///< Default zoom level for the town view. ZOOM_LVL_AIRCRAFT = ZOOM_LVL_OUT_4X, ///< Default zoom level for the aircraft view. ZOOM_LVL_SHIP = ZOOM_LVL_OUT_4X, ///< Default zoom level for the ship view. ZOOM_LVL_TRAIN = ZOOM_LVL_OUT_4X, ///< Default zoom level for the train view. @@ -50,12 +48,13 @@ enum ZoomLevel : byte { }; DECLARE_POSTFIX_INCREMENT(ZoomLevel) -extern int8 _gui_zoom_cfg; -extern int8 _font_zoom_cfg; +extern int _gui_scale; +extern int _gui_scale_cfg; extern ZoomLevel _gui_zoom; -extern ZoomLevel _font_zoom; #define ZOOM_LVL_GUI (_gui_zoom) -#define ZOOM_LVL_FONT (_font_zoom) + +static const int MIN_INTERFACE_SCALE = 100; +static const int MAX_INTERFACE_SCALE = 500; #endif /* ZOOM_TYPE_H */
    OOOO OXXX OOXX XOOO OOOX XXXXOOOO XXXX XXOO OOOOOOOO XXXX XX XXXXXX
    airport